blob: e5e4abfca5d443f5339baa726eed3ec280afb1c8 [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
Alexis Hetub027aa92015-01-19 15:56:12 -050036typedef std::pair<GLenum, GLenum> InternalFormatTypePair;
37typedef std::map<InternalFormatTypePair, GLenum> FormatMap;
38
39// A helper function to insert data into the format map with fewer characters.
40static void InsertFormatMapping(FormatMap& map, GLenum internalformat, GLenum format, GLenum type)
41{
42 map[InternalFormatTypePair(internalformat, type)] = format;
43}
44
John Bauman66b8ab22014-05-06 15:57:45 -040045static bool validImageSize(GLint level, GLsizei width, GLsizei height)
46{
Nicolas Capensf160b172014-11-26 11:58:23 -050047 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
48 {
49 return false;
50 }
John Bauman66b8ab22014-05-06 15:57:45 -040051
Nicolas Capensf160b172014-11-26 11:58:23 -050052 return true;
John Bauman66b8ab22014-05-06 15:57:45 -040053}
54
Nicolas Capens14ee7622014-10-28 23:48:41 -040055static 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 -040056{
Nicolas Capensf160b172014-11-26 11:58:23 -050057 if(!texture)
58 {
59 return error(GL_INVALID_OPERATION, false);
60 }
John Bauman66b8ab22014-05-06 15:57:45 -040061
Nicolas Capensf160b172014-11-26 11:58:23 -050062 if(compressed != texture->isCompressed(target, level))
63 {
64 return error(GL_INVALID_OPERATION, false);
65 }
John Bauman66b8ab22014-05-06 15:57:45 -040066
Nicolas Capensf160b172014-11-26 11:58:23 -050067 if(format != GL_NONE && format != texture->getFormat(target, level))
68 {
69 return error(GL_INVALID_OPERATION, false);
70 }
John Bauman66b8ab22014-05-06 15:57:45 -040071
Nicolas Capensf160b172014-11-26 11:58:23 -050072 if(compressed)
73 {
74 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
Alexis Hetub027aa92015-01-19 15:56:12 -050075 (height % 4 != 0 && height != texture->getHeight(target, 0)))
Nicolas Capensf160b172014-11-26 11:58:23 -050076 {
77 return error(GL_INVALID_OPERATION, false);
78 }
79 }
John Bauman66b8ab22014-05-06 15:57:45 -040080
Nicolas Capensf160b172014-11-26 11:58:23 -050081 if(xoffset + width > texture->getWidth(target, level) ||
Alexis Hetub027aa92015-01-19 15:56:12 -050082 yoffset + height > texture->getHeight(target, level))
Nicolas Capensf160b172014-11-26 11:58:23 -050083 {
84 return error(GL_INVALID_VALUE, false);
85 }
John Bauman66b8ab22014-05-06 15:57:45 -040086
Nicolas Capensf160b172014-11-26 11:58:23 -050087 return true;
John Bauman66b8ab22014-05-06 15:57:45 -040088}
89
Alexis Hetub027aa92015-01-19 15:56:12 -050090static 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)
91{
92 if(!texture)
93 {
94 return error(GL_INVALID_OPERATION, false);
95 }
96
97 if(compressed != texture->isCompressed(target, level))
98 {
99 return error(GL_INVALID_OPERATION, false);
100 }
101
102 if(format != GL_NONE && format != texture->getFormat(target, level))
103 {
104 return error(GL_INVALID_OPERATION, false);
105 }
106
107 if(compressed)
108 {
109 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
110 (height % 4 != 0 && height != texture->getHeight(target, 0)) ||
111 (depth % 4 != 0 && depth != texture->getDepth(target, 0)))
112 {
113 return error(GL_INVALID_OPERATION, false);
114 }
115 }
116
117 if(xoffset + width > texture->getWidth(target, level) ||
118 yoffset + height > texture->getHeight(target, level) ||
119 zoffset + depth > texture->getDepth(target, level))
120 {
121 return error(GL_INVALID_VALUE, false);
122 }
123
124 return true;
125}
126
127static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)
128{
129 // [OpenGL ES 2.0.24] table 3.9
130 switch(textureFormat)
131 {
132 case GL_ALPHA:
133 if(colorbufferFormat != GL_ALPHA &&
134 colorbufferFormat != GL_RGBA &&
135 colorbufferFormat != GL_RGBA4 &&
136 colorbufferFormat != GL_RGB5_A1 &&
137 colorbufferFormat != GL_RGBA8_OES)
138 {
139 return error(GL_INVALID_OPERATION, false);
140 }
141 break;
142 case GL_LUMINANCE:
143 case GL_RGB:
144 if(colorbufferFormat != GL_RGB &&
145 colorbufferFormat != GL_RGB565 &&
146 colorbufferFormat != GL_RGB8_OES &&
147 colorbufferFormat != GL_RGBA &&
148 colorbufferFormat != GL_RGBA4 &&
149 colorbufferFormat != GL_RGB5_A1 &&
150 colorbufferFormat != GL_RGBA8_OES)
151 {
152 return error(GL_INVALID_OPERATION, false);
153 }
154 break;
155 case GL_LUMINANCE_ALPHA:
156 case GL_RGBA:
157 if(colorbufferFormat != GL_RGBA &&
158 colorbufferFormat != GL_RGBA4 &&
159 colorbufferFormat != GL_RGB5_A1 &&
160 colorbufferFormat != GL_RGBA8_OES)
161 {
162 return error(GL_INVALID_OPERATION, false);
163 }
164 break;
165 case GL_ETC1_RGB8_OES:
166 return error(GL_INVALID_OPERATION, false);
167 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
168 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
169 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
170 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
171 if(S3TC_SUPPORT)
172 {
173 return error(GL_INVALID_OPERATION, false);
174 }
175 else
176 {
177 return error(GL_INVALID_ENUM, false);
178 }
179 case GL_DEPTH_COMPONENT:
180 case GL_DEPTH_STENCIL_OES:
181 return error(GL_INVALID_OPERATION, false);
182 default:
183 return error(GL_INVALID_ENUM, false);
184 }
185 return true;
186}
187
188static FormatMap BuildFormatMap3D()
189{
190 FormatMap map;
191
192 // Internal format | Format | Type
193 InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
194 InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
195 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
196 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
197 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
198 InsertFormatMapping(map, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
199 InsertFormatMapping(map, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE);
200 InsertFormatMapping(map, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
201 InsertFormatMapping(map, GL_R8_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE);
202 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
203 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_FLOAT);
204 InsertFormatMapping(map, GL_R32F_EXT, GL_RED_EXT, GL_FLOAT);
205 InsertFormatMapping(map, GL_RG8_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE);
206 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
207 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_FLOAT);
208 InsertFormatMapping(map, GL_RG32F_EXT, GL_RG_EXT, GL_FLOAT);
209 InsertFormatMapping(map, GL_RGB8_OES, GL_RGB, GL_UNSIGNED_BYTE);
210 InsertFormatMapping(map, GL_SRGB8_NV, GL_RGB, GL_UNSIGNED_BYTE);
211 InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE);
212 InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
Alexis Hetu0300e3c2015-03-12 17:33:07 -0400213 InsertFormatMapping(map, GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
214 InsertFormatMapping(map, GL_RGB16F_EXT, GL_RGB, GL_FLOAT);
Alexis Hetub027aa92015-01-19 15:56:12 -0500215 InsertFormatMapping(map, GL_RGB32F_EXT, GL_RGB, GL_FLOAT);
216 InsertFormatMapping(map, GL_RGBA8_OES, GL_RGBA, GL_UNSIGNED_BYTE);
217 InsertFormatMapping(map, GL_SRGB8_ALPHA8_EXT, GL_RGBA, GL_UNSIGNED_BYTE);
218 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE);
219 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
220 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT);
221 InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE);
222 InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
223 InsertFormatMapping(map, GL_RGB10_A2_EXT, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT);
224 InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
225 InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_FLOAT);
226 InsertFormatMapping(map, GL_RGBA32F_EXT, GL_RGBA, GL_FLOAT);
227
228 return map;
229}
230
231static bool ValidateType3D(GLenum type)
232{
233 switch(type)
234 {
235 case GL_UNSIGNED_BYTE:
236 case GL_BYTE:
237 case GL_UNSIGNED_SHORT:
238 case GL_SHORT:
239 case GL_UNSIGNED_INT:
240 case GL_INT:
241 case GL_HALF_FLOAT_OES:
242 case GL_FLOAT:
243 case GL_UNSIGNED_SHORT_5_6_5:
244 case GL_UNSIGNED_SHORT_4_4_4_4:
245 case GL_UNSIGNED_SHORT_5_5_5_1:
246 case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
247 return true;
248 default:
249 break;
250 }
251 return false;
252}
253
254static bool ValidateFormat3D(GLenum format)
255{
256 switch(format)
257 {
258 case GL_RED_EXT:
259 case GL_RG_EXT:
260 case GL_RGB:
261 case GL_RGBA:
262 case GL_DEPTH_COMPONENT:
263 case GL_DEPTH_STENCIL_OES:
264 case GL_LUMINANCE_ALPHA:
265 case GL_LUMINANCE:
266 case GL_ALPHA:
267 return true;
268 default:
269 break;
270 }
271 return false;
272}
273
274static bool ValidateInternalFormat3D(GLenum internalformat, GLenum format, GLenum type)
275{
276 static const FormatMap formatMap = BuildFormatMap3D();
277 FormatMap::const_iterator iter = formatMap.find(InternalFormatTypePair(internalformat, type));
278 if(iter != formatMap.end())
279 {
280 return iter->second == format;
281 }
282 return false;
283}
284
John Bauman66b8ab22014-05-06 15:57:45 -0400285extern "C"
286{
287
288void GL_APIENTRY glActiveTexture(GLenum texture)
289{
Nicolas Capensf160b172014-11-26 11:58:23 -0500290 TRACE("(GLenum texture = 0x%X)", texture);
John Bauman66b8ab22014-05-06 15:57:45 -0400291
Nicolas Capensf160b172014-11-26 11:58:23 -0500292 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400293
Nicolas Capensf160b172014-11-26 11:58:23 -0500294 if(context)
295 {
296 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
297 {
298 return error(GL_INVALID_ENUM);
299 }
John Bauman66b8ab22014-05-06 15:57:45 -0400300
Nicolas Capensf160b172014-11-26 11:58:23 -0500301 context->setActiveSampler(texture - GL_TEXTURE0);
302 }
John Bauman66b8ab22014-05-06 15:57:45 -0400303}
304
305void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)
306{
Nicolas Capensf160b172014-11-26 11:58:23 -0500307 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400308
Nicolas Capensf160b172014-11-26 11:58:23 -0500309 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400310
Nicolas Capensf160b172014-11-26 11:58:23 -0500311 if(context)
312 {
313 es2::Program *programObject = context->getProgram(program);
314 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400315
Nicolas Capensf160b172014-11-26 11:58:23 -0500316 if(!programObject)
317 {
318 if(context->getShader(program))
319 {
320 return error(GL_INVALID_OPERATION);
321 }
322 else
323 {
324 return error(GL_INVALID_VALUE);
325 }
326 }
John Bauman66b8ab22014-05-06 15:57:45 -0400327
Nicolas Capensf160b172014-11-26 11:58:23 -0500328 if(!shaderObject)
329 {
330 if(context->getProgram(shader))
331 {
332 return error(GL_INVALID_OPERATION);
333 }
334 else
335 {
336 return error(GL_INVALID_VALUE);
337 }
338 }
John Bauman66b8ab22014-05-06 15:57:45 -0400339
Nicolas Capensf160b172014-11-26 11:58:23 -0500340 if(!programObject->attachShader(shaderObject))
341 {
342 return error(GL_INVALID_OPERATION);
343 }
344 }
John Bauman66b8ab22014-05-06 15:57:45 -0400345}
346
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500347void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint name)
John Bauman66b8ab22014-05-06 15:57:45 -0400348{
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500349 TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
John Bauman66b8ab22014-05-06 15:57:45 -0400350
Nicolas Capensf160b172014-11-26 11:58:23 -0500351 switch(target)
352 {
353 case GL_ANY_SAMPLES_PASSED_EXT:
354 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
355 break;
356 default:
357 return error(GL_INVALID_ENUM);
358 }
John Bauman66b8ab22014-05-06 15:57:45 -0400359
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500360 if(name == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -0500361 {
362 return error(GL_INVALID_OPERATION);
363 }
John Bauman66b8ab22014-05-06 15:57:45 -0400364
Nicolas Capensf160b172014-11-26 11:58:23 -0500365 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400366
Nicolas Capensf160b172014-11-26 11:58:23 -0500367 if(context)
368 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500369 context->beginQuery(target, name);
Nicolas Capensf160b172014-11-26 11:58:23 -0500370 }
John Bauman66b8ab22014-05-06 15:57:45 -0400371}
372
373void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
374{
Nicolas Capensf160b172014-11-26 11:58:23 -0500375 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
John Bauman66b8ab22014-05-06 15:57:45 -0400376
Nicolas Capensf160b172014-11-26 11:58:23 -0500377 if(index >= es2::MAX_VERTEX_ATTRIBS)
378 {
379 return error(GL_INVALID_VALUE);
380 }
John Bauman66b8ab22014-05-06 15:57:45 -0400381
Nicolas Capensf160b172014-11-26 11:58:23 -0500382 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400383
Nicolas Capensf160b172014-11-26 11:58:23 -0500384 if(context)
385 {
386 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -0400387
Nicolas Capensf160b172014-11-26 11:58:23 -0500388 if(!programObject)
389 {
390 if(context->getShader(program))
391 {
392 return error(GL_INVALID_OPERATION);
393 }
394 else
395 {
396 return error(GL_INVALID_VALUE);
397 }
398 }
John Bauman66b8ab22014-05-06 15:57:45 -0400399
Nicolas Capensf160b172014-11-26 11:58:23 -0500400 if(strncmp(name, "gl_", 3) == 0)
401 {
402 return error(GL_INVALID_OPERATION);
403 }
John Bauman66b8ab22014-05-06 15:57:45 -0400404
Nicolas Capensf160b172014-11-26 11:58:23 -0500405 programObject->bindAttributeLocation(index, name);
406 }
John Bauman66b8ab22014-05-06 15:57:45 -0400407}
408
409void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
410{
Nicolas Capensf160b172014-11-26 11:58:23 -0500411 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
John Bauman66b8ab22014-05-06 15:57:45 -0400412
Nicolas Capensf160b172014-11-26 11:58:23 -0500413 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400414
Nicolas Capensf160b172014-11-26 11:58:23 -0500415 if(context)
416 {
417 switch(target)
418 {
419 case GL_ARRAY_BUFFER:
420 context->bindArrayBuffer(buffer);
421 return;
422 case GL_ELEMENT_ARRAY_BUFFER:
423 context->bindElementArrayBuffer(buffer);
424 return;
425 default:
426 return error(GL_INVALID_ENUM);
427 }
428 }
John Bauman66b8ab22014-05-06 15:57:45 -0400429}
430
431void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
432{
Nicolas Capensf160b172014-11-26 11:58:23 -0500433 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -0400434
Nicolas Capensf160b172014-11-26 11:58:23 -0500435 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
436 {
437 return error(GL_INVALID_ENUM);
438 }
John Bauman66b8ab22014-05-06 15:57:45 -0400439
Nicolas Capensf160b172014-11-26 11:58:23 -0500440 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400441
Nicolas Capensf160b172014-11-26 11:58:23 -0500442 if(context)
443 {
444 if(target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
445 {
446 context->bindReadFramebuffer(framebuffer);
447 }
Nicolas Capens08e90f02014-11-21 12:49:12 -0500448
Nicolas Capensf160b172014-11-26 11:58:23 -0500449 if(target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
450 {
451 context->bindDrawFramebuffer(framebuffer);
452 }
453 }
John Bauman66b8ab22014-05-06 15:57:45 -0400454}
455
456void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
457{
Nicolas Capensf160b172014-11-26 11:58:23 -0500458 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -0400459
Nicolas Capensf160b172014-11-26 11:58:23 -0500460 if(target != GL_RENDERBUFFER)
461 {
462 return error(GL_INVALID_ENUM);
463 }
John Bauman66b8ab22014-05-06 15:57:45 -0400464
Nicolas Capensf160b172014-11-26 11:58:23 -0500465 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400466
Nicolas Capensf160b172014-11-26 11:58:23 -0500467 if(context)
468 {
469 if(renderbuffer != 0 && !context->getRenderbuffer(renderbuffer))
470 {
471 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
472 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
473 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
474 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
475 return error(GL_INVALID_OPERATION);
476 }
Alexis Hetu42a584d2014-11-07 14:23:33 -0500477
Nicolas Capensf160b172014-11-26 11:58:23 -0500478 context->bindRenderbuffer(renderbuffer);
479 }
John Bauman66b8ab22014-05-06 15:57:45 -0400480}
481
482void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
483{
Nicolas Capensf160b172014-11-26 11:58:23 -0500484 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
John Bauman66b8ab22014-05-06 15:57:45 -0400485
Nicolas Capensf160b172014-11-26 11:58:23 -0500486 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400487
Nicolas Capensf160b172014-11-26 11:58:23 -0500488 if(context)
489 {
490 es2::Texture *textureObject = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -0400491
Nicolas Capensf160b172014-11-26 11:58:23 -0500492 if(textureObject && textureObject->getTarget() != target && texture != 0)
493 {
494 return error(GL_INVALID_OPERATION);
495 }
John Bauman66b8ab22014-05-06 15:57:45 -0400496
Alexis Hetued306182015-04-02 12:02:28 -0400497 egl::GLint clientVersion = context->getClientVersion();
498
Nicolas Capensf160b172014-11-26 11:58:23 -0500499 switch(target)
500 {
501 case GL_TEXTURE_2D:
502 context->bindTexture2D(texture);
503 return;
504 case GL_TEXTURE_CUBE_MAP:
505 context->bindTextureCubeMap(texture);
506 return;
507 case GL_TEXTURE_EXTERNAL_OES:
508 context->bindTextureExternal(texture);
509 return;
Alexis Hetued306182015-04-02 12:02:28 -0400510 case GL_TEXTURE_2D_ARRAY:
511 if(clientVersion < 3)
512 {
513 return error(GL_INVALID_ENUM);
514 }
515 else
516 {
517 UNIMPLEMENTED();
518 context->bindTexture3D(texture);
519 break;
520 }
Alexis Hetub027aa92015-01-19 15:56:12 -0500521 case GL_TEXTURE_3D_OES:
522 context->bindTexture3D(texture);
523 return;
Nicolas Capensf160b172014-11-26 11:58:23 -0500524 default:
525 return error(GL_INVALID_ENUM);
526 }
527 }
John Bauman66b8ab22014-05-06 15:57:45 -0400528}
529
530void GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
531{
Nicolas Capensf160b172014-11-26 11:58:23 -0500532 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
533 red, green, blue, alpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400534
Nicolas Capensf160b172014-11-26 11:58:23 -0500535 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400536
Nicolas Capensf160b172014-11-26 11:58:23 -0500537 if(context)
538 {
539 context->setBlendColor(es2::clamp01(red), es2::clamp01(green), es2::clamp01(blue), es2::clamp01(alpha));
540 }
John Bauman66b8ab22014-05-06 15:57:45 -0400541}
542
543void GL_APIENTRY glBlendEquation(GLenum mode)
544{
Nicolas Capensf160b172014-11-26 11:58:23 -0500545 glBlendEquationSeparate(mode, mode);
John Bauman66b8ab22014-05-06 15:57:45 -0400546}
547
548void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
549{
Nicolas Capensf160b172014-11-26 11:58:23 -0500550 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400551
Nicolas Capensf160b172014-11-26 11:58:23 -0500552 switch(modeRGB)
553 {
554 case GL_FUNC_ADD:
555 case GL_FUNC_SUBTRACT:
556 case GL_FUNC_REVERSE_SUBTRACT:
557 case GL_MIN_EXT:
558 case GL_MAX_EXT:
559 break;
560 default:
561 return error(GL_INVALID_ENUM);
562 }
John Bauman66b8ab22014-05-06 15:57:45 -0400563
Nicolas Capensf160b172014-11-26 11:58:23 -0500564 switch(modeAlpha)
565 {
566 case GL_FUNC_ADD:
567 case GL_FUNC_SUBTRACT:
568 case GL_FUNC_REVERSE_SUBTRACT:
569 case GL_MIN_EXT:
570 case GL_MAX_EXT:
571 break;
572 default:
573 return error(GL_INVALID_ENUM);
574 }
John Bauman66b8ab22014-05-06 15:57:45 -0400575
Nicolas Capensf160b172014-11-26 11:58:23 -0500576 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400577
Nicolas Capensf160b172014-11-26 11:58:23 -0500578 if(context)
579 {
580 context->setBlendEquation(modeRGB, modeAlpha);
581 }
John Bauman66b8ab22014-05-06 15:57:45 -0400582}
583
584void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
585{
Nicolas Capensf160b172014-11-26 11:58:23 -0500586 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
John Bauman66b8ab22014-05-06 15:57:45 -0400587}
588
589void GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
590{
Nicolas Capensf160b172014-11-26 11:58:23 -0500591 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
592 srcRGB, dstRGB, srcAlpha, dstAlpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400593
Nicolas Capensf160b172014-11-26 11:58:23 -0500594 switch(srcRGB)
595 {
596 case GL_ZERO:
597 case GL_ONE:
598 case GL_SRC_COLOR:
599 case GL_ONE_MINUS_SRC_COLOR:
600 case GL_DST_COLOR:
601 case GL_ONE_MINUS_DST_COLOR:
602 case GL_SRC_ALPHA:
603 case GL_ONE_MINUS_SRC_ALPHA:
604 case GL_DST_ALPHA:
605 case GL_ONE_MINUS_DST_ALPHA:
606 case GL_CONSTANT_COLOR:
607 case GL_ONE_MINUS_CONSTANT_COLOR:
608 case GL_CONSTANT_ALPHA:
609 case GL_ONE_MINUS_CONSTANT_ALPHA:
610 case GL_SRC_ALPHA_SATURATE:
611 break;
612 default:
613 return error(GL_INVALID_ENUM);
614 }
John Bauman66b8ab22014-05-06 15:57:45 -0400615
Nicolas Capensf160b172014-11-26 11:58:23 -0500616 switch(dstRGB)
617 {
618 case GL_ZERO:
619 case GL_ONE:
620 case GL_SRC_COLOR:
621 case GL_ONE_MINUS_SRC_COLOR:
622 case GL_DST_COLOR:
623 case GL_ONE_MINUS_DST_COLOR:
624 case GL_SRC_ALPHA:
625 case GL_ONE_MINUS_SRC_ALPHA:
626 case GL_DST_ALPHA:
627 case GL_ONE_MINUS_DST_ALPHA:
628 case GL_CONSTANT_COLOR:
629 case GL_ONE_MINUS_CONSTANT_COLOR:
630 case GL_CONSTANT_ALPHA:
631 case GL_ONE_MINUS_CONSTANT_ALPHA:
632 break;
633 default:
634 return error(GL_INVALID_ENUM);
635 }
John Bauman66b8ab22014-05-06 15:57:45 -0400636
Nicolas Capensf160b172014-11-26 11:58:23 -0500637 switch(srcAlpha)
638 {
639 case GL_ZERO:
640 case GL_ONE:
641 case GL_SRC_COLOR:
642 case GL_ONE_MINUS_SRC_COLOR:
643 case GL_DST_COLOR:
644 case GL_ONE_MINUS_DST_COLOR:
645 case GL_SRC_ALPHA:
646 case GL_ONE_MINUS_SRC_ALPHA:
647 case GL_DST_ALPHA:
648 case GL_ONE_MINUS_DST_ALPHA:
649 case GL_CONSTANT_COLOR:
650 case GL_ONE_MINUS_CONSTANT_COLOR:
651 case GL_CONSTANT_ALPHA:
652 case GL_ONE_MINUS_CONSTANT_ALPHA:
653 case GL_SRC_ALPHA_SATURATE:
654 break;
655 default:
656 return error(GL_INVALID_ENUM);
657 }
John Bauman66b8ab22014-05-06 15:57:45 -0400658
Nicolas Capensf160b172014-11-26 11:58:23 -0500659 switch(dstAlpha)
660 {
661 case GL_ZERO:
662 case GL_ONE:
663 case GL_SRC_COLOR:
664 case GL_ONE_MINUS_SRC_COLOR:
665 case GL_DST_COLOR:
666 case GL_ONE_MINUS_DST_COLOR:
667 case GL_SRC_ALPHA:
668 case GL_ONE_MINUS_SRC_ALPHA:
669 case GL_DST_ALPHA:
670 case GL_ONE_MINUS_DST_ALPHA:
671 case GL_CONSTANT_COLOR:
672 case GL_ONE_MINUS_CONSTANT_COLOR:
673 case GL_CONSTANT_ALPHA:
674 case GL_ONE_MINUS_CONSTANT_ALPHA:
675 break;
676 default:
677 return error(GL_INVALID_ENUM);
678 }
John Bauman66b8ab22014-05-06 15:57:45 -0400679
Nicolas Capensf160b172014-11-26 11:58:23 -0500680 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400681
Nicolas Capensf160b172014-11-26 11:58:23 -0500682 if(context)
683 {
684 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
685 }
John Bauman66b8ab22014-05-06 15:57:45 -0400686}
687
688void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
Nicolas Capens54b721d2014-12-12 12:50:04 -0500689{
690 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
Nicolas Capens4cadfe32014-12-10 22:26:26 -0500691
Nicolas Capensf160b172014-11-26 11:58:23 -0500692 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
693 target, size, data, usage);
John Bauman66b8ab22014-05-06 15:57:45 -0400694
Nicolas Capensf160b172014-11-26 11:58:23 -0500695 if(size < 0)
696 {
697 return error(GL_INVALID_VALUE);
698 }
John Bauman66b8ab22014-05-06 15:57:45 -0400699
Alexis Hetued306182015-04-02 12:02:28 -0400700 egl::GLint clientVersion = egl::getClientVersion();
701
Nicolas Capensf160b172014-11-26 11:58:23 -0500702 switch(usage)
703 {
704 case GL_STREAM_DRAW:
705 case GL_STATIC_DRAW:
706 case GL_DYNAMIC_DRAW:
707 break;
Alexis Hetued306182015-04-02 12:02:28 -0400708 case GL_STREAM_READ:
709 case GL_STREAM_COPY:
710 case GL_STATIC_READ:
711 case GL_STATIC_COPY:
712 case GL_DYNAMIC_READ:
713 case GL_DYNAMIC_COPY:
714 if(clientVersion < 3)
715 {
716 return error(GL_INVALID_ENUM);
717 }
718 break;
Nicolas Capensf160b172014-11-26 11:58:23 -0500719 default:
720 return error(GL_INVALID_ENUM);
721 }
John Bauman66b8ab22014-05-06 15:57:45 -0400722
Nicolas Capensf160b172014-11-26 11:58:23 -0500723 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400724
Nicolas Capensf160b172014-11-26 11:58:23 -0500725 if(context)
726 {
727 es2::Buffer *buffer;
John Bauman66b8ab22014-05-06 15:57:45 -0400728
Nicolas Capensf160b172014-11-26 11:58:23 -0500729 switch(target)
730 {
731 case GL_ARRAY_BUFFER:
732 buffer = context->getArrayBuffer();
733 break;
734 case GL_ELEMENT_ARRAY_BUFFER:
735 buffer = context->getElementArrayBuffer();
736 break;
737 default:
738 return error(GL_INVALID_ENUM);
739 }
John Bauman66b8ab22014-05-06 15:57:45 -0400740
Nicolas Capensf160b172014-11-26 11:58:23 -0500741 if(!buffer)
742 {
Alexis Hetued306182015-04-02 12:02:28 -0400743 // A null buffer means that "0" is bound to the requested buffer target
Nicolas Capensf160b172014-11-26 11:58:23 -0500744 return error(GL_INVALID_OPERATION);
745 }
John Bauman66b8ab22014-05-06 15:57:45 -0400746
Nicolas Capensf160b172014-11-26 11:58:23 -0500747 buffer->bufferData(data, size, usage);
748 }
John Bauman66b8ab22014-05-06 15:57:45 -0400749}
750
751void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
Nicolas Capens54b721d2014-12-12 12:50:04 -0500752{
753 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
754 offset = static_cast<GLint>(offset);
Nicolas Capens4cadfe32014-12-10 22:26:26 -0500755
Nicolas Capensf160b172014-11-26 11:58:23 -0500756 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
757 target, offset, size, data);
John Bauman66b8ab22014-05-06 15:57:45 -0400758
Nicolas Capensf160b172014-11-26 11:58:23 -0500759 if(size < 0 || offset < 0)
760 {
761 return error(GL_INVALID_VALUE);
762 }
John Bauman66b8ab22014-05-06 15:57:45 -0400763
Nicolas Capensf160b172014-11-26 11:58:23 -0500764 if(data == NULL)
765 {
766 return;
767 }
John Bauman66b8ab22014-05-06 15:57:45 -0400768
Nicolas Capensf160b172014-11-26 11:58:23 -0500769 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400770
Nicolas Capensf160b172014-11-26 11:58:23 -0500771 if(context)
772 {
773 es2::Buffer *buffer;
John Bauman66b8ab22014-05-06 15:57:45 -0400774
Nicolas Capensf160b172014-11-26 11:58:23 -0500775 switch(target)
776 {
777 case GL_ARRAY_BUFFER:
778 buffer = context->getArrayBuffer();
779 break;
780 case GL_ELEMENT_ARRAY_BUFFER:
781 buffer = context->getElementArrayBuffer();
782 break;
783 default:
784 return error(GL_INVALID_ENUM);
785 }
John Bauman66b8ab22014-05-06 15:57:45 -0400786
Nicolas Capensf160b172014-11-26 11:58:23 -0500787 if(!buffer)
788 {
Alexis Hetued306182015-04-02 12:02:28 -0400789 // A null buffer means that "0" is bound to the requested buffer target
Nicolas Capensf160b172014-11-26 11:58:23 -0500790 return error(GL_INVALID_OPERATION);
791 }
John Bauman66b8ab22014-05-06 15:57:45 -0400792
Nicolas Capensf160b172014-11-26 11:58:23 -0500793 if((size_t)size + offset > buffer->size())
John Bauman66b8ab22014-05-06 15:57:45 -0400794 {
795 return error(GL_INVALID_VALUE);
796 }
797
Nicolas Capensf160b172014-11-26 11:58:23 -0500798 buffer->bufferSubData(data, size, offset);
799 }
800}
John Bauman66b8ab22014-05-06 15:57:45 -0400801
Nicolas Capensf160b172014-11-26 11:58:23 -0500802GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
803{
804 TRACE("(GLenum target = 0x%X)", target);
805
806 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
807 {
808 return error(GL_INVALID_ENUM, 0);
809 }
810
811 es2::Context *context = es2::getContext();
812
813 if(context)
814 {
815 es2::Framebuffer *framebuffer = NULL;
816 if(target == GL_READ_FRAMEBUFFER_ANGLE)
817 {
818 framebuffer = context->getReadFramebuffer();
819 }
820 else
821 {
822 framebuffer = context->getDrawFramebuffer();
823 }
824
825 return framebuffer->completeness();
826 }
827
828 return 0;
829}
830
831void GL_APIENTRY glClear(GLbitfield mask)
832{
833 TRACE("(GLbitfield mask = %X)", mask);
834
835 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
836 {
837 return error(GL_INVALID_VALUE);
838 }
839
840 es2::Context *context = es2::getContext();
841
842 if(context)
843 {
844 context->clear(mask);
845 }
John Bauman66b8ab22014-05-06 15:57:45 -0400846}
847
848void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
849{
Nicolas Capensf160b172014-11-26 11:58:23 -0500850 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
851 red, green, blue, alpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400852
Nicolas Capensf160b172014-11-26 11:58:23 -0500853 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400854
Nicolas Capensf160b172014-11-26 11:58:23 -0500855 if(context)
856 {
857 context->setClearColor(red, green, blue, alpha);
858 }
John Bauman66b8ab22014-05-06 15:57:45 -0400859}
860
861void GL_APIENTRY glClearDepthf(GLclampf depth)
862{
Nicolas Capensf160b172014-11-26 11:58:23 -0500863 TRACE("(GLclampf depth = %f)", depth);
John Bauman66b8ab22014-05-06 15:57:45 -0400864
Nicolas Capensf160b172014-11-26 11:58:23 -0500865 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400866
Nicolas Capensf160b172014-11-26 11:58:23 -0500867 if(context)
868 {
869 context->setClearDepth(depth);
870 }
John Bauman66b8ab22014-05-06 15:57:45 -0400871}
872
873void GL_APIENTRY glClearStencil(GLint s)
874{
Nicolas Capensf160b172014-11-26 11:58:23 -0500875 TRACE("(GLint s = %d)", s);
John Bauman66b8ab22014-05-06 15:57:45 -0400876
Nicolas Capensf160b172014-11-26 11:58:23 -0500877 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400878
Nicolas Capensf160b172014-11-26 11:58:23 -0500879 if(context)
880 {
881 context->setClearStencil(s);
882 }
John Bauman66b8ab22014-05-06 15:57:45 -0400883}
884
885void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
886{
Nicolas Capensf160b172014-11-26 11:58:23 -0500887 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
888 red, green, blue, alpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400889
Nicolas Capensf160b172014-11-26 11:58:23 -0500890 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400891
Nicolas Capensf160b172014-11-26 11:58:23 -0500892 if(context)
893 {
894 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
895 }
John Bauman66b8ab22014-05-06 15:57:45 -0400896}
897
898void GL_APIENTRY glCompileShader(GLuint shader)
899{
Nicolas Capensf160b172014-11-26 11:58:23 -0500900 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400901
Nicolas Capensf160b172014-11-26 11:58:23 -0500902 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400903
Nicolas Capensf160b172014-11-26 11:58:23 -0500904 if(context)
905 {
906 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400907
Nicolas Capensf160b172014-11-26 11:58:23 -0500908 if(!shaderObject)
909 {
910 if(context->getProgram(shader))
911 {
912 return error(GL_INVALID_OPERATION);
913 }
914 else
915 {
916 return error(GL_INVALID_VALUE);
917 }
918 }
John Bauman66b8ab22014-05-06 15:57:45 -0400919
Nicolas Capensf160b172014-11-26 11:58:23 -0500920 shaderObject->compile();
921 }
John Bauman66b8ab22014-05-06 15:57:45 -0400922}
923
Nicolas Capens08e90f02014-11-21 12:49:12 -0500924void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
John Bauman66b8ab22014-05-06 15:57:45 -0400925 GLint border, GLsizei imageSize, const GLvoid* data)
926{
Nicolas Capensf160b172014-11-26 11:58:23 -0500927 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
928 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
929 target, level, internalformat, width, height, border, imageSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -0400930
Nicolas Capensf160b172014-11-26 11:58:23 -0500931 if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
932 {
933 return error(GL_INVALID_VALUE);
934 }
John Bauman66b8ab22014-05-06 15:57:45 -0400935
Alexis Hetued306182015-04-02 12:02:28 -0400936 egl::GLint clientVersion = egl::getClientVersion();
937
Nicolas Capensf160b172014-11-26 11:58:23 -0500938 switch(internalformat)
939 {
Nicolas Capens22658242014-11-29 00:31:41 -0500940 case GL_ETC1_RGB8_OES:
941 break;
Alexis Hetued306182015-04-02 12:02:28 -0400942 case GL_COMPRESSED_R11_EAC:
943 case GL_COMPRESSED_SIGNED_R11_EAC:
944 case GL_COMPRESSED_RG11_EAC:
945 case GL_COMPRESSED_SIGNED_RG11_EAC:
946 case GL_COMPRESSED_RGB8_ETC2:
947 case GL_COMPRESSED_SRGB8_ETC2:
948 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
949 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
950 case GL_COMPRESSED_RGBA8_ETC2_EAC:
951 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
952 if(clientVersion >= 3)
953 {
954 break;
955 }
956 return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -0500957 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
958 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
959 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
960 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
961 if(!S3TC_SUPPORT)
962 {
963 return error(GL_INVALID_ENUM);
964 }
965 break;
966 case GL_DEPTH_COMPONENT:
967 case GL_DEPTH_COMPONENT16:
968 case GL_DEPTH_COMPONENT32_OES:
969 case GL_DEPTH_STENCIL_OES:
970 case GL_DEPTH24_STENCIL8_OES:
971 return error(GL_INVALID_OPERATION);
972 default:
973 return error(GL_INVALID_ENUM);
974 }
John Bauman66b8ab22014-05-06 15:57:45 -0400975
Nicolas Capensf160b172014-11-26 11:58:23 -0500976 if(border != 0)
977 {
978 return error(GL_INVALID_VALUE);
979 }
John Bauman66b8ab22014-05-06 15:57:45 -0400980
Nicolas Capensf160b172014-11-26 11:58:23 -0500981 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400982
Nicolas Capensf160b172014-11-26 11:58:23 -0500983 if(context)
984 {
Alexis Hetub027aa92015-01-19 15:56:12 -0500985 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -0500986 {
987 return error(GL_INVALID_VALUE);
988 }
John Bauman66b8ab22014-05-06 15:57:45 -0400989
Nicolas Capensf160b172014-11-26 11:58:23 -0500990 switch(target)
991 {
992 case GL_TEXTURE_2D:
993 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
994 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
995 {
996 return error(GL_INVALID_VALUE);
997 }
998 break;
999 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1000 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1001 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1002 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1003 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1004 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1005 if(width != height)
1006 {
1007 return error(GL_INVALID_VALUE);
1008 }
John Bauman66b8ab22014-05-06 15:57:45 -04001009
Nicolas Capensf160b172014-11-26 11:58:23 -05001010 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1011 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
1012 {
1013 return error(GL_INVALID_VALUE);
1014 }
1015 break;
1016 default:
1017 return error(GL_INVALID_ENUM);
1018 }
John Bauman66b8ab22014-05-06 15:57:45 -04001019
Nicolas Capensf160b172014-11-26 11:58:23 -05001020 if(imageSize != es2::ComputeCompressedSize(width, height, internalformat))
1021 {
1022 return error(GL_INVALID_VALUE);
1023 }
John Bauman66b8ab22014-05-06 15:57:45 -04001024
Nicolas Capensf160b172014-11-26 11:58:23 -05001025 if(target == GL_TEXTURE_2D)
1026 {
1027 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04001028
Nicolas Capensf160b172014-11-26 11:58:23 -05001029 if(!texture)
1030 {
1031 return error(GL_INVALID_OPERATION);
1032 }
John Bauman66b8ab22014-05-06 15:57:45 -04001033
Nicolas Capensf160b172014-11-26 11:58:23 -05001034 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
1035 }
1036 else
1037 {
1038 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04001039
Nicolas Capensf160b172014-11-26 11:58:23 -05001040 if(!texture)
1041 {
1042 return error(GL_INVALID_OPERATION);
1043 }
John Bauman66b8ab22014-05-06 15:57:45 -04001044
Nicolas Capensf160b172014-11-26 11:58:23 -05001045 switch(target)
1046 {
1047 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1048 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1049 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1050 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1051 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1052 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1053 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
1054 break;
1055 default: UNREACHABLE();
1056 }
1057 }
1058 }
John Bauman66b8ab22014-05-06 15:57:45 -04001059}
1060
1061void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Nicolas Capensf160b172014-11-26 11:58:23 -05001062 GLenum format, GLsizei imageSize, const GLvoid* data)
John Bauman66b8ab22014-05-06 15:57:45 -04001063{
Nicolas Capensf160b172014-11-26 11:58:23 -05001064 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1065 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
1066 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
1067 target, level, xoffset, yoffset, width, height, format, imageSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -04001068
Nicolas Capensf160b172014-11-26 11:58:23 -05001069 if(!es2::IsTextureTarget(target))
1070 {
1071 return error(GL_INVALID_ENUM);
1072 }
John Bauman66b8ab22014-05-06 15:57:45 -04001073
Nicolas Capensf160b172014-11-26 11:58:23 -05001074 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
1075 {
1076 return error(GL_INVALID_VALUE);
1077 }
John Bauman66b8ab22014-05-06 15:57:45 -04001078
Alexis Hetued306182015-04-02 12:02:28 -04001079 egl::GLint clientVersion = egl::getClientVersion();
1080
Nicolas Capensf160b172014-11-26 11:58:23 -05001081 switch(format)
1082 {
Nicolas Capens22658242014-11-29 00:31:41 -05001083 case GL_ETC1_RGB8_OES:
1084 break;
Alexis Hetued306182015-04-02 12:02:28 -04001085 case GL_COMPRESSED_R11_EAC:
1086 case GL_COMPRESSED_SIGNED_R11_EAC:
1087 case GL_COMPRESSED_RG11_EAC:
1088 case GL_COMPRESSED_SIGNED_RG11_EAC:
1089 case GL_COMPRESSED_RGB8_ETC2:
1090 case GL_COMPRESSED_SRGB8_ETC2:
1091 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1092 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1093 case GL_COMPRESSED_RGBA8_ETC2_EAC:
1094 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
1095 if(clientVersion >= 3)
1096 {
1097 break;
1098 }
1099 return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05001100 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1101 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1102 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1103 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1104 if(!S3TC_SUPPORT)
1105 {
1106 return error(GL_INVALID_ENUM);
1107 }
1108 break;
1109 default:
1110 return error(GL_INVALID_ENUM);
1111 }
John Bauman66b8ab22014-05-06 15:57:45 -04001112
Nicolas Capensf160b172014-11-26 11:58:23 -05001113 if(width == 0 || height == 0 || data == NULL)
1114 {
1115 return;
1116 }
John Bauman66b8ab22014-05-06 15:57:45 -04001117
Nicolas Capensf160b172014-11-26 11:58:23 -05001118 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001119
Nicolas Capensf160b172014-11-26 11:58:23 -05001120 if(context)
1121 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001122 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05001123 {
1124 return error(GL_INVALID_VALUE);
1125 }
John Bauman66b8ab22014-05-06 15:57:45 -04001126
Nicolas Capensf160b172014-11-26 11:58:23 -05001127 if(imageSize != es2::ComputeCompressedSize(width, height, format))
1128 {
1129 return error(GL_INVALID_VALUE);
1130 }
John Bauman66b8ab22014-05-06 15:57:45 -04001131
Nicolas Capensf160b172014-11-26 11:58:23 -05001132 if(xoffset % 4 != 0 || yoffset % 4 != 0)
1133 {
1134 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
1135 return error(GL_INVALID_OPERATION);
1136 }
John Bauman66b8ab22014-05-06 15:57:45 -04001137
Nicolas Capensf160b172014-11-26 11:58:23 -05001138 if(target == GL_TEXTURE_2D)
1139 {
1140 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04001141
Nicolas Capensf160b172014-11-26 11:58:23 -05001142 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
1143 {
1144 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
1145 }
1146 }
1147 else if(es2::IsCubemapTextureTarget(target))
1148 {
1149 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04001150
Nicolas Capensf160b172014-11-26 11:58:23 -05001151 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
1152 {
1153 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
1154 }
1155 }
1156 else
1157 {
1158 UNREACHABLE();
1159 }
1160 }
John Bauman66b8ab22014-05-06 15:57:45 -04001161}
1162
1163void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1164{
Nicolas Capensf160b172014-11-26 11:58:23 -05001165 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
1166 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
1167 target, level, internalformat, x, y, width, height, border);
John Bauman66b8ab22014-05-06 15:57:45 -04001168
Nicolas Capensf160b172014-11-26 11:58:23 -05001169 if(!validImageSize(level, width, height))
1170 {
1171 return error(GL_INVALID_VALUE);
1172 }
John Bauman66b8ab22014-05-06 15:57:45 -04001173
Nicolas Capensf160b172014-11-26 11:58:23 -05001174 if(border != 0)
1175 {
1176 return error(GL_INVALID_VALUE);
1177 }
John Bauman66b8ab22014-05-06 15:57:45 -04001178
Nicolas Capensf160b172014-11-26 11:58:23 -05001179 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001180
Nicolas Capensf160b172014-11-26 11:58:23 -05001181 if(context)
1182 {
1183 switch(target)
1184 {
1185 case GL_TEXTURE_2D:
1186 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
1187 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
1188 {
1189 return error(GL_INVALID_VALUE);
1190 }
1191 break;
1192 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1193 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1194 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1195 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1196 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1197 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1198 if(width != height)
1199 {
1200 return error(GL_INVALID_VALUE);
1201 }
John Bauman66b8ab22014-05-06 15:57:45 -04001202
Nicolas Capensf160b172014-11-26 11:58:23 -05001203 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1204 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
1205 {
1206 return error(GL_INVALID_VALUE);
1207 }
1208 break;
1209 default:
1210 return error(GL_INVALID_ENUM);
1211 }
John Bauman66b8ab22014-05-06 15:57:45 -04001212
Nicolas Capensf160b172014-11-26 11:58:23 -05001213 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
John Bauman66b8ab22014-05-06 15:57:45 -04001214
Nicolas Capensf160b172014-11-26 11:58:23 -05001215 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1216 {
1217 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1218 }
John Bauman66b8ab22014-05-06 15:57:45 -04001219
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001220 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capensf160b172014-11-26 11:58:23 -05001221 {
1222 return error(GL_INVALID_OPERATION);
1223 }
John Bauman66b8ab22014-05-06 15:57:45 -04001224
Nicolas Capensf160b172014-11-26 11:58:23 -05001225 es2::Renderbuffer *source = framebuffer->getColorbuffer();
1226 GLenum colorbufferFormat = source->getFormat();
John Bauman66b8ab22014-05-06 15:57:45 -04001227
Alexis Hetub027aa92015-01-19 15:56:12 -05001228 if(!validateColorBufferFormat(internalformat, colorbufferFormat))
Nicolas Capensf160b172014-11-26 11:58:23 -05001229 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001230 return;
Nicolas Capensf160b172014-11-26 11:58:23 -05001231 }
John Bauman66b8ab22014-05-06 15:57:45 -04001232
Nicolas Capensf160b172014-11-26 11:58:23 -05001233 if(target == GL_TEXTURE_2D)
1234 {
1235 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04001236
Nicolas Capensf160b172014-11-26 11:58:23 -05001237 if(!texture)
1238 {
1239 return error(GL_INVALID_OPERATION);
1240 }
John Bauman66b8ab22014-05-06 15:57:45 -04001241
Nicolas Capensf160b172014-11-26 11:58:23 -05001242 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
1243 }
1244 else if(es2::IsCubemapTextureTarget(target))
1245 {
1246 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04001247
Nicolas Capensf160b172014-11-26 11:58:23 -05001248 if(!texture)
1249 {
1250 return error(GL_INVALID_OPERATION);
1251 }
John Bauman66b8ab22014-05-06 15:57:45 -04001252
Nicolas Capensf160b172014-11-26 11:58:23 -05001253 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
1254 }
1255 else UNREACHABLE();
1256 }
John Bauman66b8ab22014-05-06 15:57:45 -04001257}
1258
1259void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1260{
Nicolas Capensf160b172014-11-26 11:58:23 -05001261 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1262 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
1263 target, level, xoffset, yoffset, x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04001264
Nicolas Capensf160b172014-11-26 11:58:23 -05001265 if(!es2::IsTextureTarget(target))
1266 {
1267 return error(GL_INVALID_ENUM);
1268 }
John Bauman66b8ab22014-05-06 15:57:45 -04001269
Nicolas Capensf160b172014-11-26 11:58:23 -05001270 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
1271 {
1272 return error(GL_INVALID_VALUE);
1273 }
John Bauman66b8ab22014-05-06 15:57:45 -04001274
Nicolas Capensf160b172014-11-26 11:58:23 -05001275 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1276 {
1277 return error(GL_INVALID_VALUE);
1278 }
John Bauman66b8ab22014-05-06 15:57:45 -04001279
Nicolas Capensf160b172014-11-26 11:58:23 -05001280 if(width == 0 || height == 0)
1281 {
1282 return;
1283 }
John Bauman66b8ab22014-05-06 15:57:45 -04001284
Nicolas Capensf160b172014-11-26 11:58:23 -05001285 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001286
Nicolas Capensf160b172014-11-26 11:58:23 -05001287 if(context)
1288 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001289 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05001290 {
1291 return error(GL_INVALID_VALUE);
1292 }
John Bauman66b8ab22014-05-06 15:57:45 -04001293
Nicolas Capensf160b172014-11-26 11:58:23 -05001294 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
John Bauman66b8ab22014-05-06 15:57:45 -04001295
Nicolas Capensf160b172014-11-26 11:58:23 -05001296 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1297 {
1298 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1299 }
John Bauman66b8ab22014-05-06 15:57:45 -04001300
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001301 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capensf160b172014-11-26 11:58:23 -05001302 {
1303 return error(GL_INVALID_OPERATION);
1304 }
John Bauman66b8ab22014-05-06 15:57:45 -04001305
Nicolas Capensf160b172014-11-26 11:58:23 -05001306 es2::Renderbuffer *source = framebuffer->getColorbuffer();
1307 GLenum colorbufferFormat = source->getFormat();
1308 es2::Texture *texture = NULL;
John Bauman66b8ab22014-05-06 15:57:45 -04001309
Nicolas Capensf160b172014-11-26 11:58:23 -05001310 if(target == GL_TEXTURE_2D)
1311 {
1312 texture = context->getTexture2D();
1313 }
1314 else if(es2::IsCubemapTextureTarget(target))
1315 {
1316 texture = context->getTextureCubeMap();
1317 }
1318 else UNREACHABLE();
John Bauman66b8ab22014-05-06 15:57:45 -04001319
Nicolas Capensf160b172014-11-26 11:58:23 -05001320 if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))
1321 {
1322 return;
1323 }
1324
1325 GLenum textureFormat = texture->getFormat(target, level);
1326
Alexis Hetub027aa92015-01-19 15:56:12 -05001327 if(!validateColorBufferFormat(textureFormat, colorbufferFormat))
Nicolas Capensf160b172014-11-26 11:58:23 -05001328 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001329 return;
Nicolas Capensf160b172014-11-26 11:58:23 -05001330 }
John Bauman66b8ab22014-05-06 15:57:45 -04001331
Alexis Hetub027aa92015-01-19 15:56:12 -05001332 texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
Nicolas Capensf160b172014-11-26 11:58:23 -05001333 }
John Bauman66b8ab22014-05-06 15:57:45 -04001334}
1335
1336GLuint GL_APIENTRY glCreateProgram(void)
1337{
Nicolas Capensf160b172014-11-26 11:58:23 -05001338 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04001339
Nicolas Capensf160b172014-11-26 11:58:23 -05001340 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001341
Nicolas Capensf160b172014-11-26 11:58:23 -05001342 if(context)
1343 {
1344 return context->createProgram();
1345 }
John Bauman66b8ab22014-05-06 15:57:45 -04001346
Nicolas Capensf160b172014-11-26 11:58:23 -05001347 return 0;
John Bauman66b8ab22014-05-06 15:57:45 -04001348}
1349
1350GLuint GL_APIENTRY glCreateShader(GLenum type)
1351{
Nicolas Capensf160b172014-11-26 11:58:23 -05001352 TRACE("(GLenum type = 0x%X)", type);
John Bauman66b8ab22014-05-06 15:57:45 -04001353
Nicolas Capensf160b172014-11-26 11:58:23 -05001354 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001355
Nicolas Capensf160b172014-11-26 11:58:23 -05001356 if(context)
1357 {
1358 switch(type)
1359 {
1360 case GL_FRAGMENT_SHADER:
1361 case GL_VERTEX_SHADER:
1362 return context->createShader(type);
1363 default:
1364 return error(GL_INVALID_ENUM, 0);
1365 }
1366 }
John Bauman66b8ab22014-05-06 15:57:45 -04001367
Nicolas Capensf160b172014-11-26 11:58:23 -05001368 return 0;
John Bauman66b8ab22014-05-06 15:57:45 -04001369}
1370
1371void GL_APIENTRY glCullFace(GLenum mode)
1372{
Nicolas Capensf160b172014-11-26 11:58:23 -05001373 TRACE("(GLenum mode = 0x%X)", mode);
John Bauman66b8ab22014-05-06 15:57:45 -04001374
Nicolas Capensf160b172014-11-26 11:58:23 -05001375 switch(mode)
1376 {
1377 case GL_FRONT:
1378 case GL_BACK:
1379 case GL_FRONT_AND_BACK:
1380 {
1381 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001382
Nicolas Capensf160b172014-11-26 11:58:23 -05001383 if(context)
1384 {
1385 context->setCullMode(mode);
1386 }
1387 }
1388 break;
1389 default:
1390 return error(GL_INVALID_ENUM);
1391 }
John Bauman66b8ab22014-05-06 15:57:45 -04001392}
1393
1394void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
1395{
Nicolas Capensf160b172014-11-26 11:58:23 -05001396 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
John Bauman66b8ab22014-05-06 15:57:45 -04001397
Nicolas Capensf160b172014-11-26 11:58:23 -05001398 if(n < 0)
1399 {
1400 return error(GL_INVALID_VALUE);
1401 }
John Bauman66b8ab22014-05-06 15:57:45 -04001402
Nicolas Capensf160b172014-11-26 11:58:23 -05001403 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001404
Nicolas Capensf160b172014-11-26 11:58:23 -05001405 if(context)
1406 {
1407 for(int i = 0; i < n; i++)
1408 {
1409 context->deleteBuffer(buffers[i]);
1410 }
1411 }
John Bauman66b8ab22014-05-06 15:57:45 -04001412}
1413
1414void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
1415{
Nicolas Capensf160b172014-11-26 11:58:23 -05001416 TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
John Bauman66b8ab22014-05-06 15:57:45 -04001417
Nicolas Capensf160b172014-11-26 11:58:23 -05001418 if(n < 0)
1419 {
1420 return error(GL_INVALID_VALUE);
1421 }
John Bauman66b8ab22014-05-06 15:57:45 -04001422
Nicolas Capensf160b172014-11-26 11:58:23 -05001423 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001424
Nicolas Capensf160b172014-11-26 11:58:23 -05001425 if(context)
1426 {
1427 for(int i = 0; i < n; i++)
1428 {
1429 context->deleteFence(fences[i]);
1430 }
1431 }
John Bauman66b8ab22014-05-06 15:57:45 -04001432}
1433
1434void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1435{
Nicolas Capensf160b172014-11-26 11:58:23 -05001436 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04001437
Nicolas Capensf160b172014-11-26 11:58:23 -05001438 if(n < 0)
1439 {
1440 return error(GL_INVALID_VALUE);
1441 }
John Bauman66b8ab22014-05-06 15:57:45 -04001442
Nicolas Capensf160b172014-11-26 11:58:23 -05001443 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001444
Nicolas Capensf160b172014-11-26 11:58:23 -05001445 if(context)
1446 {
1447 for(int i = 0; i < n; i++)
1448 {
1449 if(framebuffers[i] != 0)
1450 {
1451 context->deleteFramebuffer(framebuffers[i]);
1452 }
1453 }
1454 }
John Bauman66b8ab22014-05-06 15:57:45 -04001455}
1456
1457void GL_APIENTRY glDeleteProgram(GLuint program)
1458{
Nicolas Capensf160b172014-11-26 11:58:23 -05001459 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04001460
Nicolas Capensf160b172014-11-26 11:58:23 -05001461 if(program == 0)
1462 {
1463 return;
1464 }
John Bauman66b8ab22014-05-06 15:57:45 -04001465
Nicolas Capensf160b172014-11-26 11:58:23 -05001466 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001467
Nicolas Capensf160b172014-11-26 11:58:23 -05001468 if(context)
1469 {
1470 if(!context->getProgram(program))
1471 {
1472 if(context->getShader(program))
1473 {
1474 return error(GL_INVALID_OPERATION);
1475 }
1476 else
1477 {
1478 return error(GL_INVALID_VALUE);
1479 }
1480 }
John Bauman66b8ab22014-05-06 15:57:45 -04001481
Nicolas Capensf160b172014-11-26 11:58:23 -05001482 context->deleteProgram(program);
1483 }
John Bauman66b8ab22014-05-06 15:57:45 -04001484}
1485
1486void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
1487{
Nicolas Capensf160b172014-11-26 11:58:23 -05001488 TRACE("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
John Bauman66b8ab22014-05-06 15:57:45 -04001489
Nicolas Capensf160b172014-11-26 11:58:23 -05001490 if(n < 0)
1491 {
1492 return error(GL_INVALID_VALUE);
1493 }
John Bauman66b8ab22014-05-06 15:57:45 -04001494
Nicolas Capensf160b172014-11-26 11:58:23 -05001495 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001496
Nicolas Capensf160b172014-11-26 11:58:23 -05001497 if(context)
1498 {
1499 for(int i = 0; i < n; i++)
1500 {
1501 context->deleteQuery(ids[i]);
1502 }
1503 }
John Bauman66b8ab22014-05-06 15:57:45 -04001504}
1505
1506void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1507{
Nicolas Capensf160b172014-11-26 11:58:23 -05001508 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04001509
Nicolas Capensf160b172014-11-26 11:58:23 -05001510 if(n < 0)
1511 {
1512 return error(GL_INVALID_VALUE);
1513 }
John Bauman66b8ab22014-05-06 15:57:45 -04001514
Nicolas Capensf160b172014-11-26 11:58:23 -05001515 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001516
Nicolas Capensf160b172014-11-26 11:58:23 -05001517 if(context)
1518 {
1519 for(int i = 0; i < n; i++)
1520 {
1521 context->deleteRenderbuffer(renderbuffers[i]);
1522 }
1523 }
John Bauman66b8ab22014-05-06 15:57:45 -04001524}
1525
1526void GL_APIENTRY glDeleteShader(GLuint shader)
1527{
Nicolas Capensf160b172014-11-26 11:58:23 -05001528 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -04001529
Nicolas Capensf160b172014-11-26 11:58:23 -05001530 if(shader == 0)
1531 {
1532 return;
1533 }
John Bauman66b8ab22014-05-06 15:57:45 -04001534
Nicolas Capensf160b172014-11-26 11:58:23 -05001535 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001536
Nicolas Capensf160b172014-11-26 11:58:23 -05001537 if(context)
1538 {
1539 if(!context->getShader(shader))
1540 {
1541 if(context->getProgram(shader))
1542 {
1543 return error(GL_INVALID_OPERATION);
1544 }
1545 else
1546 {
1547 return error(GL_INVALID_VALUE);
1548 }
1549 }
John Bauman66b8ab22014-05-06 15:57:45 -04001550
Nicolas Capensf160b172014-11-26 11:58:23 -05001551 context->deleteShader(shader);
1552 }
John Bauman66b8ab22014-05-06 15:57:45 -04001553}
1554
1555void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
1556{
Nicolas Capensf160b172014-11-26 11:58:23 -05001557 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
John Bauman66b8ab22014-05-06 15:57:45 -04001558
Nicolas Capensf160b172014-11-26 11:58:23 -05001559 if(n < 0)
1560 {
1561 return error(GL_INVALID_VALUE);
1562 }
John Bauman66b8ab22014-05-06 15:57:45 -04001563
Nicolas Capensf160b172014-11-26 11:58:23 -05001564 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001565
Nicolas Capensf160b172014-11-26 11:58:23 -05001566 if(context)
1567 {
1568 for(int i = 0; i < n; i++)
1569 {
1570 if(textures[i] != 0)
1571 {
1572 context->deleteTexture(textures[i]);
1573 }
1574 }
1575 }
John Bauman66b8ab22014-05-06 15:57:45 -04001576}
1577
1578void GL_APIENTRY glDepthFunc(GLenum func)
1579{
Nicolas Capensf160b172014-11-26 11:58:23 -05001580 TRACE("(GLenum func = 0x%X)", func);
John Bauman66b8ab22014-05-06 15:57:45 -04001581
Nicolas Capensf160b172014-11-26 11:58:23 -05001582 switch(func)
1583 {
1584 case GL_NEVER:
1585 case GL_ALWAYS:
1586 case GL_LESS:
1587 case GL_LEQUAL:
1588 case GL_EQUAL:
1589 case GL_GREATER:
1590 case GL_GEQUAL:
1591 case GL_NOTEQUAL:
1592 break;
1593 default:
1594 return error(GL_INVALID_ENUM);
1595 }
John Bauman66b8ab22014-05-06 15:57:45 -04001596
Nicolas Capensf160b172014-11-26 11:58:23 -05001597 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001598
Nicolas Capensf160b172014-11-26 11:58:23 -05001599 if(context)
1600 {
1601 context->setDepthFunc(func);
1602 }
John Bauman66b8ab22014-05-06 15:57:45 -04001603}
1604
1605void GL_APIENTRY glDepthMask(GLboolean flag)
1606{
Nicolas Capensf160b172014-11-26 11:58:23 -05001607 TRACE("(GLboolean flag = %d)", flag);
John Bauman66b8ab22014-05-06 15:57:45 -04001608
Nicolas Capensf160b172014-11-26 11:58:23 -05001609 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001610
Nicolas Capensf160b172014-11-26 11:58:23 -05001611 if(context)
1612 {
1613 context->setDepthMask(flag != GL_FALSE);
1614 }
John Bauman66b8ab22014-05-06 15:57:45 -04001615}
1616
1617void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
1618{
Nicolas Capensf160b172014-11-26 11:58:23 -05001619 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
John Bauman66b8ab22014-05-06 15:57:45 -04001620
Nicolas Capensf160b172014-11-26 11:58:23 -05001621 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001622
Nicolas Capensf160b172014-11-26 11:58:23 -05001623 if(context)
1624 {
1625 context->setDepthRange(zNear, zFar);
1626 }
John Bauman66b8ab22014-05-06 15:57:45 -04001627}
1628
1629void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)
1630{
Nicolas Capensf160b172014-11-26 11:58:23 -05001631 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
John Bauman66b8ab22014-05-06 15:57:45 -04001632
Nicolas Capensf160b172014-11-26 11:58:23 -05001633 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001634
Nicolas Capensf160b172014-11-26 11:58:23 -05001635 if(context)
1636 {
John Bauman66b8ab22014-05-06 15:57:45 -04001637
Nicolas Capensf160b172014-11-26 11:58:23 -05001638 es2::Program *programObject = context->getProgram(program);
1639 es2::Shader *shaderObject = context->getShader(shader);
Nicolas Capens08e90f02014-11-21 12:49:12 -05001640
Nicolas Capensf160b172014-11-26 11:58:23 -05001641 if(!programObject)
1642 {
1643 es2::Shader *shaderByProgramHandle;
1644 shaderByProgramHandle = context->getShader(program);
1645 if(!shaderByProgramHandle)
1646 {
1647 return error(GL_INVALID_VALUE);
1648 }
1649 else
1650 {
1651 return error(GL_INVALID_OPERATION);
1652 }
1653 }
John Bauman66b8ab22014-05-06 15:57:45 -04001654
Nicolas Capensf160b172014-11-26 11:58:23 -05001655 if(!shaderObject)
1656 {
1657 es2::Program *programByShaderHandle = context->getProgram(shader);
1658 if(!programByShaderHandle)
1659 {
1660 return error(GL_INVALID_VALUE);
1661 }
1662 else
1663 {
1664 return error(GL_INVALID_OPERATION);
1665 }
1666 }
John Bauman66b8ab22014-05-06 15:57:45 -04001667
Nicolas Capensf160b172014-11-26 11:58:23 -05001668 if(!programObject->detachShader(shaderObject))
1669 {
1670 return error(GL_INVALID_OPERATION);
1671 }
1672 }
John Bauman66b8ab22014-05-06 15:57:45 -04001673}
1674
1675void GL_APIENTRY glDisable(GLenum cap)
1676{
Nicolas Capensf160b172014-11-26 11:58:23 -05001677 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04001678
Nicolas Capensf160b172014-11-26 11:58:23 -05001679 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001680
Nicolas Capensf160b172014-11-26 11:58:23 -05001681 if(context)
1682 {
1683 switch(cap)
1684 {
1685 case GL_CULL_FACE: context->setCullFace(false); break;
1686 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1687 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1688 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1689 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1690 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1691 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1692 case GL_BLEND: context->setBlend(false); break;
1693 case GL_DITHER: context->setDither(false); break;
Alexis Hetufceb1832015-03-10 16:42:04 -04001694 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndex(false); break;
1695 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscard(false); break;
Nicolas Capensf160b172014-11-26 11:58:23 -05001696 default:
1697 return error(GL_INVALID_ENUM);
1698 }
1699 }
John Bauman66b8ab22014-05-06 15:57:45 -04001700}
1701
1702void GL_APIENTRY glDisableVertexAttribArray(GLuint index)
1703{
Nicolas Capensf160b172014-11-26 11:58:23 -05001704 TRACE("(GLuint index = %d)", index);
John Bauman66b8ab22014-05-06 15:57:45 -04001705
Nicolas Capensf160b172014-11-26 11:58:23 -05001706 if(index >= es2::MAX_VERTEX_ATTRIBS)
1707 {
1708 return error(GL_INVALID_VALUE);
1709 }
John Bauman66b8ab22014-05-06 15:57:45 -04001710
Nicolas Capensf160b172014-11-26 11:58:23 -05001711 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001712
Nicolas Capensf160b172014-11-26 11:58:23 -05001713 if(context)
1714 {
1715 context->setEnableVertexAttribArray(index, false);
1716 }
John Bauman66b8ab22014-05-06 15:57:45 -04001717}
1718
1719void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
1720{
Nicolas Capensf160b172014-11-26 11:58:23 -05001721 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
John Bauman66b8ab22014-05-06 15:57:45 -04001722
Alexis Hetued306182015-04-02 12:02:28 -04001723 switch(mode)
1724 {
1725 case GL_POINTS:
1726 case GL_LINES:
1727 case GL_LINE_LOOP:
1728 case GL_LINE_STRIP:
1729 case GL_TRIANGLES:
1730 case GL_TRIANGLE_FAN:
1731 case GL_TRIANGLE_STRIP:
1732 break;
1733 default:
1734 return error(GL_INVALID_ENUM);
1735 }
1736
Nicolas Capensf160b172014-11-26 11:58:23 -05001737 if(count < 0 || first < 0)
1738 {
1739 return error(GL_INVALID_VALUE);
1740 }
John Bauman66b8ab22014-05-06 15:57:45 -04001741
Nicolas Capensf160b172014-11-26 11:58:23 -05001742 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001743
Nicolas Capensf160b172014-11-26 11:58:23 -05001744 if(context)
1745 {
1746 context->drawArrays(mode, first, count);
1747 }
John Bauman66b8ab22014-05-06 15:57:45 -04001748}
1749
1750void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
1751{
Nicolas Capensf160b172014-11-26 11:58:23 -05001752 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
1753 mode, count, type, indices);
John Bauman66b8ab22014-05-06 15:57:45 -04001754
Alexis Hetued306182015-04-02 12:02:28 -04001755 switch(mode)
1756 {
1757 case GL_POINTS:
1758 case GL_LINES:
1759 case GL_LINE_LOOP:
1760 case GL_LINE_STRIP:
1761 case GL_TRIANGLES:
1762 case GL_TRIANGLE_FAN:
1763 case GL_TRIANGLE_STRIP:
1764 break;
1765 default:
1766 return error(GL_INVALID_ENUM);
1767 }
1768
Nicolas Capensf160b172014-11-26 11:58:23 -05001769 if(count < 0)
1770 {
1771 return error(GL_INVALID_VALUE);
1772 }
John Bauman66b8ab22014-05-06 15:57:45 -04001773
Nicolas Capensf160b172014-11-26 11:58:23 -05001774 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001775
Nicolas Capensf160b172014-11-26 11:58:23 -05001776 if(context)
1777 {
1778 switch(type)
1779 {
1780 case GL_UNSIGNED_BYTE:
1781 case GL_UNSIGNED_SHORT:
1782 case GL_UNSIGNED_INT:
1783 break;
1784 default:
1785 return error(GL_INVALID_ENUM);
1786 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05001787
Nicolas Capensf160b172014-11-26 11:58:23 -05001788 context->drawElements(mode, count, type, indices);
1789 }
John Bauman66b8ab22014-05-06 15:57:45 -04001790}
1791
1792void GL_APIENTRY glEnable(GLenum cap)
1793{
Nicolas Capensf160b172014-11-26 11:58:23 -05001794 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04001795
Nicolas Capensf160b172014-11-26 11:58:23 -05001796 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001797
Nicolas Capensf160b172014-11-26 11:58:23 -05001798 if(context)
1799 {
1800 switch(cap)
1801 {
1802 case GL_CULL_FACE: context->setCullFace(true); break;
1803 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1804 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1805 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1806 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1807 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1808 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1809 case GL_BLEND: context->setBlend(true); break;
1810 case GL_DITHER: context->setDither(true); break;
Alexis Hetufceb1832015-03-10 16:42:04 -04001811 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndex(true); break;
1812 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscard(true); break;
Nicolas Capensf160b172014-11-26 11:58:23 -05001813 default:
1814 return error(GL_INVALID_ENUM);
1815 }
1816 }
John Bauman66b8ab22014-05-06 15:57:45 -04001817}
1818
1819void GL_APIENTRY glEnableVertexAttribArray(GLuint index)
1820{
Nicolas Capensf160b172014-11-26 11:58:23 -05001821 TRACE("(GLuint index = %d)", index);
John Bauman66b8ab22014-05-06 15:57:45 -04001822
Nicolas Capensf160b172014-11-26 11:58:23 -05001823 if(index >= es2::MAX_VERTEX_ATTRIBS)
1824 {
1825 return error(GL_INVALID_VALUE);
1826 }
John Bauman66b8ab22014-05-06 15:57:45 -04001827
Nicolas Capensf160b172014-11-26 11:58:23 -05001828 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001829
Nicolas Capensf160b172014-11-26 11:58:23 -05001830 if(context)
1831 {
1832 context->setEnableVertexAttribArray(index, true);
1833 }
John Bauman66b8ab22014-05-06 15:57:45 -04001834}
1835
1836void GL_APIENTRY glEndQueryEXT(GLenum target)
1837{
Nicolas Capensf160b172014-11-26 11:58:23 -05001838 TRACE("GLenum target = 0x%X)", target);
John Bauman66b8ab22014-05-06 15:57:45 -04001839
Nicolas Capensf160b172014-11-26 11:58:23 -05001840 switch(target)
1841 {
1842 case GL_ANY_SAMPLES_PASSED_EXT:
1843 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1844 break;
1845 default:
1846 return error(GL_INVALID_ENUM);
1847 }
John Bauman66b8ab22014-05-06 15:57:45 -04001848
Nicolas Capensf160b172014-11-26 11:58:23 -05001849 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001850
Nicolas Capensf160b172014-11-26 11:58:23 -05001851 if(context)
1852 {
1853 context->endQuery(target);
1854 }
John Bauman66b8ab22014-05-06 15:57:45 -04001855}
1856
1857void GL_APIENTRY glFinishFenceNV(GLuint fence)
1858{
Nicolas Capensf160b172014-11-26 11:58:23 -05001859 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04001860
Nicolas Capensf160b172014-11-26 11:58:23 -05001861 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001862
Nicolas Capensf160b172014-11-26 11:58:23 -05001863 if(context)
1864 {
1865 es2::Fence* fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04001866
Nicolas Capensf160b172014-11-26 11:58:23 -05001867 if(fenceObject == NULL)
1868 {
1869 return error(GL_INVALID_OPERATION);
1870 }
John Bauman66b8ab22014-05-06 15:57:45 -04001871
Nicolas Capensf160b172014-11-26 11:58:23 -05001872 fenceObject->finishFence();
1873 }
John Bauman66b8ab22014-05-06 15:57:45 -04001874}
1875
1876void GL_APIENTRY glFinish(void)
1877{
Nicolas Capensf160b172014-11-26 11:58:23 -05001878 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04001879
Nicolas Capensf160b172014-11-26 11:58:23 -05001880 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001881
Nicolas Capensf160b172014-11-26 11:58:23 -05001882 if(context)
1883 {
1884 context->finish();
1885 }
John Bauman66b8ab22014-05-06 15:57:45 -04001886}
1887
1888void GL_APIENTRY glFlush(void)
1889{
Nicolas Capensf160b172014-11-26 11:58:23 -05001890 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04001891
Nicolas Capensf160b172014-11-26 11:58:23 -05001892 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001893
Nicolas Capensf160b172014-11-26 11:58:23 -05001894 if(context)
1895 {
1896 context->flush();
1897 }
John Bauman66b8ab22014-05-06 15:57:45 -04001898}
1899
1900void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1901{
Nicolas Capensf160b172014-11-26 11:58:23 -05001902 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1903 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04001904
Nicolas Capensf160b172014-11-26 11:58:23 -05001905 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) ||
1906 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
1907 {
1908 return error(GL_INVALID_ENUM);
1909 }
John Bauman66b8ab22014-05-06 15:57:45 -04001910
Nicolas Capensf160b172014-11-26 11:58:23 -05001911 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001912
Nicolas Capensf160b172014-11-26 11:58:23 -05001913 if(context)
1914 {
1915 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001916 GLuint framebufferName = 0;
Nicolas Capensf160b172014-11-26 11:58:23 -05001917 if(target == GL_READ_FRAMEBUFFER_ANGLE)
1918 {
1919 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001920 framebufferName = context->getReadFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05001921 }
1922 else
1923 {
1924 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001925 framebufferName = context->getDrawFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05001926 }
John Bauman66b8ab22014-05-06 15:57:45 -04001927
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001928 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
Nicolas Capensf160b172014-11-26 11:58:23 -05001929 {
1930 return error(GL_INVALID_OPERATION);
1931 }
John Bauman66b8ab22014-05-06 15:57:45 -04001932
Nicolas Capensf160b172014-11-26 11:58:23 -05001933 switch(attachment)
1934 {
1935 case GL_COLOR_ATTACHMENT0:
1936 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1937 break;
1938 case GL_DEPTH_ATTACHMENT:
1939 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1940 break;
1941 case GL_STENCIL_ATTACHMENT:
1942 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1943 break;
1944 default:
1945 return error(GL_INVALID_ENUM);
1946 }
1947 }
John Bauman66b8ab22014-05-06 15:57:45 -04001948}
1949
1950void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1951{
Nicolas Capensf160b172014-11-26 11:58:23 -05001952 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1953 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
John Bauman66b8ab22014-05-06 15:57:45 -04001954
Nicolas Capensf160b172014-11-26 11:58:23 -05001955 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1956 {
1957 return error(GL_INVALID_ENUM);
1958 }
John Bauman66b8ab22014-05-06 15:57:45 -04001959
Nicolas Capensf160b172014-11-26 11:58:23 -05001960 switch(attachment)
1961 {
1962 case GL_COLOR_ATTACHMENT0:
1963 case GL_DEPTH_ATTACHMENT:
1964 case GL_STENCIL_ATTACHMENT:
1965 break;
1966 default:
1967 return error(GL_INVALID_ENUM);
1968 }
John Bauman66b8ab22014-05-06 15:57:45 -04001969
Nicolas Capensf160b172014-11-26 11:58:23 -05001970 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001971
Nicolas Capensf160b172014-11-26 11:58:23 -05001972 if(context)
1973 {
1974 if(texture == 0)
1975 {
1976 textarget = GL_NONE;
1977 }
1978 else
1979 {
1980 es2::Texture *tex = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -04001981
Nicolas Capensf160b172014-11-26 11:58:23 -05001982 if(tex == NULL)
1983 {
1984 return error(GL_INVALID_OPERATION);
1985 }
John Bauman66b8ab22014-05-06 15:57:45 -04001986
Nicolas Capensf160b172014-11-26 11:58:23 -05001987 if(tex->isCompressed(textarget, level))
1988 {
1989 return error(GL_INVALID_OPERATION);
1990 }
John Bauman66b8ab22014-05-06 15:57:45 -04001991
Nicolas Capensf160b172014-11-26 11:58:23 -05001992 switch(textarget)
1993 {
1994 case GL_TEXTURE_2D:
1995 if(tex->getTarget() != GL_TEXTURE_2D)
1996 {
1997 return error(GL_INVALID_OPERATION);
1998 }
1999 break;
2000 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2001 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2002 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2003 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2004 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2005 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2006 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2007 {
2008 return error(GL_INVALID_OPERATION);
2009 }
2010 break;
2011 default:
2012 return error(GL_INVALID_ENUM);
2013 }
John Bauman66b8ab22014-05-06 15:57:45 -04002014
Nicolas Capensf160b172014-11-26 11:58:23 -05002015 if(level != 0)
2016 {
2017 return error(GL_INVALID_VALUE);
2018 }
2019 }
John Bauman66b8ab22014-05-06 15:57:45 -04002020
Nicolas Capensf160b172014-11-26 11:58:23 -05002021 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002022 GLuint framebufferName = 0;
Nicolas Capensf160b172014-11-26 11:58:23 -05002023 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2024 {
2025 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002026 framebufferName = context->getReadFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002027 }
2028 else
2029 {
2030 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002031 framebufferName = context->getDrawFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002032 }
John Bauman66b8ab22014-05-06 15:57:45 -04002033
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002034 if(framebufferName == 0 || !framebuffer)
Nicolas Capensf160b172014-11-26 11:58:23 -05002035 {
2036 return error(GL_INVALID_OPERATION);
2037 }
John Bauman66b8ab22014-05-06 15:57:45 -04002038
Nicolas Capensf160b172014-11-26 11:58:23 -05002039 switch(attachment)
2040 {
2041 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2042 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2043 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2044 }
2045 }
John Bauman66b8ab22014-05-06 15:57:45 -04002046}
2047
2048void GL_APIENTRY glFrontFace(GLenum mode)
2049{
Nicolas Capensf160b172014-11-26 11:58:23 -05002050 TRACE("(GLenum mode = 0x%X)", mode);
John Bauman66b8ab22014-05-06 15:57:45 -04002051
Nicolas Capensf160b172014-11-26 11:58:23 -05002052 switch(mode)
2053 {
2054 case GL_CW:
2055 case GL_CCW:
2056 {
2057 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002058
Nicolas Capensf160b172014-11-26 11:58:23 -05002059 if(context)
2060 {
2061 context->setFrontFace(mode);
2062 }
2063 }
2064 break;
2065 default:
2066 return error(GL_INVALID_ENUM);
2067 }
John Bauman66b8ab22014-05-06 15:57:45 -04002068}
2069
2070void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
2071{
Nicolas Capensf160b172014-11-26 11:58:23 -05002072 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002073
Nicolas Capensf160b172014-11-26 11:58:23 -05002074 if(n < 0)
2075 {
2076 return error(GL_INVALID_VALUE);
2077 }
John Bauman66b8ab22014-05-06 15:57:45 -04002078
Nicolas Capensf160b172014-11-26 11:58:23 -05002079 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002080
Nicolas Capensf160b172014-11-26 11:58:23 -05002081 if(context)
2082 {
2083 for(int i = 0; i < n; i++)
2084 {
2085 buffers[i] = context->createBuffer();
2086 }
2087 }
John Bauman66b8ab22014-05-06 15:57:45 -04002088}
2089
2090void GL_APIENTRY glGenerateMipmap(GLenum target)
2091{
Nicolas Capensf160b172014-11-26 11:58:23 -05002092 TRACE("(GLenum target = 0x%X)", target);
John Bauman66b8ab22014-05-06 15:57:45 -04002093
Nicolas Capensf160b172014-11-26 11:58:23 -05002094 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002095
Nicolas Capensf160b172014-11-26 11:58:23 -05002096 if(context)
2097 {
Alexis Hetued306182015-04-02 12:02:28 -04002098 es2::Texture *texture = nullptr;
2099
2100 egl::GLint clientVersion = context->getClientVersion();
John Bauman66b8ab22014-05-06 15:57:45 -04002101
Nicolas Capensf160b172014-11-26 11:58:23 -05002102 switch(target)
2103 {
2104 case GL_TEXTURE_2D:
2105 texture = context->getTexture2D();
2106 break;
2107 case GL_TEXTURE_CUBE_MAP:
2108 texture = context->getTextureCubeMap();
2109 break;
Alexis Hetued306182015-04-02 12:02:28 -04002110 case GL_TEXTURE_2D_ARRAY:
2111 if(clientVersion < 3)
2112 {
2113 return error(GL_INVALID_ENUM);
2114 }
2115 else
2116 {
2117 UNIMPLEMENTED();
2118 texture = context->getTexture3D();
2119 break;
2120 }
2121 case GL_TEXTURE_3D_OES:
2122 texture = context->getTexture3D();
2123 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05002124 default:
2125 return error(GL_INVALID_ENUM);
2126 }
John Bauman66b8ab22014-05-06 15:57:45 -04002127
Nicolas Capensf160b172014-11-26 11:58:23 -05002128 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2129 {
2130 return error(GL_INVALID_OPERATION);
2131 }
John Bauman66b8ab22014-05-06 15:57:45 -04002132
Nicolas Capensf160b172014-11-26 11:58:23 -05002133 texture->generateMipmaps();
2134 }
John Bauman66b8ab22014-05-06 15:57:45 -04002135}
2136
2137void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
2138{
Nicolas Capensf160b172014-11-26 11:58:23 -05002139 TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
John Bauman66b8ab22014-05-06 15:57:45 -04002140
Nicolas Capensf160b172014-11-26 11:58:23 -05002141 if(n < 0)
2142 {
2143 return error(GL_INVALID_VALUE);
2144 }
John Bauman66b8ab22014-05-06 15:57:45 -04002145
Nicolas Capensf160b172014-11-26 11:58:23 -05002146 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002147
Nicolas Capensf160b172014-11-26 11:58:23 -05002148 if(context)
2149 {
2150 for(int i = 0; i < n; i++)
2151 {
2152 fences[i] = context->createFence();
2153 }
2154 }
John Bauman66b8ab22014-05-06 15:57:45 -04002155}
2156
2157void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2158{
Nicolas Capensf160b172014-11-26 11:58:23 -05002159 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002160
Nicolas Capensf160b172014-11-26 11:58:23 -05002161 if(n < 0)
2162 {
2163 return error(GL_INVALID_VALUE);
2164 }
John Bauman66b8ab22014-05-06 15:57:45 -04002165
Nicolas Capensf160b172014-11-26 11:58:23 -05002166 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002167
Nicolas Capensf160b172014-11-26 11:58:23 -05002168 if(context)
2169 {
2170 for(int i = 0; i < n; i++)
2171 {
2172 framebuffers[i] = context->createFramebuffer();
2173 }
2174 }
John Bauman66b8ab22014-05-06 15:57:45 -04002175}
2176
2177void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
2178{
Nicolas Capensf160b172014-11-26 11:58:23 -05002179 TRACE("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
John Bauman66b8ab22014-05-06 15:57:45 -04002180
Nicolas Capensf160b172014-11-26 11:58:23 -05002181 if(n < 0)
2182 {
2183 return error(GL_INVALID_VALUE);
2184 }
John Bauman66b8ab22014-05-06 15:57:45 -04002185
Nicolas Capensf160b172014-11-26 11:58:23 -05002186 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002187
Nicolas Capensf160b172014-11-26 11:58:23 -05002188 if(context)
2189 {
2190 for(int i = 0; i < n; i++)
2191 {
2192 ids[i] = context->createQuery();
2193 }
2194 }
John Bauman66b8ab22014-05-06 15:57:45 -04002195}
2196
2197void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2198{
Nicolas Capensf160b172014-11-26 11:58:23 -05002199 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002200
Nicolas Capensf160b172014-11-26 11:58:23 -05002201 if(n < 0)
2202 {
2203 return error(GL_INVALID_VALUE);
2204 }
John Bauman66b8ab22014-05-06 15:57:45 -04002205
Nicolas Capensf160b172014-11-26 11:58:23 -05002206 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002207
Nicolas Capensf160b172014-11-26 11:58:23 -05002208 if(context)
2209 {
2210 for(int i = 0; i < n; i++)
2211 {
2212 renderbuffers[i] = context->createRenderbuffer();
2213 }
2214 }
John Bauman66b8ab22014-05-06 15:57:45 -04002215}
2216
2217void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
2218{
Nicolas Capensf160b172014-11-26 11:58:23 -05002219 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
John Bauman66b8ab22014-05-06 15:57:45 -04002220
Nicolas Capensf160b172014-11-26 11:58:23 -05002221 if(n < 0)
2222 {
2223 return error(GL_INVALID_VALUE);
2224 }
John Bauman66b8ab22014-05-06 15:57:45 -04002225
Nicolas Capensf160b172014-11-26 11:58:23 -05002226 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002227
Nicolas Capensf160b172014-11-26 11:58:23 -05002228 if(context)
2229 {
2230 for(int i = 0; i < n; i++)
2231 {
2232 textures[i] = context->createTexture();
2233 }
2234 }
John Bauman66b8ab22014-05-06 15:57:45 -04002235}
2236
2237void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
2238{
Nicolas Capensf160b172014-11-26 11:58:23 -05002239 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2240 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
2241 program, index, bufsize, length, size, type, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002242
Nicolas Capensf160b172014-11-26 11:58:23 -05002243 if(bufsize < 0)
2244 {
2245 return error(GL_INVALID_VALUE);
2246 }
John Bauman66b8ab22014-05-06 15:57:45 -04002247
Nicolas Capensf160b172014-11-26 11:58:23 -05002248 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002249
Nicolas Capensf160b172014-11-26 11:58:23 -05002250 if(context)
2251 {
2252 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002253
Nicolas Capensf160b172014-11-26 11:58:23 -05002254 if(!programObject)
2255 {
2256 if(context->getShader(program))
2257 {
2258 return error(GL_INVALID_OPERATION);
2259 }
2260 else
2261 {
2262 return error(GL_INVALID_VALUE);
2263 }
2264 }
John Bauman66b8ab22014-05-06 15:57:45 -04002265
Nicolas Capensf160b172014-11-26 11:58:23 -05002266 if(index >= (GLuint)programObject->getActiveAttributeCount())
2267 {
2268 return error(GL_INVALID_VALUE);
2269 }
John Bauman66b8ab22014-05-06 15:57:45 -04002270
Nicolas Capensf160b172014-11-26 11:58:23 -05002271 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2272 }
John Bauman66b8ab22014-05-06 15:57:45 -04002273}
2274
2275void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
2276{
Nicolas Capensf160b172014-11-26 11:58:23 -05002277 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
2278 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = %s)",
2279 program, index, bufsize, length, size, type, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002280
Nicolas Capensf160b172014-11-26 11:58:23 -05002281 if(bufsize < 0)
2282 {
2283 return error(GL_INVALID_VALUE);
2284 }
John Bauman66b8ab22014-05-06 15:57:45 -04002285
Nicolas Capensf160b172014-11-26 11:58:23 -05002286 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002287
Nicolas Capensf160b172014-11-26 11:58:23 -05002288 if(context)
2289 {
2290 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002291
Nicolas Capensf160b172014-11-26 11:58:23 -05002292 if(!programObject)
2293 {
2294 if(context->getShader(program))
2295 {
2296 return error(GL_INVALID_OPERATION);
2297 }
2298 else
2299 {
2300 return error(GL_INVALID_VALUE);
2301 }
2302 }
John Bauman66b8ab22014-05-06 15:57:45 -04002303
Nicolas Capensf160b172014-11-26 11:58:23 -05002304 if(index >= (GLuint)programObject->getActiveUniformCount())
2305 {
2306 return error(GL_INVALID_VALUE);
2307 }
John Bauman66b8ab22014-05-06 15:57:45 -04002308
Nicolas Capensf160b172014-11-26 11:58:23 -05002309 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2310 }
John Bauman66b8ab22014-05-06 15:57:45 -04002311}
2312
2313void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2314{
Nicolas Capensf160b172014-11-26 11:58:23 -05002315 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2316 program, maxcount, count, shaders);
John Bauman66b8ab22014-05-06 15:57:45 -04002317
Nicolas Capensf160b172014-11-26 11:58:23 -05002318 if(maxcount < 0)
2319 {
2320 return error(GL_INVALID_VALUE);
2321 }
John Bauman66b8ab22014-05-06 15:57:45 -04002322
Nicolas Capensf160b172014-11-26 11:58:23 -05002323 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002324
Nicolas Capensf160b172014-11-26 11:58:23 -05002325 if(context)
2326 {
2327 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002328
Nicolas Capensf160b172014-11-26 11:58:23 -05002329 if(!programObject)
2330 {
2331 if(context->getShader(program))
2332 {
2333 return error(GL_INVALID_OPERATION);
2334 }
2335 else
2336 {
2337 return error(GL_INVALID_VALUE);
2338 }
2339 }
John Bauman66b8ab22014-05-06 15:57:45 -04002340
Nicolas Capensf160b172014-11-26 11:58:23 -05002341 return programObject->getAttachedShaders(maxcount, count, shaders);
2342 }
John Bauman66b8ab22014-05-06 15:57:45 -04002343}
2344
2345int GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
2346{
Nicolas Capensf160b172014-11-26 11:58:23 -05002347 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002348
Nicolas Capensf160b172014-11-26 11:58:23 -05002349 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002350
Nicolas Capensf160b172014-11-26 11:58:23 -05002351 if(context)
2352 {
John Bauman66b8ab22014-05-06 15:57:45 -04002353
Nicolas Capensf160b172014-11-26 11:58:23 -05002354 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002355
Nicolas Capensf160b172014-11-26 11:58:23 -05002356 if(!programObject)
2357 {
2358 if(context->getShader(program))
2359 {
2360 return error(GL_INVALID_OPERATION, -1);
2361 }
2362 else
2363 {
2364 return error(GL_INVALID_VALUE, -1);
2365 }
2366 }
John Bauman66b8ab22014-05-06 15:57:45 -04002367
Nicolas Capensf160b172014-11-26 11:58:23 -05002368 if(!programObject->isLinked())
2369 {
2370 return error(GL_INVALID_OPERATION, -1);
2371 }
John Bauman66b8ab22014-05-06 15:57:45 -04002372
Nicolas Capensf160b172014-11-26 11:58:23 -05002373 return programObject->getAttributeLocation(name);
2374 }
John Bauman66b8ab22014-05-06 15:57:45 -04002375
Nicolas Capensf160b172014-11-26 11:58:23 -05002376 return -1;
John Bauman66b8ab22014-05-06 15:57:45 -04002377}
2378
2379void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
2380{
Nicolas Capensf160b172014-11-26 11:58:23 -05002381 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002382
Nicolas Capensf160b172014-11-26 11:58:23 -05002383 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002384
Nicolas Capensf160b172014-11-26 11:58:23 -05002385 if(context)
2386 {
2387 if(!(context->getBooleanv(pname, params)))
2388 {
2389 GLenum nativeType;
2390 unsigned int numParams = 0;
2391 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2392 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002393
Nicolas Capensf160b172014-11-26 11:58:23 -05002394 if(numParams == 0)
2395 return; // it is known that the pname is valid, but there are no parameters to return
John Bauman66b8ab22014-05-06 15:57:45 -04002396
Nicolas Capensf160b172014-11-26 11:58:23 -05002397 if(nativeType == GL_FLOAT)
2398 {
2399 GLfloat *floatParams = NULL;
2400 floatParams = new GLfloat[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002401
Nicolas Capensf160b172014-11-26 11:58:23 -05002402 context->getFloatv(pname, floatParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002403
Nicolas Capensf160b172014-11-26 11:58:23 -05002404 for(unsigned int i = 0; i < numParams; ++i)
2405 {
2406 if(floatParams[i] == 0.0f)
2407 params[i] = GL_FALSE;
2408 else
2409 params[i] = GL_TRUE;
2410 }
John Bauman66b8ab22014-05-06 15:57:45 -04002411
Nicolas Capensf160b172014-11-26 11:58:23 -05002412 delete [] floatParams;
2413 }
2414 else if(nativeType == GL_INT)
2415 {
2416 GLint *intParams = NULL;
2417 intParams = new GLint[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002418
Nicolas Capensf160b172014-11-26 11:58:23 -05002419 context->getIntegerv(pname, intParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002420
Nicolas Capensf160b172014-11-26 11:58:23 -05002421 for(unsigned int i = 0; i < numParams; ++i)
2422 {
2423 if(intParams[i] == 0)
2424 params[i] = GL_FALSE;
2425 else
2426 params[i] = GL_TRUE;
2427 }
John Bauman66b8ab22014-05-06 15:57:45 -04002428
Nicolas Capensf160b172014-11-26 11:58:23 -05002429 delete [] intParams;
2430 }
2431 }
2432 }
John Bauman66b8ab22014-05-06 15:57:45 -04002433}
2434
2435void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2436{
Nicolas Capensf160b172014-11-26 11:58:23 -05002437 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002438
Nicolas Capensf160b172014-11-26 11:58:23 -05002439 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002440
Nicolas Capensf160b172014-11-26 11:58:23 -05002441 if(context)
2442 {
2443 es2::Buffer *buffer;
John Bauman66b8ab22014-05-06 15:57:45 -04002444
Nicolas Capensf160b172014-11-26 11:58:23 -05002445 switch(target)
2446 {
2447 case GL_ARRAY_BUFFER:
2448 buffer = context->getArrayBuffer();
2449 break;
2450 case GL_ELEMENT_ARRAY_BUFFER:
2451 buffer = context->getElementArrayBuffer();
2452 break;
2453 default:
2454 return error(GL_INVALID_ENUM);
2455 }
John Bauman66b8ab22014-05-06 15:57:45 -04002456
Nicolas Capensf160b172014-11-26 11:58:23 -05002457 if(!buffer)
2458 {
2459 // A null buffer means that "0" is bound to the requested buffer target
2460 return error(GL_INVALID_OPERATION);
2461 }
John Bauman66b8ab22014-05-06 15:57:45 -04002462
Alexis Hetued306182015-04-02 12:02:28 -04002463 egl::GLint clientVersion = context->getClientVersion();
2464
Nicolas Capensf160b172014-11-26 11:58:23 -05002465 switch(pname)
2466 {
2467 case GL_BUFFER_USAGE:
2468 *params = buffer->usage();
2469 break;
2470 case GL_BUFFER_SIZE:
2471 *params = buffer->size();
2472 break;
Alexis Hetued306182015-04-02 12:02:28 -04002473 case GL_BUFFER_ACCESS_FLAGS:
2474 if(clientVersion >= 3)
2475 {
2476 *params = buffer->access();
2477 break;
2478 }
2479 else return error(GL_INVALID_ENUM);
2480 case GL_BUFFER_MAPPED:
2481 if(clientVersion >= 3)
2482 {
2483 *params = buffer->isMapped();
2484 break;
2485 }
2486 else return error(GL_INVALID_ENUM);
2487 case GL_BUFFER_MAP_LENGTH:
2488 if(clientVersion >= 3)
2489 {
2490 *params = buffer->length();
2491 break;
2492 }
2493 else return error(GL_INVALID_ENUM);
2494 case GL_BUFFER_MAP_OFFSET:
2495 if(clientVersion >= 3)
2496 {
2497 *params = buffer->offset();
2498 break;
2499 }
2500 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05002501 default:
2502 return error(GL_INVALID_ENUM);
2503 }
2504 }
John Bauman66b8ab22014-05-06 15:57:45 -04002505}
2506
2507GLenum GL_APIENTRY glGetError(void)
2508{
Nicolas Capensf160b172014-11-26 11:58:23 -05002509 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002510
Nicolas Capensf160b172014-11-26 11:58:23 -05002511 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002512
Nicolas Capensf160b172014-11-26 11:58:23 -05002513 if(context)
2514 {
2515 return context->getError();
2516 }
John Bauman66b8ab22014-05-06 15:57:45 -04002517
Nicolas Capensf160b172014-11-26 11:58:23 -05002518 return GL_NO_ERROR;
John Bauman66b8ab22014-05-06 15:57:45 -04002519}
2520
2521void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2522{
Nicolas Capensf160b172014-11-26 11:58:23 -05002523 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002524
Nicolas Capensf160b172014-11-26 11:58:23 -05002525 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002526
Nicolas Capensf160b172014-11-26 11:58:23 -05002527 if(context)
2528 {
2529 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002530
Nicolas Capensf160b172014-11-26 11:58:23 -05002531 if(fenceObject == NULL)
2532 {
2533 return error(GL_INVALID_OPERATION);
2534 }
John Bauman66b8ab22014-05-06 15:57:45 -04002535
Nicolas Capensf160b172014-11-26 11:58:23 -05002536 fenceObject->getFenceiv(pname, params);
2537 }
John Bauman66b8ab22014-05-06 15:57:45 -04002538}
2539
2540void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
2541{
Nicolas Capensf160b172014-11-26 11:58:23 -05002542 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002543
Nicolas Capensf160b172014-11-26 11:58:23 -05002544 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002545
Nicolas Capensf160b172014-11-26 11:58:23 -05002546 if(context)
2547 {
2548 if(!(context->getFloatv(pname, params)))
2549 {
2550 GLenum nativeType;
2551 unsigned int numParams = 0;
2552 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2553 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002554
Nicolas Capensf160b172014-11-26 11:58:23 -05002555 if(numParams == 0)
2556 return; // it is known that the pname is valid, but that there are no parameters to return.
John Bauman66b8ab22014-05-06 15:57:45 -04002557
Nicolas Capensf160b172014-11-26 11:58:23 -05002558 if(nativeType == GL_BOOL)
2559 {
2560 GLboolean *boolParams = NULL;
2561 boolParams = new GLboolean[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002562
Nicolas Capensf160b172014-11-26 11:58:23 -05002563 context->getBooleanv(pname, boolParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002564
Nicolas Capensf160b172014-11-26 11:58:23 -05002565 for(unsigned int i = 0; i < numParams; ++i)
2566 {
2567 if(boolParams[i] == GL_FALSE)
2568 params[i] = 0.0f;
2569 else
2570 params[i] = 1.0f;
2571 }
John Bauman66b8ab22014-05-06 15:57:45 -04002572
Nicolas Capensf160b172014-11-26 11:58:23 -05002573 delete [] boolParams;
2574 }
2575 else if(nativeType == GL_INT)
2576 {
2577 GLint *intParams = NULL;
2578 intParams = new GLint[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002579
Nicolas Capensf160b172014-11-26 11:58:23 -05002580 context->getIntegerv(pname, intParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002581
Nicolas Capensf160b172014-11-26 11:58:23 -05002582 for(unsigned int i = 0; i < numParams; ++i)
2583 {
2584 params[i] = (GLfloat)intParams[i];
2585 }
John Bauman66b8ab22014-05-06 15:57:45 -04002586
Nicolas Capensf160b172014-11-26 11:58:23 -05002587 delete [] intParams;
2588 }
2589 }
2590 }
John Bauman66b8ab22014-05-06 15:57:45 -04002591}
2592
2593void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2594{
Nicolas Capensf160b172014-11-26 11:58:23 -05002595 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2596 target, attachment, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002597
Nicolas Capensf160b172014-11-26 11:58:23 -05002598 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002599
Nicolas Capensf160b172014-11-26 11:58:23 -05002600 if(context)
2601 {
2602 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2603 {
2604 return error(GL_INVALID_ENUM);
2605 }
John Bauman66b8ab22014-05-06 15:57:45 -04002606
Nicolas Capensf160b172014-11-26 11:58:23 -05002607 es2::Framebuffer *framebuffer = NULL;
2608 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2609 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002610 if(context->getReadFramebufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002611 {
2612 return error(GL_INVALID_OPERATION);
2613 }
John Bauman66b8ab22014-05-06 15:57:45 -04002614
Nicolas Capensf160b172014-11-26 11:58:23 -05002615 framebuffer = context->getReadFramebuffer();
2616 }
2617 else
2618 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002619 if(context->getDrawFramebufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002620 {
2621 return error(GL_INVALID_OPERATION);
2622 }
John Bauman66b8ab22014-05-06 15:57:45 -04002623
Nicolas Capensf160b172014-11-26 11:58:23 -05002624 framebuffer = context->getDrawFramebuffer();
2625 }
John Bauman66b8ab22014-05-06 15:57:45 -04002626
Nicolas Capensf160b172014-11-26 11:58:23 -05002627 GLenum attachmentType;
2628 GLuint attachmentHandle;
2629 switch(attachment)
2630 {
2631 case GL_COLOR_ATTACHMENT0:
2632 attachmentType = framebuffer->getColorbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002633 attachmentHandle = framebuffer->getColorbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002634 break;
2635 case GL_DEPTH_ATTACHMENT:
2636 attachmentType = framebuffer->getDepthbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002637 attachmentHandle = framebuffer->getDepthbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002638 break;
2639 case GL_STENCIL_ATTACHMENT:
2640 attachmentType = framebuffer->getStencilbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002641 attachmentHandle = framebuffer->getStencilbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002642 break;
2643 default:
2644 return error(GL_INVALID_ENUM);
2645 }
John Bauman66b8ab22014-05-06 15:57:45 -04002646
Nicolas Capensf160b172014-11-26 11:58:23 -05002647 GLenum attachmentObjectType; // Type category
2648 if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
2649 {
2650 attachmentObjectType = attachmentType;
2651 }
2652 else if(es2::IsTextureTarget(attachmentType))
2653 {
2654 attachmentObjectType = GL_TEXTURE;
2655 }
2656 else UNREACHABLE();
John Bauman66b8ab22014-05-06 15:57:45 -04002657
Nicolas Capensf160b172014-11-26 11:58:23 -05002658 switch(pname)
2659 {
2660 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2661 *params = attachmentObjectType;
2662 break;
2663 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2664 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2665 {
2666 *params = attachmentHandle;
2667 }
2668 else
2669 {
2670 return error(GL_INVALID_ENUM);
2671 }
2672 break;
2673 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2674 if(attachmentObjectType == GL_TEXTURE)
2675 {
2676 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2677 }
2678 else
2679 {
2680 return error(GL_INVALID_ENUM);
2681 }
2682 break;
2683 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2684 if(attachmentObjectType == GL_TEXTURE)
2685 {
2686 if(es2::IsCubemapTextureTarget(attachmentType))
2687 {
2688 *params = attachmentType;
2689 }
2690 else
2691 {
2692 *params = 0;
2693 }
2694 }
2695 else
2696 {
2697 return error(GL_INVALID_ENUM);
2698 }
2699 break;
2700 default:
2701 return error(GL_INVALID_ENUM);
2702 }
2703 }
John Bauman66b8ab22014-05-06 15:57:45 -04002704}
2705
2706GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void)
2707{
Nicolas Capensf160b172014-11-26 11:58:23 -05002708 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002709
Nicolas Capensf160b172014-11-26 11:58:23 -05002710 return GL_NO_ERROR;
John Bauman66b8ab22014-05-06 15:57:45 -04002711}
2712
2713void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)
2714{
Nicolas Capensf160b172014-11-26 11:58:23 -05002715 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002716
Nicolas Capensf160b172014-11-26 11:58:23 -05002717 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002718
Nicolas Capens7ae353d2015-03-13 17:59:58 -04002719 if(!context)
2720 {
2721 ERR("glGetIntegerv() called without current context."); // Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
2722
2723 // This is not spec compliant! When there is no current GL context, functions should
2724 // have no side effects. Google Maps queries these values before creating a context,
2725 // so we need this as a bug-compatible workaround.
2726 switch(pname)
2727 {
2728 case GL_MAX_TEXTURE_SIZE: *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE; return;
2729 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS; return;
2730 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
2731 case GL_STENCIL_BITS: *params = 8; return;
2732 case GL_ALIASED_LINE_WIDTH_RANGE:
2733 params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
2734 params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
2735 return;
2736 }
2737 }
2738
Nicolas Capensf160b172014-11-26 11:58:23 -05002739 if(context)
2740 {
2741 if(!(context->getIntegerv(pname, params)))
2742 {
2743 GLenum nativeType;
2744 unsigned int numParams = 0;
2745 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2746 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002747
Nicolas Capensf160b172014-11-26 11:58:23 -05002748 if(numParams == 0)
2749 return; // it is known that pname is valid, but there are no parameters to return
John Bauman66b8ab22014-05-06 15:57:45 -04002750
Nicolas Capensf160b172014-11-26 11:58:23 -05002751 if(nativeType == GL_BOOL)
2752 {
2753 GLboolean *boolParams = NULL;
2754 boolParams = new GLboolean[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002755
Nicolas Capensf160b172014-11-26 11:58:23 -05002756 context->getBooleanv(pname, boolParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002757
Nicolas Capensf160b172014-11-26 11:58:23 -05002758 for(unsigned int i = 0; i < numParams; ++i)
2759 {
Alexis Hetued306182015-04-02 12:02:28 -04002760 params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
Nicolas Capensf160b172014-11-26 11:58:23 -05002761 }
John Bauman66b8ab22014-05-06 15:57:45 -04002762
Nicolas Capensf160b172014-11-26 11:58:23 -05002763 delete [] boolParams;
2764 }
2765 else if(nativeType == GL_FLOAT)
2766 {
2767 GLfloat *floatParams = NULL;
2768 floatParams = new GLfloat[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002769
Nicolas Capensf160b172014-11-26 11:58:23 -05002770 context->getFloatv(pname, floatParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002771
Nicolas Capensf160b172014-11-26 11:58:23 -05002772 for(unsigned int i = 0; i < numParams; ++i)
2773 {
2774 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
2775 {
Alexis Hetued306182015-04-02 12:02:28 -04002776 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) * 0.5f);
Nicolas Capensf160b172014-11-26 11:58:23 -05002777 }
2778 else
2779 {
2780 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
2781 }
2782 }
John Bauman66b8ab22014-05-06 15:57:45 -04002783
Nicolas Capensf160b172014-11-26 11:58:23 -05002784 delete [] floatParams;
2785 }
2786 }
2787 }
John Bauman66b8ab22014-05-06 15:57:45 -04002788}
2789
2790void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2791{
Nicolas Capensf160b172014-11-26 11:58:23 -05002792 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", program, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002793
Nicolas Capensf160b172014-11-26 11:58:23 -05002794 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002795
Nicolas Capensf160b172014-11-26 11:58:23 -05002796 if(context)
2797 {
2798 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002799
Nicolas Capensf160b172014-11-26 11:58:23 -05002800 if(!programObject)
2801 {
2802 return error(GL_INVALID_VALUE);
2803 }
John Bauman66b8ab22014-05-06 15:57:45 -04002804
Nicolas Capensf160b172014-11-26 11:58:23 -05002805 switch(pname)
2806 {
2807 case GL_DELETE_STATUS:
2808 *params = programObject->isFlaggedForDeletion();
2809 return;
2810 case GL_LINK_STATUS:
2811 *params = programObject->isLinked();
2812 return;
2813 case GL_VALIDATE_STATUS:
2814 *params = programObject->isValidated();
2815 return;
2816 case GL_INFO_LOG_LENGTH:
2817 *params = programObject->getInfoLogLength();
2818 return;
2819 case GL_ATTACHED_SHADERS:
2820 *params = programObject->getAttachedShadersCount();
2821 return;
2822 case GL_ACTIVE_ATTRIBUTES:
2823 *params = programObject->getActiveAttributeCount();
2824 return;
2825 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2826 *params = programObject->getActiveAttributeMaxLength();
2827 return;
2828 case GL_ACTIVE_UNIFORMS:
2829 *params = programObject->getActiveUniformCount();
2830 return;
2831 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2832 *params = programObject->getActiveUniformMaxLength();
2833 return;
2834 default:
2835 return error(GL_INVALID_ENUM);
2836 }
2837 }
John Bauman66b8ab22014-05-06 15:57:45 -04002838}
2839
2840void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
2841{
Nicolas Capensf160b172014-11-26 11:58:23 -05002842 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
2843 program, bufsize, length, infolog);
John Bauman66b8ab22014-05-06 15:57:45 -04002844
Nicolas Capensf160b172014-11-26 11:58:23 -05002845 if(bufsize < 0)
2846 {
2847 return error(GL_INVALID_VALUE);
2848 }
John Bauman66b8ab22014-05-06 15:57:45 -04002849
Nicolas Capensf160b172014-11-26 11:58:23 -05002850 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002851
Nicolas Capensf160b172014-11-26 11:58:23 -05002852 if(context)
2853 {
2854 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002855
Nicolas Capensf160b172014-11-26 11:58:23 -05002856 if(!programObject)
2857 {
2858 return error(GL_INVALID_VALUE);
2859 }
John Bauman66b8ab22014-05-06 15:57:45 -04002860
Nicolas Capensf160b172014-11-26 11:58:23 -05002861 programObject->getInfoLog(bufsize, length, infolog);
2862 }
John Bauman66b8ab22014-05-06 15:57:45 -04002863}
2864
2865void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
2866{
Nicolas Capensf160b172014-11-26 11:58:23 -05002867 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002868
Nicolas Capensf160b172014-11-26 11:58:23 -05002869 switch(pname)
2870 {
2871 case GL_CURRENT_QUERY_EXT:
2872 break;
2873 default:
2874 return error(GL_INVALID_ENUM);
2875 }
John Bauman66b8ab22014-05-06 15:57:45 -04002876
Nicolas Capensf160b172014-11-26 11:58:23 -05002877 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002878
Nicolas Capensf160b172014-11-26 11:58:23 -05002879 if(context)
2880 {
2881 params[0] = context->getActiveQuery(target);
2882 }
John Bauman66b8ab22014-05-06 15:57:45 -04002883}
2884
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002885void GL_APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
John Bauman66b8ab22014-05-06 15:57:45 -04002886{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002887 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", name, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002888
Nicolas Capensf160b172014-11-26 11:58:23 -05002889 switch(pname)
2890 {
2891 case GL_QUERY_RESULT_EXT:
2892 case GL_QUERY_RESULT_AVAILABLE_EXT:
2893 break;
2894 default:
2895 return error(GL_INVALID_ENUM);
2896 }
John Bauman66b8ab22014-05-06 15:57:45 -04002897
Nicolas Capensf160b172014-11-26 11:58:23 -05002898 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002899
Nicolas Capensf160b172014-11-26 11:58:23 -05002900 if(context)
2901 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002902 es2::Query *queryObject = context->getQuery(name, false, GL_NONE);
John Bauman66b8ab22014-05-06 15:57:45 -04002903
Nicolas Capensf160b172014-11-26 11:58:23 -05002904 if(!queryObject)
2905 {
2906 return error(GL_INVALID_OPERATION);
2907 }
John Bauman66b8ab22014-05-06 15:57:45 -04002908
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002909 if(context->getActiveQuery(queryObject->getType()) == name)
Nicolas Capensf160b172014-11-26 11:58:23 -05002910 {
2911 return error(GL_INVALID_OPERATION);
2912 }
John Bauman66b8ab22014-05-06 15:57:45 -04002913
Nicolas Capensf160b172014-11-26 11:58:23 -05002914 switch(pname)
2915 {
2916 case GL_QUERY_RESULT_EXT:
2917 params[0] = queryObject->getResult();
2918 break;
2919 case GL_QUERY_RESULT_AVAILABLE_EXT:
2920 params[0] = queryObject->isResultAvailable();
2921 break;
2922 default:
2923 ASSERT(false);
2924 }
2925 }
John Bauman66b8ab22014-05-06 15:57:45 -04002926}
2927
2928void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2929{
Nicolas Capensf160b172014-11-26 11:58:23 -05002930 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002931
Nicolas Capensf160b172014-11-26 11:58:23 -05002932 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002933
Nicolas Capensf160b172014-11-26 11:58:23 -05002934 if(context)
2935 {
2936 if(target != GL_RENDERBUFFER)
2937 {
2938 return error(GL_INVALID_ENUM);
2939 }
John Bauman66b8ab22014-05-06 15:57:45 -04002940
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002941 if(context->getRenderbufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002942 {
2943 return error(GL_INVALID_OPERATION);
2944 }
John Bauman66b8ab22014-05-06 15:57:45 -04002945
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002946 es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
John Bauman66b8ab22014-05-06 15:57:45 -04002947
Nicolas Capensf160b172014-11-26 11:58:23 -05002948 switch(pname)
2949 {
2950 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
2951 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
2952 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
2953 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
2954 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
2955 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
2956 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
2957 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
2958 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
2959 case GL_RENDERBUFFER_SAMPLES_ANGLE: *params = renderbuffer->getSamples(); break;
2960 default:
2961 return error(GL_INVALID_ENUM);
2962 }
2963 }
John Bauman66b8ab22014-05-06 15:57:45 -04002964}
2965
2966void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2967{
Nicolas Capensf160b172014-11-26 11:58:23 -05002968 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002969
Nicolas Capensf160b172014-11-26 11:58:23 -05002970 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002971
Nicolas Capensf160b172014-11-26 11:58:23 -05002972 if(context)
2973 {
2974 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04002975
Nicolas Capensf160b172014-11-26 11:58:23 -05002976 if(!shaderObject)
2977 {
2978 return error(GL_INVALID_VALUE);
2979 }
John Bauman66b8ab22014-05-06 15:57:45 -04002980
Nicolas Capensf160b172014-11-26 11:58:23 -05002981 switch(pname)
2982 {
2983 case GL_SHADER_TYPE:
2984 *params = shaderObject->getType();
2985 return;
2986 case GL_DELETE_STATUS:
2987 *params = shaderObject->isFlaggedForDeletion();
2988 return;
2989 case GL_COMPILE_STATUS:
2990 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2991 return;
2992 case GL_INFO_LOG_LENGTH:
2993 *params = shaderObject->getInfoLogLength();
2994 return;
2995 case GL_SHADER_SOURCE_LENGTH:
2996 *params = shaderObject->getSourceLength();
2997 return;
2998 default:
2999 return error(GL_INVALID_ENUM);
3000 }
3001 }
John Bauman66b8ab22014-05-06 15:57:45 -04003002}
3003
3004void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3005{
Nicolas Capensf160b172014-11-26 11:58:23 -05003006 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
3007 shader, bufsize, length, infolog);
John Bauman66b8ab22014-05-06 15:57:45 -04003008
Nicolas Capensf160b172014-11-26 11:58:23 -05003009 if(bufsize < 0)
3010 {
3011 return error(GL_INVALID_VALUE);
3012 }
John Bauman66b8ab22014-05-06 15:57:45 -04003013
Nicolas Capensf160b172014-11-26 11:58:23 -05003014 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003015
Nicolas Capensf160b172014-11-26 11:58:23 -05003016 if(context)
3017 {
3018 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003019
Nicolas Capensf160b172014-11-26 11:58:23 -05003020 if(!shaderObject)
3021 {
3022 return error(GL_INVALID_VALUE);
3023 }
John Bauman66b8ab22014-05-06 15:57:45 -04003024
Nicolas Capensf160b172014-11-26 11:58:23 -05003025 shaderObject->getInfoLog(bufsize, length, infolog);
3026 }
John Bauman66b8ab22014-05-06 15:57:45 -04003027}
3028
3029void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3030{
Nicolas Capensf160b172014-11-26 11:58:23 -05003031 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
3032 shadertype, precisiontype, range, precision);
John Bauman66b8ab22014-05-06 15:57:45 -04003033
Nicolas Capensf160b172014-11-26 11:58:23 -05003034 switch(shadertype)
3035 {
3036 case GL_VERTEX_SHADER:
3037 case GL_FRAGMENT_SHADER:
3038 break;
3039 default:
3040 return error(GL_INVALID_ENUM);
3041 }
John Bauman66b8ab22014-05-06 15:57:45 -04003042
Nicolas Capensf160b172014-11-26 11:58:23 -05003043 switch(precisiontype)
3044 {
3045 case GL_LOW_FLOAT:
3046 case GL_MEDIUM_FLOAT:
3047 case GL_HIGH_FLOAT:
3048 // IEEE 754 single-precision
3049 range[0] = 127;
3050 range[1] = 127;
3051 *precision = 23;
3052 break;
3053 case GL_LOW_INT:
3054 case GL_MEDIUM_INT:
3055 case GL_HIGH_INT:
3056 // Single-precision floating-point numbers can accurately represent integers up to +/-16777216
3057 range[0] = 24;
3058 range[1] = 24;
3059 *precision = 0;
3060 break;
3061 default:
3062 return error(GL_INVALID_ENUM);
3063 }
John Bauman66b8ab22014-05-06 15:57:45 -04003064}
3065
3066void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3067{
Nicolas Capensf160b172014-11-26 11:58:23 -05003068 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3069 shader, bufsize, length, source);
John Bauman66b8ab22014-05-06 15:57:45 -04003070
Nicolas Capensf160b172014-11-26 11:58:23 -05003071 if(bufsize < 0)
3072 {
3073 return error(GL_INVALID_VALUE);
3074 }
John Bauman66b8ab22014-05-06 15:57:45 -04003075
Nicolas Capensf160b172014-11-26 11:58:23 -05003076 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003077
Nicolas Capensf160b172014-11-26 11:58:23 -05003078 if(context)
3079 {
3080 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003081
Nicolas Capensf160b172014-11-26 11:58:23 -05003082 if(!shaderObject)
3083 {
3084 return error(GL_INVALID_OPERATION);
3085 }
John Bauman66b8ab22014-05-06 15:57:45 -04003086
Nicolas Capensf160b172014-11-26 11:58:23 -05003087 shaderObject->getSource(bufsize, length, source);
3088 }
John Bauman66b8ab22014-05-06 15:57:45 -04003089}
3090
3091const GLubyte* GL_APIENTRY glGetString(GLenum name)
3092{
Nicolas Capensf160b172014-11-26 11:58:23 -05003093 TRACE("(GLenum name = 0x%X)", name);
John Bauman66b8ab22014-05-06 15:57:45 -04003094
Nicolas Capensf160b172014-11-26 11:58:23 -05003095 switch(name)
3096 {
3097 case GL_VENDOR:
3098 return (GLubyte*)"TransGaming Inc.";
3099 case GL_RENDERER:
3100 return (GLubyte*)"SwiftShader";
3101 case GL_VERSION:
3102 return (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
3103 case GL_SHADING_LANGUAGE_VERSION:
3104 return (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
3105 case GL_EXTENSIONS:
3106 // Keep list sorted in following order:
3107 // OES extensions
3108 // EXT extensions
3109 // Vendor extensions
3110 return (GLubyte*)
Nicolas Capens22658242014-11-29 00:31:41 -05003111 "GL_OES_compressed_ETC1_RGB8_texture "
Nicolas Capensf160b172014-11-26 11:58:23 -05003112 "GL_OES_depth_texture "
3113 "GL_OES_depth_texture_cube_map "
3114 "GL_OES_EGL_image "
3115 "GL_OES_EGL_image_external "
3116 "GL_OES_element_index_uint "
3117 "GL_OES_packed_depth_stencil "
3118 "GL_OES_rgb8_rgba8 "
3119 "GL_OES_standard_derivatives "
3120 "GL_OES_texture_float "
3121 "GL_OES_texture_float_linear "
3122 "GL_OES_texture_half_float "
3123 "GL_OES_texture_half_float_linear "
3124 "GL_OES_texture_npot "
Alexis Hetub027aa92015-01-19 15:56:12 -05003125 "GL_OES_texture_3D "
Nicolas Capensf160b172014-11-26 11:58:23 -05003126 "GL_EXT_blend_minmax "
3127 "GL_EXT_occlusion_query_boolean "
3128 "GL_EXT_read_format_bgra "
Nicolas Capens22658242014-11-29 00:31:41 -05003129 #if (S3TC_SUPPORT)
Nicolas Capensf160b172014-11-26 11:58:23 -05003130 "GL_EXT_texture_compression_dxt1 "
Nicolas Capens22658242014-11-29 00:31:41 -05003131 #endif
Nicolas Capensf160b172014-11-26 11:58:23 -05003132 "GL_EXT_texture_filter_anisotropic "
3133 "GL_EXT_texture_format_BGRA8888 "
3134 "GL_ANGLE_framebuffer_blit "
Alexis Hetue9233fb2015-02-11 10:31:58 -05003135 "GL_NV_framebuffer_blit "
Nicolas Capensf160b172014-11-26 11:58:23 -05003136 "GL_ANGLE_framebuffer_multisample "
Nicolas Capens22658242014-11-29 00:31:41 -05003137 #if (S3TC_SUPPORT)
3138 "GL_ANGLE_texture_compression_dxt3 "
3139 "GL_ANGLE_texture_compression_dxt5 "
3140 #endif
Nicolas Capensf160b172014-11-26 11:58:23 -05003141 "GL_NV_fence";
3142 default:
3143 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3144 }
John Bauman66b8ab22014-05-06 15:57:45 -04003145}
3146
3147void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3148{
Nicolas Capensf160b172014-11-26 11:58:23 -05003149 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003150
Nicolas Capensf160b172014-11-26 11:58:23 -05003151 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003152
Nicolas Capensf160b172014-11-26 11:58:23 -05003153 if(context)
3154 {
3155 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04003156
Alexis Hetued306182015-04-02 12:02:28 -04003157 egl::GLint clientVersion = context->getClientVersion();
3158
Nicolas Capensf160b172014-11-26 11:58:23 -05003159 switch(target)
3160 {
3161 case GL_TEXTURE_2D:
3162 texture = context->getTexture2D();
3163 break;
3164 case GL_TEXTURE_CUBE_MAP:
3165 texture = context->getTextureCubeMap();
3166 break;
3167 case GL_TEXTURE_EXTERNAL_OES:
3168 texture = context->getTextureExternal();
3169 break;
Alexis Hetued306182015-04-02 12:02:28 -04003170 case GL_TEXTURE_2D_ARRAY:
3171 if(clientVersion < 3)
3172 {
3173 return error(GL_INVALID_ENUM);
3174 }
3175 else
3176 {
3177 UNIMPLEMENTED();
3178 texture = context->getTexture3D();
3179 break;
3180 }
3181 case GL_TEXTURE_3D_OES:
3182 texture = context->getTexture3D();
3183 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003184 default:
3185 return error(GL_INVALID_ENUM);
3186 }
John Bauman66b8ab22014-05-06 15:57:45 -04003187
Nicolas Capensf160b172014-11-26 11:58:23 -05003188 switch(pname)
3189 {
3190 case GL_TEXTURE_MAG_FILTER:
3191 *params = (GLfloat)texture->getMagFilter();
3192 break;
3193 case GL_TEXTURE_MIN_FILTER:
3194 *params = (GLfloat)texture->getMinFilter();
3195 break;
3196 case GL_TEXTURE_WRAP_S:
3197 *params = (GLfloat)texture->getWrapS();
3198 break;
3199 case GL_TEXTURE_WRAP_T:
3200 *params = (GLfloat)texture->getWrapT();
3201 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05003202 case GL_TEXTURE_WRAP_R_OES:
3203 *params = (GLfloat)texture->getWrapR();
3204 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003205 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3206 *params = texture->getMaxAnisotropy();
3207 break;
3208 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3209 *params = (GLfloat)1;
3210 break;
Alexis Hetued306182015-04-02 12:02:28 -04003211 case GL_TEXTURE_BASE_LEVEL:
3212 if(clientVersion >= 3)
3213 {
3214 *params = (GLfloat)texture->getBaseLevel();
3215 break;
3216 }
3217 else return error(GL_INVALID_ENUM);
3218 case GL_TEXTURE_COMPARE_FUNC:
3219 if(clientVersion >= 3)
3220 {
3221 *params = (GLfloat)texture->getCompareFunc();
3222 break;
3223 }
3224 else return error(GL_INVALID_ENUM);
3225 case GL_TEXTURE_COMPARE_MODE:
3226 if(clientVersion >= 3)
3227 {
3228 *params = (GLfloat)texture->getCompareMode();
3229 break;
3230 }
3231 else return error(GL_INVALID_ENUM);
3232 case GL_TEXTURE_IMMUTABLE_FORMAT:
3233 if(clientVersion >= 3)
3234 {
3235 *params = (GLfloat)texture->getImmutableFormat();
3236 break;
3237 }
3238 else return error(GL_INVALID_ENUM);
3239 case GL_TEXTURE_MAX_LEVEL:
3240 if(clientVersion >= 3)
3241 {
3242 *params = (GLfloat)texture->getMaxLevel();
3243 break;
3244 }
3245 else return error(GL_INVALID_ENUM);
3246 case GL_TEXTURE_MAX_LOD:
3247 if(clientVersion >= 3)
3248 {
3249 *params = texture->getMaxLOD();
3250 break;
3251 }
3252 else return error(GL_INVALID_ENUM);
3253 case GL_TEXTURE_MIN_LOD:
3254 if(clientVersion >= 3)
3255 {
3256 *params = texture->getMinLOD();
3257 break;
3258 }
3259 else return error(GL_INVALID_ENUM);
3260 case GL_TEXTURE_SWIZZLE_R:
3261 if(clientVersion >= 3)
3262 {
3263 *params = (GLfloat)texture->getSwizzleR();
3264 break;
3265 }
3266 else return error(GL_INVALID_ENUM);
3267 case GL_TEXTURE_SWIZZLE_G:
3268 if(clientVersion >= 3)
3269 {
3270 *params = (GLfloat)texture->getSwizzleG();
3271 break;
3272 }
3273 else return error(GL_INVALID_ENUM);
3274 case GL_TEXTURE_SWIZZLE_B:
3275 if(clientVersion >= 3)
3276 {
3277 *params = (GLfloat)texture->getSwizzleB();
3278 break;
3279 }
3280 else return error(GL_INVALID_ENUM);
3281 case GL_TEXTURE_SWIZZLE_A:
3282 if(clientVersion >= 3)
3283 {
3284 *params = (GLfloat)texture->getSwizzleA();
3285 break;
3286 }
3287 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003288 default:
3289 return error(GL_INVALID_ENUM);
3290 }
3291 }
John Bauman66b8ab22014-05-06 15:57:45 -04003292}
3293
3294void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3295{
Nicolas Capensf160b172014-11-26 11:58:23 -05003296 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003297
Nicolas Capensf160b172014-11-26 11:58:23 -05003298 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003299
Nicolas Capensf160b172014-11-26 11:58:23 -05003300 if(context)
3301 {
3302 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04003303
Alexis Hetued306182015-04-02 12:02:28 -04003304 egl::GLint clientVersion = context->getClientVersion();
3305
Nicolas Capensf160b172014-11-26 11:58:23 -05003306 switch(target)
3307 {
3308 case GL_TEXTURE_2D:
3309 texture = context->getTexture2D();
3310 break;
3311 case GL_TEXTURE_CUBE_MAP:
3312 texture = context->getTextureCubeMap();
3313 break;
3314 case GL_TEXTURE_EXTERNAL_OES:
3315 texture = context->getTextureExternal();
3316 break;
Alexis Hetued306182015-04-02 12:02:28 -04003317 case GL_TEXTURE_2D_ARRAY:
3318 if(clientVersion < 3)
3319 {
3320 return error(GL_INVALID_ENUM);
3321 }
3322 else
3323 {
3324 UNIMPLEMENTED();
3325 texture = context->getTexture3D();
3326 break;
3327 }
3328 case GL_TEXTURE_3D_OES:
3329 texture = context->getTexture3D();
3330 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003331 default:
3332 return error(GL_INVALID_ENUM);
3333 }
John Bauman66b8ab22014-05-06 15:57:45 -04003334
Nicolas Capensf160b172014-11-26 11:58:23 -05003335 switch(pname)
3336 {
3337 case GL_TEXTURE_MAG_FILTER:
3338 *params = texture->getMagFilter();
3339 break;
3340 case GL_TEXTURE_MIN_FILTER:
3341 *params = texture->getMinFilter();
3342 break;
3343 case GL_TEXTURE_WRAP_S:
3344 *params = texture->getWrapS();
3345 break;
3346 case GL_TEXTURE_WRAP_T:
3347 *params = texture->getWrapT();
3348 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05003349 case GL_TEXTURE_WRAP_R_OES:
3350 *params = texture->getWrapR();
3351 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003352 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3353 *params = (GLint)texture->getMaxAnisotropy();
3354 break;
3355 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3356 *params = 1;
3357 break;
Alexis Hetued306182015-04-02 12:02:28 -04003358 case GL_TEXTURE_BASE_LEVEL:
3359 if(clientVersion >= 3)
3360 {
3361 *params = texture->getBaseLevel();
3362 break;
3363 }
3364 else return error(GL_INVALID_ENUM);
3365 case GL_TEXTURE_COMPARE_FUNC:
3366 if(clientVersion >= 3)
3367 {
3368 *params = (GLint)texture->getCompareFunc();
3369 break;
3370 }
3371 else return error(GL_INVALID_ENUM);
3372 case GL_TEXTURE_COMPARE_MODE:
3373 if(clientVersion >= 3)
3374 {
3375 *params = (GLint)texture->getCompareMode();
3376 break;
3377 }
3378 else return error(GL_INVALID_ENUM);
3379 case GL_TEXTURE_IMMUTABLE_FORMAT:
3380 if(clientVersion >= 3)
3381 {
3382 *params = (GLint)texture->getImmutableFormat();
3383 break;
3384 }
3385 else return error(GL_INVALID_ENUM);
3386 case GL_TEXTURE_MAX_LEVEL:
3387 if(clientVersion >= 3)
3388 {
3389 *params = texture->getMaxLevel();
3390 break;
3391 }
3392 else return error(GL_INVALID_ENUM);
3393 case GL_TEXTURE_MAX_LOD:
3394 if(clientVersion >= 3)
3395 {
3396 *params = (GLint)texture->getMaxLOD();
3397 break;
3398 }
3399 else return error(GL_INVALID_ENUM);
3400 case GL_TEXTURE_MIN_LOD:
3401 if(clientVersion >= 3)
3402 {
3403 *params = (GLint)texture->getMinLOD();
3404 break;
3405 }
3406 else return error(GL_INVALID_ENUM);
3407 case GL_TEXTURE_SWIZZLE_R:
3408 if(clientVersion >= 3)
3409 {
3410 *params = (GLint)texture->getSwizzleR();
3411 break;
3412 }
3413 else return error(GL_INVALID_ENUM);
3414 case GL_TEXTURE_SWIZZLE_G:
3415 if(clientVersion >= 3)
3416 {
3417 *params = (GLint)texture->getSwizzleG();
3418 break;
3419 }
3420 else return error(GL_INVALID_ENUM);
3421 case GL_TEXTURE_SWIZZLE_B:
3422 if(clientVersion >= 3)
3423 {
3424 *params = (GLint)texture->getSwizzleB();
3425 break;
3426 }
3427 else return error(GL_INVALID_ENUM);
3428 case GL_TEXTURE_SWIZZLE_A:
3429 if(clientVersion >= 3)
3430 {
3431 *params = (GLint)texture->getSwizzleA();
3432 break;
3433 }
3434 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003435 default:
3436 return error(GL_INVALID_ENUM);
3437 }
3438 }
John Bauman66b8ab22014-05-06 15:57:45 -04003439}
3440
3441void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3442{
Nicolas Capensf160b172014-11-26 11:58:23 -05003443 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3444 program, location, bufSize, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003445
Nicolas Capensf160b172014-11-26 11:58:23 -05003446 if(bufSize < 0)
3447 {
3448 return error(GL_INVALID_VALUE);
3449 }
John Bauman66b8ab22014-05-06 15:57:45 -04003450
Nicolas Capensf160b172014-11-26 11:58:23 -05003451 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003452
Nicolas Capensf160b172014-11-26 11:58:23 -05003453 if(context)
3454 {
3455 if(program == 0)
3456 {
3457 return error(GL_INVALID_VALUE);
3458 }
John Bauman66b8ab22014-05-06 15:57:45 -04003459
Nicolas Capensf160b172014-11-26 11:58:23 -05003460 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003461
Nicolas Capensf160b172014-11-26 11:58:23 -05003462 if(!programObject || !programObject->isLinked())
3463 {
3464 return error(GL_INVALID_OPERATION);
3465 }
John Bauman66b8ab22014-05-06 15:57:45 -04003466
Nicolas Capensf160b172014-11-26 11:58:23 -05003467 if(!programObject->getUniformfv(location, &bufSize, params))
3468 {
3469 return error(GL_INVALID_OPERATION);
3470 }
3471 }
John Bauman66b8ab22014-05-06 15:57:45 -04003472}
3473
3474void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3475{
Nicolas Capensf160b172014-11-26 11:58:23 -05003476 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003477
Nicolas Capensf160b172014-11-26 11:58:23 -05003478 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003479
Nicolas Capensf160b172014-11-26 11:58:23 -05003480 if(context)
3481 {
3482 if(program == 0)
3483 {
3484 return error(GL_INVALID_VALUE);
3485 }
John Bauman66b8ab22014-05-06 15:57:45 -04003486
Nicolas Capensf160b172014-11-26 11:58:23 -05003487 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003488
Nicolas Capensf160b172014-11-26 11:58:23 -05003489 if(!programObject || !programObject->isLinked())
3490 {
3491 return error(GL_INVALID_OPERATION);
3492 }
John Bauman66b8ab22014-05-06 15:57:45 -04003493
Nicolas Capensf160b172014-11-26 11:58:23 -05003494 if(!programObject->getUniformfv(location, NULL, params))
3495 {
3496 return error(GL_INVALID_OPERATION);
3497 }
3498 }
John Bauman66b8ab22014-05-06 15:57:45 -04003499}
3500
3501void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3502{
Nicolas Capensf160b172014-11-26 11:58:23 -05003503 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3504 program, location, bufSize, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003505
Nicolas Capensf160b172014-11-26 11:58:23 -05003506 if(bufSize < 0)
3507 {
3508 return error(GL_INVALID_VALUE);
3509 }
John Bauman66b8ab22014-05-06 15:57:45 -04003510
Nicolas Capensf160b172014-11-26 11:58:23 -05003511 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003512
Nicolas Capensf160b172014-11-26 11:58:23 -05003513 if(context)
3514 {
3515 if(program == 0)
3516 {
3517 return error(GL_INVALID_VALUE);
3518 }
John Bauman66b8ab22014-05-06 15:57:45 -04003519
Nicolas Capensf160b172014-11-26 11:58:23 -05003520 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003521
Nicolas Capensf160b172014-11-26 11:58:23 -05003522 if(!programObject || !programObject->isLinked())
3523 {
3524 return error(GL_INVALID_OPERATION);
3525 }
John Bauman66b8ab22014-05-06 15:57:45 -04003526
Nicolas Capensf160b172014-11-26 11:58:23 -05003527 if(!programObject)
3528 {
3529 return error(GL_INVALID_OPERATION);
3530 }
John Bauman66b8ab22014-05-06 15:57:45 -04003531
Nicolas Capensf160b172014-11-26 11:58:23 -05003532 if(!programObject->getUniformiv(location, &bufSize, params))
3533 {
3534 return error(GL_INVALID_OPERATION);
3535 }
3536 }
John Bauman66b8ab22014-05-06 15:57:45 -04003537}
3538
3539void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
3540{
Nicolas Capensf160b172014-11-26 11:58:23 -05003541 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003542
Nicolas Capensf160b172014-11-26 11:58:23 -05003543 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003544
Nicolas Capensf160b172014-11-26 11:58:23 -05003545 if(context)
3546 {
3547 if(program == 0)
3548 {
3549 return error(GL_INVALID_VALUE);
3550 }
John Bauman66b8ab22014-05-06 15:57:45 -04003551
Nicolas Capensf160b172014-11-26 11:58:23 -05003552 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003553
Nicolas Capensf160b172014-11-26 11:58:23 -05003554 if(!programObject || !programObject->isLinked())
3555 {
3556 return error(GL_INVALID_OPERATION);
3557 }
John Bauman66b8ab22014-05-06 15:57:45 -04003558
Nicolas Capensf160b172014-11-26 11:58:23 -05003559 if(!programObject)
3560 {
3561 return error(GL_INVALID_OPERATION);
3562 }
John Bauman66b8ab22014-05-06 15:57:45 -04003563
Nicolas Capensf160b172014-11-26 11:58:23 -05003564 if(!programObject->getUniformiv(location, NULL, params))
3565 {
3566 return error(GL_INVALID_OPERATION);
3567 }
3568 }
John Bauman66b8ab22014-05-06 15:57:45 -04003569}
3570
3571int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
3572{
Nicolas Capensf160b172014-11-26 11:58:23 -05003573 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
John Bauman66b8ab22014-05-06 15:57:45 -04003574
Nicolas Capensf160b172014-11-26 11:58:23 -05003575 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003576
Nicolas Capensf160b172014-11-26 11:58:23 -05003577 if(strstr(name, "gl_") == name)
3578 {
3579 return -1;
3580 }
John Bauman66b8ab22014-05-06 15:57:45 -04003581
Nicolas Capensf160b172014-11-26 11:58:23 -05003582 if(context)
3583 {
3584 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003585
Nicolas Capensf160b172014-11-26 11:58:23 -05003586 if(!programObject)
3587 {
3588 if(context->getShader(program))
3589 {
3590 return error(GL_INVALID_OPERATION, -1);
3591 }
3592 else
3593 {
3594 return error(GL_INVALID_VALUE, -1);
3595 }
3596 }
John Bauman66b8ab22014-05-06 15:57:45 -04003597
Nicolas Capensf160b172014-11-26 11:58:23 -05003598 if(!programObject->isLinked())
3599 {
3600 return error(GL_INVALID_OPERATION, -1);
3601 }
John Bauman66b8ab22014-05-06 15:57:45 -04003602
Nicolas Capensf160b172014-11-26 11:58:23 -05003603 return programObject->getUniformLocation(name);
3604 }
John Bauman66b8ab22014-05-06 15:57:45 -04003605
Nicolas Capensf160b172014-11-26 11:58:23 -05003606 return -1;
John Bauman66b8ab22014-05-06 15:57:45 -04003607}
3608
3609void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3610{
Nicolas Capensf160b172014-11-26 11:58:23 -05003611 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003612
Nicolas Capensf160b172014-11-26 11:58:23 -05003613 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003614
Nicolas Capensf160b172014-11-26 11:58:23 -05003615 if(context)
3616 {
3617 if(index >= es2::MAX_VERTEX_ATTRIBS)
3618 {
3619 return error(GL_INVALID_VALUE);
3620 }
John Bauman66b8ab22014-05-06 15:57:45 -04003621
Nicolas Capensf160b172014-11-26 11:58:23 -05003622 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
Alexis Hetued306182015-04-02 12:02:28 -04003623
3624 egl::GLint clientVersion = context->getClientVersion();
John Bauman66b8ab22014-05-06 15:57:45 -04003625
Nicolas Capensf160b172014-11-26 11:58:23 -05003626 switch(pname)
3627 {
3628 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3629 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3630 break;
3631 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3632 *params = (GLfloat)attribState.mSize;
3633 break;
3634 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3635 *params = (GLfloat)attribState.mStride;
3636 break;
3637 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3638 *params = (GLfloat)attribState.mType;
3639 break;
3640 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3641 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
3642 break;
3643 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003644 *params = (GLfloat)attribState.mBoundBuffer.name();
Nicolas Capensf160b172014-11-26 11:58:23 -05003645 break;
3646 case GL_CURRENT_VERTEX_ATTRIB:
3647 for(int i = 0; i < 4; ++i)
3648 {
3649 params[i] = attribState.mCurrentValue[i];
3650 }
3651 break;
Alexis Hetued306182015-04-02 12:02:28 -04003652 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
3653 if(clientVersion >= 3)
3654 {
3655 switch(attribState.mType)
3656 {
3657 case GL_BYTE:
3658 case GL_UNSIGNED_BYTE:
3659 case GL_SHORT:
3660 case GL_UNSIGNED_SHORT:
3661 case GL_INT:
3662 case GL_INT_2_10_10_10_REV:
3663 case GL_UNSIGNED_INT:
3664 case GL_FIXED:
3665 *params = (GLfloat)GL_TRUE;
3666 break;
3667 default:
3668 *params = (GLfloat)GL_FALSE;
3669 break;
3670 }
3671 break;
3672 }
3673 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003674 default: return error(GL_INVALID_ENUM);
3675 }
3676 }
John Bauman66b8ab22014-05-06 15:57:45 -04003677}
3678
3679void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3680{
Nicolas Capensf160b172014-11-26 11:58:23 -05003681 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003682
Nicolas Capensf160b172014-11-26 11:58:23 -05003683 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003684
Nicolas Capensf160b172014-11-26 11:58:23 -05003685 if(context)
3686 {
3687 if(index >= es2::MAX_VERTEX_ATTRIBS)
3688 {
3689 return error(GL_INVALID_VALUE);
3690 }
John Bauman66b8ab22014-05-06 15:57:45 -04003691
Nicolas Capensf160b172014-11-26 11:58:23 -05003692 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
John Bauman66b8ab22014-05-06 15:57:45 -04003693
Alexis Hetued306182015-04-02 12:02:28 -04003694 egl::GLint clientVersion = context->getClientVersion();
3695
Nicolas Capensf160b172014-11-26 11:58:23 -05003696 switch(pname)
3697 {
3698 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3699 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3700 break;
3701 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3702 *params = attribState.mSize;
3703 break;
3704 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3705 *params = attribState.mStride;
3706 break;
3707 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3708 *params = attribState.mType;
3709 break;
3710 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3711 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
3712 break;
3713 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003714 *params = attribState.mBoundBuffer.name();
Nicolas Capensf160b172014-11-26 11:58:23 -05003715 break;
3716 case GL_CURRENT_VERTEX_ATTRIB:
3717 for(int i = 0; i < 4; ++i)
3718 {
3719 float currentValue = attribState.mCurrentValue[i];
3720 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3721 }
3722 break;
Alexis Hetued306182015-04-02 12:02:28 -04003723 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
3724 if(clientVersion >= 3)
3725 {
3726 switch(attribState.mType)
3727 {
3728 case GL_BYTE:
3729 case GL_UNSIGNED_BYTE:
3730 case GL_SHORT:
3731 case GL_UNSIGNED_SHORT:
3732 case GL_INT:
3733 case GL_INT_2_10_10_10_REV:
3734 case GL_UNSIGNED_INT:
3735 case GL_FIXED:
3736 *params = GL_TRUE;
3737 break;
3738 default:
3739 *params = GL_FALSE;
3740 break;
3741 }
3742 break;
3743 }
3744 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003745 default: return error(GL_INVALID_ENUM);
3746 }
3747 }
John Bauman66b8ab22014-05-06 15:57:45 -04003748}
3749
3750void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
3751{
Nicolas Capensf160b172014-11-26 11:58:23 -05003752 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
John Bauman66b8ab22014-05-06 15:57:45 -04003753
Nicolas Capensf160b172014-11-26 11:58:23 -05003754 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003755
Nicolas Capensf160b172014-11-26 11:58:23 -05003756 if(context)
3757 {
3758 if(index >= es2::MAX_VERTEX_ATTRIBS)
3759 {
3760 return error(GL_INVALID_VALUE);
3761 }
John Bauman66b8ab22014-05-06 15:57:45 -04003762
Nicolas Capensf160b172014-11-26 11:58:23 -05003763 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3764 {
3765 return error(GL_INVALID_ENUM);
3766 }
John Bauman66b8ab22014-05-06 15:57:45 -04003767
Nicolas Capensf160b172014-11-26 11:58:23 -05003768 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
3769 }
John Bauman66b8ab22014-05-06 15:57:45 -04003770}
3771
3772void GL_APIENTRY glHint(GLenum target, GLenum mode)
3773{
Nicolas Capensf160b172014-11-26 11:58:23 -05003774 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
John Bauman66b8ab22014-05-06 15:57:45 -04003775
Nicolas Capensf160b172014-11-26 11:58:23 -05003776 switch(mode)
3777 {
3778 case GL_FASTEST:
3779 case GL_NICEST:
3780 case GL_DONT_CARE:
3781 break;
3782 default:
3783 return error(GL_INVALID_ENUM);
3784 }
John Bauman66b8ab22014-05-06 15:57:45 -04003785
Nicolas Capensf160b172014-11-26 11:58:23 -05003786 es2::Context *context = es2::getContext();
3787 switch(target)
3788 {
3789 case GL_GENERATE_MIPMAP_HINT:
3790 if(context) context->setGenerateMipmapHint(mode);
3791 break;
3792 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3793 if(context) context->setFragmentShaderDerivativeHint(mode);
3794 break;
3795 default:
3796 return error(GL_INVALID_ENUM);
3797 }
John Bauman66b8ab22014-05-06 15:57:45 -04003798}
3799
3800GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)
3801{
Nicolas Capensf160b172014-11-26 11:58:23 -05003802 TRACE("(GLuint buffer = %d)", buffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003803
Nicolas Capensf160b172014-11-26 11:58:23 -05003804 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003805
Nicolas Capensf160b172014-11-26 11:58:23 -05003806 if(context && buffer)
3807 {
3808 es2::Buffer *bufferObject = context->getBuffer(buffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003809
Nicolas Capensf160b172014-11-26 11:58:23 -05003810 if(bufferObject)
3811 {
3812 return GL_TRUE;
3813 }
3814 }
John Bauman66b8ab22014-05-06 15:57:45 -04003815
Nicolas Capensf160b172014-11-26 11:58:23 -05003816 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003817}
3818
3819GLboolean GL_APIENTRY glIsEnabled(GLenum cap)
3820{
Nicolas Capensf160b172014-11-26 11:58:23 -05003821 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04003822
Nicolas Capensf160b172014-11-26 11:58:23 -05003823 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003824
Nicolas Capensf160b172014-11-26 11:58:23 -05003825 if(context)
3826 {
3827 switch(cap)
3828 {
3829 case GL_CULL_FACE: return context->isCullFaceEnabled();
3830 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3831 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3832 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3833 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3834 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3835 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3836 case GL_BLEND: return context->isBlendEnabled();
3837 case GL_DITHER: return context->isDitherEnabled();
3838 default:
3839 return error(GL_INVALID_ENUM, false);
3840 }
3841 }
John Bauman66b8ab22014-05-06 15:57:45 -04003842
Nicolas Capensf160b172014-11-26 11:58:23 -05003843 return false;
John Bauman66b8ab22014-05-06 15:57:45 -04003844}
3845
3846GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)
3847{
Nicolas Capensf160b172014-11-26 11:58:23 -05003848 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04003849
Nicolas Capensf160b172014-11-26 11:58:23 -05003850 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003851
Nicolas Capensf160b172014-11-26 11:58:23 -05003852 if(context)
3853 {
3854 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04003855
Nicolas Capensf160b172014-11-26 11:58:23 -05003856 if(fenceObject == NULL)
3857 {
3858 return GL_FALSE;
3859 }
John Bauman66b8ab22014-05-06 15:57:45 -04003860
Nicolas Capensf160b172014-11-26 11:58:23 -05003861 return fenceObject->isFence();
3862 }
John Bauman66b8ab22014-05-06 15:57:45 -04003863
Nicolas Capensf160b172014-11-26 11:58:23 -05003864 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003865}
3866
3867GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
3868{
Nicolas Capensf160b172014-11-26 11:58:23 -05003869 TRACE("(GLuint framebuffer = %d)", framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003870
Nicolas Capensf160b172014-11-26 11:58:23 -05003871 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003872
Nicolas Capensf160b172014-11-26 11:58:23 -05003873 if(context && framebuffer)
3874 {
3875 es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003876
Nicolas Capensf160b172014-11-26 11:58:23 -05003877 if(framebufferObject)
3878 {
3879 return GL_TRUE;
3880 }
3881 }
John Bauman66b8ab22014-05-06 15:57:45 -04003882
Nicolas Capensf160b172014-11-26 11:58:23 -05003883 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003884}
3885
3886GLboolean GL_APIENTRY glIsProgram(GLuint program)
3887{
Nicolas Capensf160b172014-11-26 11:58:23 -05003888 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04003889
Nicolas Capensf160b172014-11-26 11:58:23 -05003890 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003891
Nicolas Capensf160b172014-11-26 11:58:23 -05003892 if(context && program)
3893 {
3894 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003895
Nicolas Capensf160b172014-11-26 11:58:23 -05003896 if(programObject)
3897 {
3898 return GL_TRUE;
3899 }
3900 }
John Bauman66b8ab22014-05-06 15:57:45 -04003901
Nicolas Capensf160b172014-11-26 11:58:23 -05003902 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003903}
3904
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003905GLboolean GL_APIENTRY glIsQueryEXT(GLuint name)
John Bauman66b8ab22014-05-06 15:57:45 -04003906{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003907 TRACE("(GLuint name = %d)", name);
John Bauman66b8ab22014-05-06 15:57:45 -04003908
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003909 if(name == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05003910 {
3911 return GL_FALSE;
3912 }
John Bauman66b8ab22014-05-06 15:57:45 -04003913
Nicolas Capensf160b172014-11-26 11:58:23 -05003914 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003915
Nicolas Capensf160b172014-11-26 11:58:23 -05003916 if(context)
3917 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003918 es2::Query *queryObject = context->getQuery(name, false, GL_NONE);
John Bauman66b8ab22014-05-06 15:57:45 -04003919
Nicolas Capensf160b172014-11-26 11:58:23 -05003920 if(queryObject)
3921 {
3922 return GL_TRUE;
3923 }
3924 }
John Bauman66b8ab22014-05-06 15:57:45 -04003925
Nicolas Capensf160b172014-11-26 11:58:23 -05003926 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003927}
3928
3929GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
3930{
Nicolas Capensf160b172014-11-26 11:58:23 -05003931 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003932
Nicolas Capensf160b172014-11-26 11:58:23 -05003933 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003934
Nicolas Capensf160b172014-11-26 11:58:23 -05003935 if(context && renderbuffer)
3936 {
3937 es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04003938
Nicolas Capensf160b172014-11-26 11:58:23 -05003939 if(renderbufferObject)
3940 {
3941 return GL_TRUE;
3942 }
3943 }
John Bauman66b8ab22014-05-06 15:57:45 -04003944
Nicolas Capensf160b172014-11-26 11:58:23 -05003945 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003946}
3947
3948GLboolean GL_APIENTRY glIsShader(GLuint shader)
3949{
Nicolas Capensf160b172014-11-26 11:58:23 -05003950 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003951
Nicolas Capensf160b172014-11-26 11:58:23 -05003952 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003953
Nicolas Capensf160b172014-11-26 11:58:23 -05003954 if(context && shader)
3955 {
3956 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003957
Nicolas Capensf160b172014-11-26 11:58:23 -05003958 if(shaderObject)
3959 {
3960 return GL_TRUE;
3961 }
3962 }
John Bauman66b8ab22014-05-06 15:57:45 -04003963
Nicolas Capensf160b172014-11-26 11:58:23 -05003964 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003965}
3966
3967GLboolean GL_APIENTRY glIsTexture(GLuint texture)
3968{
Nicolas Capensf160b172014-11-26 11:58:23 -05003969 TRACE("(GLuint texture = %d)", texture);
John Bauman66b8ab22014-05-06 15:57:45 -04003970
Nicolas Capensf160b172014-11-26 11:58:23 -05003971 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003972
Nicolas Capensf160b172014-11-26 11:58:23 -05003973 if(context && texture)
3974 {
3975 es2::Texture *textureObject = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -04003976
Nicolas Capensf160b172014-11-26 11:58:23 -05003977 if(textureObject)
3978 {
3979 return GL_TRUE;
3980 }
3981 }
John Bauman66b8ab22014-05-06 15:57:45 -04003982
Nicolas Capensf160b172014-11-26 11:58:23 -05003983 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04003984}
3985
3986void GL_APIENTRY glLineWidth(GLfloat width)
3987{
Nicolas Capensf160b172014-11-26 11:58:23 -05003988 TRACE("(GLfloat width = %f)", width);
John Bauman66b8ab22014-05-06 15:57:45 -04003989
Nicolas Capensf160b172014-11-26 11:58:23 -05003990 if(width <= 0.0f)
3991 {
3992 return error(GL_INVALID_VALUE);
3993 }
John Bauman66b8ab22014-05-06 15:57:45 -04003994
Nicolas Capensf160b172014-11-26 11:58:23 -05003995 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003996
Nicolas Capensf160b172014-11-26 11:58:23 -05003997 if(context)
3998 {
3999 context->setLineWidth(width);
4000 }
John Bauman66b8ab22014-05-06 15:57:45 -04004001}
4002
4003void GL_APIENTRY glLinkProgram(GLuint program)
4004{
Nicolas Capensf160b172014-11-26 11:58:23 -05004005 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04004006
Nicolas Capensf160b172014-11-26 11:58:23 -05004007 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004008
Nicolas Capensf160b172014-11-26 11:58:23 -05004009 if(context)
4010 {
4011 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004012
Nicolas Capensf160b172014-11-26 11:58:23 -05004013 if(!programObject)
4014 {
4015 if(context->getShader(program))
4016 {
4017 return error(GL_INVALID_OPERATION);
4018 }
4019 else
4020 {
4021 return error(GL_INVALID_VALUE);
4022 }
4023 }
John Bauman66b8ab22014-05-06 15:57:45 -04004024
Nicolas Capensf160b172014-11-26 11:58:23 -05004025 programObject->link();
4026 }
John Bauman66b8ab22014-05-06 15:57:45 -04004027}
4028
4029void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)
4030{
Nicolas Capensf160b172014-11-26 11:58:23 -05004031 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04004032
Nicolas Capensf160b172014-11-26 11:58:23 -05004033 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004034
Nicolas Capensf160b172014-11-26 11:58:23 -05004035 if(context)
4036 {
Alexis Hetued306182015-04-02 12:02:28 -04004037 egl::GLint clientVersion = context->getClientVersion();
4038
Nicolas Capensf160b172014-11-26 11:58:23 -05004039 switch(pname)
4040 {
4041 case GL_UNPACK_ALIGNMENT:
4042 if(param != 1 && param != 2 && param != 4 && param != 8)
4043 {
4044 return error(GL_INVALID_VALUE);
4045 }
4046 context->setUnpackAlignment(param);
4047 break;
4048 case GL_PACK_ALIGNMENT:
4049 if(param != 1 && param != 2 && param != 4 && param != 8)
4050 {
4051 return error(GL_INVALID_VALUE);
4052 }
4053 context->setPackAlignment(param);
4054 break;
Alexis Hetued306182015-04-02 12:02:28 -04004055 case GL_PACK_ROW_LENGTH:
4056 case GL_PACK_SKIP_PIXELS:
4057 case GL_PACK_SKIP_ROWS:
4058 case GL_UNPACK_ROW_LENGTH:
4059 case GL_UNPACK_IMAGE_HEIGHT:
4060 case GL_UNPACK_SKIP_PIXELS:
4061 case GL_UNPACK_SKIP_ROWS:
4062 case GL_UNPACK_SKIP_IMAGES:
4063 if(clientVersion >= 3)
4064 {
4065 UNIMPLEMENTED();
4066 break;
4067 }
4068 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05004069 default:
4070 return error(GL_INVALID_ENUM);
4071 }
4072 }
John Bauman66b8ab22014-05-06 15:57:45 -04004073}
4074
4075void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
4076{
Nicolas Capensf160b172014-11-26 11:58:23 -05004077 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
John Bauman66b8ab22014-05-06 15:57:45 -04004078
Nicolas Capensf160b172014-11-26 11:58:23 -05004079 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004080
Nicolas Capensf160b172014-11-26 11:58:23 -05004081 if(context)
4082 {
4083 context->setPolygonOffsetParams(factor, units);
4084 }
John Bauman66b8ab22014-05-06 15:57:45 -04004085}
4086
4087void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
Nicolas Capensf160b172014-11-26 11:58:23 -05004088 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
John Bauman66b8ab22014-05-06 15:57:45 -04004089{
Nicolas Capensf160b172014-11-26 11:58:23 -05004090 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4091 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4092 x, y, width, height, format, type, bufSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -04004093
Nicolas Capensf160b172014-11-26 11:58:23 -05004094 if(width < 0 || height < 0 || bufSize < 0)
4095 {
4096 return error(GL_INVALID_VALUE);
4097 }
John Bauman66b8ab22014-05-06 15:57:45 -04004098
Nicolas Capensf160b172014-11-26 11:58:23 -05004099 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004100
Nicolas Capensf160b172014-11-26 11:58:23 -05004101 if(context)
4102 {
4103 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4104 }
John Bauman66b8ab22014-05-06 15:57:45 -04004105}
4106
4107void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
4108{
Nicolas Capensf160b172014-11-26 11:58:23 -05004109 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4110 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
4111 x, y, width, height, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04004112
Nicolas Capensf160b172014-11-26 11:58:23 -05004113 if(width < 0 || height < 0)
4114 {
4115 return error(GL_INVALID_VALUE);
4116 }
John Bauman66b8ab22014-05-06 15:57:45 -04004117
Nicolas Capensf160b172014-11-26 11:58:23 -05004118 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004119
Nicolas Capensf160b172014-11-26 11:58:23 -05004120 if(context)
4121 {
4122 context->readPixels(x, y, width, height, format, type, NULL, pixels);
4123 }
John Bauman66b8ab22014-05-06 15:57:45 -04004124}
4125
4126void GL_APIENTRY glReleaseShaderCompiler(void)
4127{
Nicolas Capensf160b172014-11-26 11:58:23 -05004128 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04004129
Nicolas Capensf160b172014-11-26 11:58:23 -05004130 es2::Shader::releaseCompiler();
John Bauman66b8ab22014-05-06 15:57:45 -04004131}
4132
4133void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4134{
Nicolas Capensf160b172014-11-26 11:58:23 -05004135 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4136 target, samples, internalformat, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004137
Nicolas Capensf160b172014-11-26 11:58:23 -05004138 switch(target)
4139 {
4140 case GL_RENDERBUFFER:
4141 break;
4142 default:
4143 return error(GL_INVALID_ENUM);
4144 }
John Bauman66b8ab22014-05-06 15:57:45 -04004145
Nicolas Capensf160b172014-11-26 11:58:23 -05004146 if(!es2::IsColorRenderable(internalformat) && !es2::IsDepthRenderable(internalformat) && !es2::IsStencilRenderable(internalformat))
4147 {
4148 return error(GL_INVALID_ENUM);
4149 }
John Bauman66b8ab22014-05-06 15:57:45 -04004150
Nicolas Capensf160b172014-11-26 11:58:23 -05004151 if(width < 0 || height < 0 || samples < 0)
4152 {
4153 return error(GL_INVALID_VALUE);
4154 }
John Bauman66b8ab22014-05-06 15:57:45 -04004155
Nicolas Capensf160b172014-11-26 11:58:23 -05004156 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004157
Nicolas Capensf160b172014-11-26 11:58:23 -05004158 if(context)
4159 {
4160 if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4161 height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4162 samples > es2::IMPLEMENTATION_MAX_SAMPLES)
4163 {
4164 return error(GL_INVALID_VALUE);
4165 }
John Bauman66b8ab22014-05-06 15:57:45 -04004166
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004167 GLuint handle = context->getRenderbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05004168 if(handle == 0)
4169 {
4170 return error(GL_INVALID_OPERATION);
4171 }
John Bauman66b8ab22014-05-06 15:57:45 -04004172
Nicolas Capensf160b172014-11-26 11:58:23 -05004173 switch(internalformat)
4174 {
4175 case GL_DEPTH_COMPONENT16:
4176 context->setRenderbufferStorage(new es2::Depthbuffer(width, height, samples));
4177 break;
4178 case GL_RGBA4:
4179 case GL_RGB5_A1:
4180 case GL_RGB565:
4181 case GL_RGB8_OES:
4182 case GL_RGBA8_OES:
4183 context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
4184 break;
4185 case GL_STENCIL_INDEX8:
4186 context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
4187 break;
4188 case GL_DEPTH24_STENCIL8_OES:
4189 context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, samples));
4190 break;
4191 default:
4192 return error(GL_INVALID_ENUM);
4193 }
4194 }
John Bauman66b8ab22014-05-06 15:57:45 -04004195}
4196
4197void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4198{
Nicolas Capensf160b172014-11-26 11:58:23 -05004199 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004200}
4201
4202void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
4203{
Nicolas Capensf160b172014-11-26 11:58:23 -05004204 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
John Bauman66b8ab22014-05-06 15:57:45 -04004205
Nicolas Capensf160b172014-11-26 11:58:23 -05004206 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004207
Nicolas Capensf160b172014-11-26 11:58:23 -05004208 if(context)
4209 {
4210 context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
4211 }
John Bauman66b8ab22014-05-06 15:57:45 -04004212}
4213
4214void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
4215{
Nicolas Capensf160b172014-11-26 11:58:23 -05004216 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
John Bauman66b8ab22014-05-06 15:57:45 -04004217
Nicolas Capensf160b172014-11-26 11:58:23 -05004218 if(condition != GL_ALL_COMPLETED_NV)
4219 {
4220 return error(GL_INVALID_ENUM);
4221 }
John Bauman66b8ab22014-05-06 15:57:45 -04004222
Nicolas Capensf160b172014-11-26 11:58:23 -05004223 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004224
Nicolas Capensf160b172014-11-26 11:58:23 -05004225 if(context)
4226 {
4227 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004228
Nicolas Capensf160b172014-11-26 11:58:23 -05004229 if(fenceObject == NULL)
4230 {
4231 return error(GL_INVALID_OPERATION);
4232 }
John Bauman66b8ab22014-05-06 15:57:45 -04004233
Nicolas Capensf160b172014-11-26 11:58:23 -05004234 fenceObject->setFence(condition);
4235 }
John Bauman66b8ab22014-05-06 15:57:45 -04004236}
4237
4238void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4239{
Nicolas Capensf160b172014-11-26 11:58:23 -05004240 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004241
Nicolas Capensf160b172014-11-26 11:58:23 -05004242 if(width < 0 || height < 0)
4243 {
4244 return error(GL_INVALID_VALUE);
4245 }
John Bauman66b8ab22014-05-06 15:57:45 -04004246
Nicolas Capensf160b172014-11-26 11:58:23 -05004247 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004248
Nicolas Capensf160b172014-11-26 11:58:23 -05004249 if(context)
4250 {
4251 context->setScissorParams(x, y, width, height);
4252 }
John Bauman66b8ab22014-05-06 15:57:45 -04004253}
4254
4255void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
4256{
Nicolas Capensf160b172014-11-26 11:58:23 -05004257 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
4258 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
4259 n, shaders, binaryformat, binary, length);
John Bauman66b8ab22014-05-06 15:57:45 -04004260
Nicolas Capensf160b172014-11-26 11:58:23 -05004261 // No binary shader formats are supported.
4262 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04004263}
4264
Nicolas Capensb0e93552014-10-28 11:54:43 -04004265void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
John Bauman66b8ab22014-05-06 15:57:45 -04004266{
Nicolas Capensf160b172014-11-26 11:58:23 -05004267 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
4268 shader, count, string, length);
John Bauman66b8ab22014-05-06 15:57:45 -04004269
Nicolas Capensf160b172014-11-26 11:58:23 -05004270 if(count < 0)
4271 {
4272 return error(GL_INVALID_VALUE);
4273 }
John Bauman66b8ab22014-05-06 15:57:45 -04004274
Nicolas Capensf160b172014-11-26 11:58:23 -05004275 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004276
Nicolas Capensf160b172014-11-26 11:58:23 -05004277 if(context)
4278 {
4279 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004280
Nicolas Capensf160b172014-11-26 11:58:23 -05004281 if(!shaderObject)
4282 {
4283 if(context->getProgram(shader))
4284 {
4285 return error(GL_INVALID_OPERATION);
4286 }
4287 else
4288 {
4289 return error(GL_INVALID_VALUE);
4290 }
4291 }
John Bauman66b8ab22014-05-06 15:57:45 -04004292
Nicolas Capensf160b172014-11-26 11:58:23 -05004293 shaderObject->setSource(count, string, length);
4294 }
John Bauman66b8ab22014-05-06 15:57:45 -04004295}
4296
4297void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
4298{
Nicolas Capensf160b172014-11-26 11:58:23 -05004299 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004300}
4301
4302void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4303{
Nicolas Capensf160b172014-11-26 11:58:23 -05004304 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 -04004305
Nicolas Capensf160b172014-11-26 11:58:23 -05004306 switch(face)
4307 {
4308 case GL_FRONT:
4309 case GL_BACK:
4310 case GL_FRONT_AND_BACK:
4311 break;
4312 default:
4313 return error(GL_INVALID_ENUM);
4314 }
John Bauman66b8ab22014-05-06 15:57:45 -04004315
Nicolas Capensf160b172014-11-26 11:58:23 -05004316 switch(func)
4317 {
4318 case GL_NEVER:
4319 case GL_ALWAYS:
4320 case GL_LESS:
4321 case GL_LEQUAL:
4322 case GL_EQUAL:
4323 case GL_GEQUAL:
4324 case GL_GREATER:
4325 case GL_NOTEQUAL:
4326 break;
4327 default:
4328 return error(GL_INVALID_ENUM);
4329 }
John Bauman66b8ab22014-05-06 15:57:45 -04004330
Nicolas Capensf160b172014-11-26 11:58:23 -05004331 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004332
Nicolas Capensf160b172014-11-26 11:58:23 -05004333 if(context)
4334 {
4335 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4336 {
4337 context->setStencilParams(func, ref, mask);
4338 }
John Bauman66b8ab22014-05-06 15:57:45 -04004339
Nicolas Capensf160b172014-11-26 11:58:23 -05004340 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4341 {
4342 context->setStencilBackParams(func, ref, mask);
4343 }
4344 }
John Bauman66b8ab22014-05-06 15:57:45 -04004345}
4346
4347void GL_APIENTRY glStencilMask(GLuint mask)
4348{
Nicolas Capensf160b172014-11-26 11:58:23 -05004349 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004350}
4351
4352void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
4353{
Nicolas Capensf160b172014-11-26 11:58:23 -05004354 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004355
Nicolas Capensf160b172014-11-26 11:58:23 -05004356 switch(face)
4357 {
4358 case GL_FRONT:
4359 case GL_BACK:
4360 case GL_FRONT_AND_BACK:
4361 break;
4362 default:
4363 return error(GL_INVALID_ENUM);
4364 }
John Bauman66b8ab22014-05-06 15:57:45 -04004365
Nicolas Capensf160b172014-11-26 11:58:23 -05004366 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004367
Nicolas Capensf160b172014-11-26 11:58:23 -05004368 if(context)
4369 {
4370 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4371 {
4372 context->setStencilWritemask(mask);
4373 }
John Bauman66b8ab22014-05-06 15:57:45 -04004374
Nicolas Capensf160b172014-11-26 11:58:23 -05004375 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4376 {
4377 context->setStencilBackWritemask(mask);
4378 }
4379 }
John Bauman66b8ab22014-05-06 15:57:45 -04004380}
4381
4382void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4383{
Nicolas Capensf160b172014-11-26 11:58:23 -05004384 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
John Bauman66b8ab22014-05-06 15:57:45 -04004385}
4386
4387void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4388{
Nicolas Capensf160b172014-11-26 11:58:23 -05004389 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4390 face, fail, zfail, zpass);
John Bauman66b8ab22014-05-06 15:57:45 -04004391
Nicolas Capensf160b172014-11-26 11:58:23 -05004392 switch(face)
4393 {
4394 case GL_FRONT:
4395 case GL_BACK:
4396 case GL_FRONT_AND_BACK:
4397 break;
4398 default:
4399 return error(GL_INVALID_ENUM);
4400 }
John Bauman66b8ab22014-05-06 15:57:45 -04004401
Nicolas Capensf160b172014-11-26 11:58:23 -05004402 switch(fail)
4403 {
4404 case GL_ZERO:
4405 case GL_KEEP:
4406 case GL_REPLACE:
4407 case GL_INCR:
4408 case GL_DECR:
4409 case GL_INVERT:
4410 case GL_INCR_WRAP:
4411 case GL_DECR_WRAP:
4412 break;
4413 default:
4414 return error(GL_INVALID_ENUM);
4415 }
John Bauman66b8ab22014-05-06 15:57:45 -04004416
Nicolas Capensf160b172014-11-26 11:58:23 -05004417 switch(zfail)
4418 {
4419 case GL_ZERO:
4420 case GL_KEEP:
4421 case GL_REPLACE:
4422 case GL_INCR:
4423 case GL_DECR:
4424 case GL_INVERT:
4425 case GL_INCR_WRAP:
4426 case GL_DECR_WRAP:
4427 break;
4428 default:
4429 return error(GL_INVALID_ENUM);
4430 }
John Bauman66b8ab22014-05-06 15:57:45 -04004431
Nicolas Capensf160b172014-11-26 11:58:23 -05004432 switch(zpass)
4433 {
4434 case GL_ZERO:
4435 case GL_KEEP:
4436 case GL_REPLACE:
4437 case GL_INCR:
4438 case GL_DECR:
4439 case GL_INVERT:
4440 case GL_INCR_WRAP:
4441 case GL_DECR_WRAP:
4442 break;
4443 default:
4444 return error(GL_INVALID_ENUM);
4445 }
John Bauman66b8ab22014-05-06 15:57:45 -04004446
Nicolas Capensf160b172014-11-26 11:58:23 -05004447 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004448
Nicolas Capensf160b172014-11-26 11:58:23 -05004449 if(context)
4450 {
4451 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4452 {
4453 context->setStencilOperations(fail, zfail, zpass);
4454 }
John Bauman66b8ab22014-05-06 15:57:45 -04004455
Nicolas Capensf160b172014-11-26 11:58:23 -05004456 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4457 {
4458 context->setStencilBackOperations(fail, zfail, zpass);
4459 }
4460 }
John Bauman66b8ab22014-05-06 15:57:45 -04004461}
4462
4463GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)
4464{
Nicolas Capensf160b172014-11-26 11:58:23 -05004465 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004466
Nicolas Capensf160b172014-11-26 11:58:23 -05004467 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004468
Nicolas Capensf160b172014-11-26 11:58:23 -05004469 if(context)
4470 {
4471 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004472
Nicolas Capensf160b172014-11-26 11:58:23 -05004473 if(fenceObject == NULL)
4474 {
4475 return error(GL_INVALID_OPERATION, GL_TRUE);
4476 }
John Bauman66b8ab22014-05-06 15:57:45 -04004477
Nicolas Capensf160b172014-11-26 11:58:23 -05004478 return fenceObject->testFence();
4479 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05004480
Nicolas Capensf160b172014-11-26 11:58:23 -05004481 return GL_TRUE;
John Bauman66b8ab22014-05-06 15:57:45 -04004482}
4483
4484void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4485 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4486{
Nicolas Capensf160b172014-11-26 11:58:23 -05004487 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
4488 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
4489 target, level, internalformat, width, height, border, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04004490
Nicolas Capensf160b172014-11-26 11:58:23 -05004491 if(!validImageSize(level, width, height))
4492 {
4493 return error(GL_INVALID_VALUE);
4494 }
John Bauman66b8ab22014-05-06 15:57:45 -04004495
Nicolas Capensf160b172014-11-26 11:58:23 -05004496 es2::Context *context = es2::getContext();
4497
4498 if(context)
4499 {
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004500 if(context->getClientVersion() < 3)
4501 {
4502 if(internalformat != format)
4503 {
4504 return error(GL_INVALID_OPERATION);
4505 }
4506 }
4507
4508 switch(format)
4509 {
4510 case GL_ALPHA:
4511 case GL_LUMINANCE:
4512 case GL_LUMINANCE_ALPHA:
4513 switch(type)
4514 {
4515 case GL_UNSIGNED_BYTE:
4516 case GL_FLOAT:
4517 case GL_HALF_FLOAT_OES:
4518 break;
4519 default:
4520 return error(GL_INVALID_ENUM);
4521 }
4522 break;
Alexis Hetued306182015-04-02 12:02:28 -04004523 case GL_RED:
4524 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004525 {
Alexis Hetued306182015-04-02 12:02:28 -04004526 case GL_R8:
4527 switch(type)
4528 {
4529 case GL_UNSIGNED_BYTE:
4530 break;
4531 default:
4532 return error(GL_INVALID_ENUM);
4533 }
4534 break;
4535 case GL_R8_SNORM:
4536 switch(type)
4537 {
4538 case GL_BYTE:
4539 break;
4540 default:
4541 return error(GL_INVALID_ENUM);
4542 }
4543 break;
4544 case GL_R16F:
4545 switch(type)
4546 {
4547 case GL_FLOAT:
4548 case GL_HALF_FLOAT:
4549 break;
4550 default:
4551 return error(GL_INVALID_ENUM);
4552 }
4553 break;
4554 case GL_R32F:
4555 switch(type)
4556 {
4557 case GL_FLOAT:
4558 break;
4559 default:
4560 return error(GL_INVALID_ENUM);
4561 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004562 break;
4563 default:
Alexis Hetued306182015-04-02 12:02:28 -04004564 return error(GL_INVALID_VALUE);
4565 }
4566 break;
4567 case GL_RED_INTEGER:
4568 switch(internalformat)
4569 {
4570 case GL_R8UI:
4571 switch(type)
4572 {
4573 case GL_UNSIGNED_BYTE:
4574 break;
4575 default:
4576 return error(GL_INVALID_ENUM);
4577 }
4578 break;
4579 case GL_R8I:
4580 switch(type)
4581 {
4582 case GL_BYTE:
4583 break;
4584 default:
4585 return error(GL_INVALID_ENUM);
4586 }
4587 break;
4588 case GL_R16UI:
4589 switch(type)
4590 {
4591 case GL_UNSIGNED_SHORT:
4592 break;
4593 default:
4594 return error(GL_INVALID_ENUM);
4595 }
4596 break;
4597 case GL_R16I:
4598 switch(type)
4599 {
4600 case GL_SHORT:
4601 break;
4602 default:
4603 return error(GL_INVALID_ENUM);
4604 }
4605 break;
4606 case GL_R32UI:
4607 switch(type)
4608 {
4609 case GL_UNSIGNED_INT:
4610 break;
4611 default:
4612 return error(GL_INVALID_ENUM);
4613 }
4614 break;
4615 case GL_R32I:
4616 switch(type)
4617 {
4618 case GL_INT:
4619 break;
4620 default:
4621 return error(GL_INVALID_ENUM);
4622 }
4623 break;
4624 default:
4625 return error(GL_INVALID_VALUE);
4626 }
4627 break;
4628 case GL_RG_INTEGER:
4629 switch(internalformat)
4630 {
4631 case GL_RG8UI:
4632 switch(type)
4633 {
4634 case GL_UNSIGNED_BYTE:
4635 break;
4636 default:
4637 return error(GL_INVALID_ENUM);
4638 }
4639 break;
4640 case GL_RG8I:
4641 switch(type)
4642 {
4643 case GL_BYTE:
4644 break;
4645 default:
4646 return error(GL_INVALID_ENUM);
4647 }
4648 break;
4649 case GL_RG16UI:
4650 switch(type)
4651 {
4652 case GL_UNSIGNED_SHORT:
4653 break;
4654 default:
4655 return error(GL_INVALID_ENUM);
4656 }
4657 break;
4658 case GL_RG16I:
4659 switch(type)
4660 {
4661 case GL_SHORT:
4662 break;
4663 default:
4664 return error(GL_INVALID_ENUM);
4665 }
4666 break;
4667 case GL_RG32UI:
4668 switch(type)
4669 {
4670 case GL_UNSIGNED_INT:
4671 break;
4672 default:
4673 return error(GL_INVALID_ENUM);
4674 }
4675 break;
4676 case GL_RG32I:
4677 switch(type)
4678 {
4679 case GL_INT:
4680 break;
4681 default:
4682 return error(GL_INVALID_ENUM);
4683 }
4684 break;
4685 default:
4686 return error(GL_INVALID_VALUE);
4687 }
4688 break;
4689 case GL_RGB_INTEGER:
4690 switch(internalformat)
4691 {
4692 case GL_RGB8UI:
4693 switch(type)
4694 {
4695 case GL_UNSIGNED_BYTE:
4696 break;
4697 default:
4698 return error(GL_INVALID_ENUM);
4699 }
4700 break;
4701 case GL_RGB8I:
4702 switch(type)
4703 {
4704 case GL_BYTE:
4705 break;
4706 default:
4707 return error(GL_INVALID_ENUM);
4708 }
4709 break;
4710 case GL_RGB16UI:
4711 switch(type)
4712 {
4713 case GL_UNSIGNED_SHORT:
4714 break;
4715 default:
4716 return error(GL_INVALID_ENUM);
4717 }
4718 break;
4719 case GL_RGB16I:
4720 switch(type)
4721 {
4722 case GL_SHORT:
4723 break;
4724 default:
4725 return error(GL_INVALID_ENUM);
4726 }
4727 break;
4728 case GL_RGB32UI:
4729 switch(type)
4730 {
4731 case GL_UNSIGNED_INT:
4732 break;
4733 default:
4734 return error(GL_INVALID_ENUM);
4735 }
4736 break;
4737 case GL_RGB32I:
4738 switch(type)
4739 {
4740 case GL_INT:
4741 break;
4742 default:
4743 return error(GL_INVALID_ENUM);
4744 }
4745 break;
4746 default:
4747 return error(GL_INVALID_VALUE);
4748 }
4749 break;
4750 case GL_RGBA_INTEGER:
4751 switch(internalformat)
4752 {
4753 case GL_RGBA8UI:
4754 switch(type)
4755 {
4756 case GL_UNSIGNED_BYTE:
4757 break;
4758 default:
4759 return error(GL_INVALID_ENUM);
4760 }
4761 break;
4762 case GL_RGBA8I:
4763 switch(type)
4764 {
4765 case GL_BYTE:
4766 break;
4767 default:
4768 return error(GL_INVALID_ENUM);
4769 }
4770 break;
4771 case GL_RGB10_A2UI:
4772 switch(type)
4773 {
4774 case GL_UNSIGNED_INT_2_10_10_10_REV:
4775 break;
4776 default:
4777 return error(GL_INVALID_ENUM);
4778 }
4779 break;
4780 case GL_RGBA16UI:
4781 switch(type)
4782 {
4783 case GL_UNSIGNED_SHORT:
4784 break;
4785 default:
4786 return error(GL_INVALID_ENUM);
4787 }
4788 break;
4789 case GL_RGBA16I:
4790 switch(type)
4791 {
4792 case GL_SHORT:
4793 break;
4794 default:
4795 return error(GL_INVALID_ENUM);
4796 }
4797 break;
4798 case GL_RGBA32UI:
4799 switch(type)
4800 {
4801 case GL_INT:
4802 break;
4803 default:
4804 return error(GL_INVALID_ENUM);
4805 }
4806 break;
4807 case GL_RGBA32I:
4808 switch(type)
4809 {
4810 case GL_UNSIGNED_INT:
4811 break;
4812 default:
4813 return error(GL_INVALID_ENUM);
4814 }
4815 break;
4816 default:
4817 return error(GL_INVALID_VALUE);
4818 }
4819 break;
4820 case GL_RG:
4821 switch(internalformat)
4822 {
4823 case GL_RG8:
4824 switch(type)
4825 {
4826 case GL_UNSIGNED_BYTE:
4827 break;
4828 default:
4829 return error(GL_INVALID_ENUM);
4830 }
4831 break;
4832 case GL_RG8_SNORM:
4833 switch(type)
4834 {
4835 case GL_BYTE:
4836 break;
4837 default:
4838 return error(GL_INVALID_ENUM);
4839 }
4840 break;
4841 case GL_RG16F:
4842 switch(type)
4843 {
4844 case GL_FLOAT:
4845 case GL_HALF_FLOAT:
4846 break;
4847 default:
4848 return error(GL_INVALID_ENUM);
4849 }
4850 break;
4851 case GL_RG32F:
4852 switch(type)
4853 {
4854 case GL_FLOAT:
4855 break;
4856 default:
4857 return error(GL_INVALID_ENUM);
4858 }
4859 break;
4860 default:
4861 return error(GL_INVALID_VALUE);
4862 }
4863 break;
4864 case GL_RGB:
4865 switch(internalformat)
4866 {
4867 case GL_RGB:
4868 switch(type)
4869 {
4870 case GL_UNSIGNED_BYTE:
4871 case GL_UNSIGNED_SHORT_5_6_5:
4872 case GL_FLOAT:
4873 case GL_HALF_FLOAT_OES:
4874 break;
4875 default:
4876 return error(GL_INVALID_ENUM);
4877 }
4878 break;
4879 case GL_RGB8:
4880 switch(type)
4881 {
4882 case GL_UNSIGNED_BYTE:
4883 break;
4884 default:
4885 return error(GL_INVALID_ENUM);
4886 }
4887 break;
4888 case GL_SRGB8:
4889 switch(type)
4890 {
4891 case GL_UNSIGNED_BYTE:
4892 break;
4893 default:
4894 return error(GL_INVALID_ENUM);
4895 }
4896 break;
4897 case GL_RGB565:
4898 switch(type)
4899 {
4900 case GL_UNSIGNED_BYTE:
4901 case GL_UNSIGNED_SHORT_5_6_5:
4902 break;
4903 default:
4904 return error(GL_INVALID_ENUM);
4905 }
4906 break;
4907 case GL_RGB8_SNORM:
4908 switch(type)
4909 {
4910 case GL_BYTE:
4911 break;
4912 default:
4913 return error(GL_INVALID_ENUM);
4914 }
4915 break;
4916 case GL_R11F_G11F_B10F:
4917 switch(type)
4918 {
4919 case GL_UNSIGNED_INT_10F_11F_11F_REV:
4920 case GL_FLOAT:
4921 case GL_HALF_FLOAT:
4922 break;
4923 default:
4924 return error(GL_INVALID_ENUM);
4925 }
4926 break;
4927 case GL_RGB9_E5:
4928 switch(type)
4929 {
4930 case GL_UNSIGNED_INT_5_9_9_9_REV:
4931 case GL_FLOAT:
4932 case GL_HALF_FLOAT:
4933 break;
4934 default:
4935 return error(GL_INVALID_ENUM);
4936 }
4937 break;
4938 case GL_RGB16F:
4939 switch(type)
4940 {
4941 case GL_FLOAT:
4942 case GL_HALF_FLOAT:
4943 break;
4944 default:
4945 return error(GL_INVALID_ENUM);
4946 }
4947 break;
4948 case GL_RGB32F:
4949 switch(type)
4950 {
4951 case GL_FLOAT:
4952 break;
4953 default:
4954 return error(GL_INVALID_ENUM);
4955 }
4956 break;
4957 default:
4958 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004959 }
4960 break;
4961 case GL_RGBA:
Alexis Hetued306182015-04-02 12:02:28 -04004962 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05004963 {
Alexis Hetued306182015-04-02 12:02:28 -04004964 case GL_RGBA:
4965 switch(type)
4966 {
4967 case GL_UNSIGNED_BYTE:
4968 case GL_UNSIGNED_SHORT_4_4_4_4:
4969 case GL_UNSIGNED_SHORT_5_5_5_1:
4970 case GL_FLOAT:
4971 case GL_HALF_FLOAT_OES:
4972 break;
4973 default:
4974 return error(GL_INVALID_ENUM);
4975 }
4976 break;
4977 case GL_RGBA8:
4978 switch(type)
4979 {
4980 case GL_UNSIGNED_BYTE:
4981 break;
4982 default:
4983 return error(GL_INVALID_ENUM);
4984 }
4985 break;
4986 case GL_SRGB8_ALPHA8:
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_RGB5_A1:
4996 switch(type)
4997 {
4998 case GL_UNSIGNED_BYTE:
4999 case GL_UNSIGNED_SHORT_5_5_5_1:
5000 case GL_UNSIGNED_INT_2_10_10_10_REV:
5001 break;
5002 default:
5003 return error(GL_INVALID_ENUM);
5004 }
5005 break;
5006 case GL_RGBA8_SNORM:
5007 switch(type)
5008 {
5009 case GL_BYTE:
5010 break;
5011 default:
5012 return error(GL_INVALID_ENUM);
5013 }
5014 break;
5015 case GL_RGBA4:
5016 switch(type)
5017 {
5018 case GL_UNSIGNED_BYTE:
5019 case GL_UNSIGNED_SHORT_4_4_4_4:
5020 break;
5021 default:
5022 return error(GL_INVALID_ENUM);
5023 }
5024 break;
5025 case GL_RGB10_A2:
5026 switch(type)
5027 {
5028 case GL_UNSIGNED_INT_2_10_10_10_REV:
5029 break;
5030 default:
5031 return error(GL_INVALID_ENUM);
5032 }
5033 break;
5034 case GL_RGBA16F:
5035 switch(type)
5036 {
5037 case GL_FLOAT:
5038 case GL_HALF_FLOAT:
5039 break;
5040 default:
5041 return error(GL_INVALID_ENUM);
5042 }
5043 break;
5044 case GL_RGBA32F:
5045 switch(type)
5046 {
5047 case GL_FLOAT:
5048 break;
5049 default:
5050 return error(GL_INVALID_ENUM);
5051 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005052 break;
5053 default:
Alexis Hetued306182015-04-02 12:02:28 -04005054 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005055 }
5056 break;
5057 case GL_BGRA_EXT:
5058 switch(type)
5059 {
5060 case GL_UNSIGNED_BYTE:
5061 break;
5062 default:
5063 return error(GL_INVALID_ENUM);
5064 }
5065 break;
5066 case GL_ETC1_RGB8_OES:
5067 return error(GL_INVALID_OPERATION);
5068 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5069 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5070 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5071 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5072 if(S3TC_SUPPORT)
5073 {
5074 return error(GL_INVALID_OPERATION);
5075 }
5076 else
5077 {
5078 return error(GL_INVALID_ENUM);
5079 }
5080 case GL_DEPTH_COMPONENT:
Alexis Hetued306182015-04-02 12:02:28 -04005081 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005082 {
Alexis Hetued306182015-04-02 12:02:28 -04005083 case GL_DEPTH_COMPONENT:
5084 case GL_DEPTH_COMPONENT16:
5085 switch(type)
5086 {
5087 case GL_UNSIGNED_SHORT:
5088 case GL_UNSIGNED_INT:
5089 break;
5090 default:
5091 return error(GL_INVALID_ENUM);
5092 }
5093 break;
5094 case GL_DEPTH_COMPONENT24:
5095 switch(type)
5096 {
5097 case GL_UNSIGNED_INT:
5098 break;
5099 default:
5100 return error(GL_INVALID_ENUM);
5101 }
5102 break;
5103 case GL_DEPTH_COMPONENT32F:
5104 switch(type)
5105 {
5106 case GL_UNSIGNED_INT:
5107 break;
5108 default:
5109 return error(GL_INVALID_ENUM);
5110 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005111 break;
5112 default:
Alexis Hetued306182015-04-02 12:02:28 -04005113 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005114 }
5115 break;
5116 case GL_DEPTH_STENCIL_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005117 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005118 {
Alexis Hetued306182015-04-02 12:02:28 -04005119 case GL_DEPTH_STENCIL_OES:
5120 case GL_DEPTH24_STENCIL8:
5121 switch(type)
5122 {
5123 case GL_UNSIGNED_INT_24_8_OES:
5124 break;
5125 default:
5126 return error(GL_INVALID_ENUM);
5127 }
5128 break;
5129 case GL_DEPTH32F_STENCIL8:
5130 switch(type)
5131 {
5132 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
5133 break;
5134 default:
5135 return error(GL_INVALID_ENUM);
5136 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005137 break;
5138 default:
Alexis Hetued306182015-04-02 12:02:28 -04005139 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005140 }
5141 break;
5142 default:
5143 return error(GL_INVALID_VALUE);
5144 }
5145
5146 if(border != 0)
5147 {
5148 return error(GL_INVALID_VALUE);
5149 }
5150
Nicolas Capensf160b172014-11-26 11:58:23 -05005151 switch(target)
5152 {
Nicolas Capens22658242014-11-29 00:31:41 -05005153 case GL_TEXTURE_2D:
Nicolas Capensf160b172014-11-26 11:58:23 -05005154 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
5155 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
John Bauman66b8ab22014-05-06 15:57:45 -04005156 {
Nicolas Capensf160b172014-11-26 11:58:23 -05005157 return error(GL_INVALID_VALUE);
John Bauman66b8ab22014-05-06 15:57:45 -04005158 }
5159 break;
Nicolas Capens22658242014-11-29 00:31:41 -05005160 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5161 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5162 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5163 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5164 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5165 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
Nicolas Capensf160b172014-11-26 11:58:23 -05005166 if(width != height)
John Bauman66b8ab22014-05-06 15:57:45 -04005167 {
Nicolas Capensf160b172014-11-26 11:58:23 -05005168 return error(GL_INVALID_VALUE);
5169 }
5170
5171 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
5172 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
5173 {
5174 return error(GL_INVALID_VALUE);
John Bauman66b8ab22014-05-06 15:57:45 -04005175 }
5176 break;
Nicolas Capens22658242014-11-29 00:31:41 -05005177 default:
Nicolas Capensf160b172014-11-26 11:58:23 -05005178 return error(GL_INVALID_ENUM);
5179 }
John Bauman66b8ab22014-05-06 15:57:45 -04005180
Nicolas Capensf160b172014-11-26 11:58:23 -05005181 if(target == GL_TEXTURE_2D)
5182 {
5183 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04005184
Nicolas Capensf160b172014-11-26 11:58:23 -05005185 if(!texture)
5186 {
5187 return error(GL_INVALID_OPERATION);
5188 }
John Bauman66b8ab22014-05-06 15:57:45 -04005189
Nicolas Capensf160b172014-11-26 11:58:23 -05005190 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
5191 }
5192 else
5193 {
5194 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04005195
Nicolas Capensf160b172014-11-26 11:58:23 -05005196 if(!texture)
5197 {
5198 return error(GL_INVALID_OPERATION);
5199 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05005200
Nicolas Capensf160b172014-11-26 11:58:23 -05005201 texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
5202 }
5203 }
John Bauman66b8ab22014-05-06 15:57:45 -04005204}
5205
5206void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5207{
Nicolas Capensf160b172014-11-26 11:58:23 -05005208 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04005209
Nicolas Capensf160b172014-11-26 11:58:23 -05005210 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005211
Nicolas Capensf160b172014-11-26 11:58:23 -05005212 if(context)
5213 {
5214 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04005215
Alexis Hetued306182015-04-02 12:02:28 -04005216 egl::GLint clientVersion = context->getClientVersion();
5217
Nicolas Capensf160b172014-11-26 11:58:23 -05005218 switch(target)
5219 {
5220 case GL_TEXTURE_2D:
5221 texture = context->getTexture2D();
5222 break;
Alexis Hetued306182015-04-02 12:02:28 -04005223 case GL_TEXTURE_2D_ARRAY:
5224 if(clientVersion < 3)
5225 {
5226 return error(GL_INVALID_ENUM);
5227 }
5228 else
5229 {
5230 UNIMPLEMENTED();
5231 texture = context->getTexture3D();
5232 break;
5233 }
Alexis Hetub027aa92015-01-19 15:56:12 -05005234 case GL_TEXTURE_3D_OES:
5235 texture = context->getTexture3D();
5236 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005237 case GL_TEXTURE_CUBE_MAP:
5238 texture = context->getTextureCubeMap();
5239 break;
5240 case GL_TEXTURE_EXTERNAL_OES:
5241 texture = context->getTextureExternal();
5242 break;
5243 default:
5244 return error(GL_INVALID_ENUM);
5245 }
John Bauman66b8ab22014-05-06 15:57:45 -04005246
Nicolas Capensf160b172014-11-26 11:58:23 -05005247 switch(pname)
5248 {
5249 case GL_TEXTURE_WRAP_S:
5250 if(!texture->setWrapS((GLenum)param))
5251 {
5252 return error(GL_INVALID_ENUM);
5253 }
5254 break;
5255 case GL_TEXTURE_WRAP_T:
5256 if(!texture->setWrapT((GLenum)param))
5257 {
5258 return error(GL_INVALID_ENUM);
5259 }
5260 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05005261 case GL_TEXTURE_WRAP_R_OES:
5262 if(!texture->setWrapR((GLenum)param))
5263 {
5264 return error(GL_INVALID_ENUM);
5265 }
5266 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005267 case GL_TEXTURE_MIN_FILTER:
5268 if(!texture->setMinFilter((GLenum)param))
5269 {
5270 return error(GL_INVALID_ENUM);
5271 }
5272 break;
5273 case GL_TEXTURE_MAG_FILTER:
5274 if(!texture->setMagFilter((GLenum)param))
5275 {
5276 return error(GL_INVALID_ENUM);
5277 }
5278 break;
5279 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5280 if(!texture->setMaxAnisotropy(param))
5281 {
5282 return error(GL_INVALID_VALUE);
5283 }
5284 break;
Alexis Hetued306182015-04-02 12:02:28 -04005285 case GL_TEXTURE_BASE_LEVEL:
5286 if(clientVersion < 3 || !texture->setBaseLevel((GLint)param))
5287 {
5288 return error(GL_INVALID_VALUE);
5289 }
5290 break;
5291 case GL_TEXTURE_COMPARE_FUNC:
5292 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5293 {
5294 return error(GL_INVALID_VALUE);
5295 }
5296 break;
5297 case GL_TEXTURE_COMPARE_MODE:
5298 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5299 {
5300 return error(GL_INVALID_VALUE);
5301 }
5302 break;
5303 case GL_TEXTURE_IMMUTABLE_FORMAT:
5304 if(clientVersion < 3 || !texture->setCompareMode((GLboolean)param))
5305 {
5306 return error(GL_INVALID_VALUE);
5307 }
5308 break;
5309 case GL_TEXTURE_MAX_LEVEL:
5310 if(clientVersion < 3 || !texture->setMaxLevel((GLint)param))
5311 {
5312 return error(GL_INVALID_VALUE);
5313 }
5314 break;
5315 case GL_TEXTURE_MAX_LOD:
5316 if(clientVersion < 3 || !texture->setMaxLOD(param))
5317 {
5318 return error(GL_INVALID_VALUE);
5319 }
5320 break;
5321 case GL_TEXTURE_MIN_LOD:
5322 if(clientVersion < 3 || !texture->setMinLOD(param))
5323 {
5324 return error(GL_INVALID_VALUE);
5325 }
5326 break;
5327 case GL_TEXTURE_SWIZZLE_R:
5328 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5329 {
5330 return error(GL_INVALID_VALUE);
5331 }
5332 break;
5333 case GL_TEXTURE_SWIZZLE_G:
5334 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5335 {
5336 return error(GL_INVALID_VALUE);
5337 }
5338 break;
5339 case GL_TEXTURE_SWIZZLE_B:
5340 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5341 {
5342 return error(GL_INVALID_VALUE);
5343 }
5344 break;
5345 case GL_TEXTURE_SWIZZLE_A:
5346 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5347 {
5348 return error(GL_INVALID_VALUE);
5349 }
5350 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005351 default:
5352 return error(GL_INVALID_ENUM);
5353 }
5354 }
John Bauman66b8ab22014-05-06 15:57:45 -04005355}
5356
5357void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5358{
Nicolas Capensf160b172014-11-26 11:58:23 -05005359 glTexParameterf(target, pname, *params);
John Bauman66b8ab22014-05-06 15:57:45 -04005360}
5361
5362void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
5363{
Nicolas Capensf160b172014-11-26 11:58:23 -05005364 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04005365
Nicolas Capensf160b172014-11-26 11:58:23 -05005366 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005367
Nicolas Capensf160b172014-11-26 11:58:23 -05005368 if(context)
5369 {
5370 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04005371
Alexis Hetued306182015-04-02 12:02:28 -04005372 egl::GLint clientVersion = context->getClientVersion();
5373
Nicolas Capensf160b172014-11-26 11:58:23 -05005374 switch(target)
5375 {
5376 case GL_TEXTURE_2D:
5377 texture = context->getTexture2D();
5378 break;
Alexis Hetued306182015-04-02 12:02:28 -04005379 case GL_TEXTURE_2D_ARRAY:
5380 if(clientVersion < 3)
5381 {
5382 return error(GL_INVALID_ENUM);
5383 }
5384 else
5385 {
5386 UNIMPLEMENTED();
5387 texture = context->getTexture3D();
5388 break;
5389 }
Alexis Hetub027aa92015-01-19 15:56:12 -05005390 case GL_TEXTURE_3D_OES:
5391 texture = context->getTexture3D();
5392 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005393 case GL_TEXTURE_CUBE_MAP:
5394 texture = context->getTextureCubeMap();
5395 break;
5396 case GL_TEXTURE_EXTERNAL_OES:
Alexis Hetuf7be67f2015-02-11 16:11:07 -05005397 texture = context->getTextureExternal();
5398 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005399 default:
5400 return error(GL_INVALID_ENUM);
5401 }
John Bauman66b8ab22014-05-06 15:57:45 -04005402
Nicolas Capensf160b172014-11-26 11:58:23 -05005403 switch(pname)
5404 {
5405 case GL_TEXTURE_WRAP_S:
5406 if(!texture->setWrapS((GLenum)param))
5407 {
5408 return error(GL_INVALID_ENUM);
5409 }
5410 break;
5411 case GL_TEXTURE_WRAP_T:
5412 if(!texture->setWrapT((GLenum)param))
5413 {
5414 return error(GL_INVALID_ENUM);
5415 }
5416 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05005417 case GL_TEXTURE_WRAP_R_OES:
5418 if(!texture->setWrapR((GLenum)param))
5419 {
5420 return error(GL_INVALID_ENUM);
5421 }
5422 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005423 case GL_TEXTURE_MIN_FILTER:
5424 if(!texture->setMinFilter((GLenum)param))
5425 {
5426 return error(GL_INVALID_ENUM);
5427 }
5428 break;
5429 case GL_TEXTURE_MAG_FILTER:
5430 if(!texture->setMagFilter((GLenum)param))
5431 {
5432 return error(GL_INVALID_ENUM);
5433 }
5434 break;
5435 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5436 if(!texture->setMaxAnisotropy((GLfloat)param))
5437 {
5438 return error(GL_INVALID_VALUE);
5439 }
5440 break;
Alexis Hetued306182015-04-02 12:02:28 -04005441 case GL_TEXTURE_BASE_LEVEL:
5442 if(clientVersion < 3 || !texture->setBaseLevel(param))
5443 {
5444 return error(GL_INVALID_VALUE);
5445 }
5446 break;
5447 case GL_TEXTURE_COMPARE_FUNC:
5448 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5449 {
5450 return error(GL_INVALID_VALUE);
5451 }
5452 break;
5453 case GL_TEXTURE_COMPARE_MODE:
5454 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5455 {
5456 return error(GL_INVALID_VALUE);
5457 }
5458 case GL_TEXTURE_IMMUTABLE_FORMAT:
5459 if(clientVersion < 3 || !texture->setCompareMode((GLboolean)param))
5460 {
5461 return error(GL_INVALID_VALUE);
5462 }
5463 break;
5464 case GL_TEXTURE_MAX_LEVEL:
5465 if(clientVersion < 3 || !texture->setMaxLevel(param))
5466 {
5467 return error(GL_INVALID_VALUE);
5468 }
5469 break;
5470 case GL_TEXTURE_MAX_LOD:
5471 if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
5472 {
5473 return error(GL_INVALID_VALUE);
5474 }
5475 break;
5476 case GL_TEXTURE_MIN_LOD:
5477 if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
5478 {
5479 return error(GL_INVALID_VALUE);
5480 }
5481 break;
5482 case GL_TEXTURE_SWIZZLE_R:
5483 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5484 {
5485 return error(GL_INVALID_VALUE);
5486 }
5487 break;
5488 case GL_TEXTURE_SWIZZLE_G:
5489 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5490 {
5491 return error(GL_INVALID_VALUE);
5492 }
5493 break;
5494 case GL_TEXTURE_SWIZZLE_B:
5495 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5496 {
5497 return error(GL_INVALID_VALUE);
5498 }
5499 break;
5500 case GL_TEXTURE_SWIZZLE_A:
5501 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5502 {
5503 return error(GL_INVALID_VALUE);
5504 }
5505 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005506 default:
5507 return error(GL_INVALID_ENUM);
5508 }
5509 }
John Bauman66b8ab22014-05-06 15:57:45 -04005510}
5511
5512void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5513{
Nicolas Capensf160b172014-11-26 11:58:23 -05005514 glTexParameteri(target, pname, *params);
John Bauman66b8ab22014-05-06 15:57:45 -04005515}
5516
5517void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Nicolas Capensf160b172014-11-26 11:58:23 -05005518 GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04005519{
Nicolas Capensf160b172014-11-26 11:58:23 -05005520 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
5521 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
5522 "const GLvoid* pixels = 0x%0.8p)",
5523 target, level, xoffset, yoffset, width, height, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04005524
Nicolas Capensf160b172014-11-26 11:58:23 -05005525 if(!es2::IsTextureTarget(target))
5526 {
5527 return error(GL_INVALID_ENUM);
5528 }
John Bauman66b8ab22014-05-06 15:57:45 -04005529
Nicolas Capensf160b172014-11-26 11:58:23 -05005530 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
5531 {
5532 return error(GL_INVALID_VALUE);
5533 }
John Bauman66b8ab22014-05-06 15:57:45 -04005534
Nicolas Capensf160b172014-11-26 11:58:23 -05005535 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5536 {
5537 return error(GL_INVALID_VALUE);
5538 }
John Bauman66b8ab22014-05-06 15:57:45 -04005539
Nicolas Capensf160b172014-11-26 11:58:23 -05005540 if(!es2::CheckTextureFormatType(format, type))
5541 {
5542 return error(GL_INVALID_ENUM);
5543 }
John Bauman66b8ab22014-05-06 15:57:45 -04005544
Nicolas Capensf160b172014-11-26 11:58:23 -05005545 if(width == 0 || height == 0 || pixels == NULL)
5546 {
5547 return;
5548 }
John Bauman66b8ab22014-05-06 15:57:45 -04005549
Nicolas Capensf160b172014-11-26 11:58:23 -05005550 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005551
Nicolas Capensf160b172014-11-26 11:58:23 -05005552 if(context)
5553 {
Alexis Hetub027aa92015-01-19 15:56:12 -05005554 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05005555 {
5556 return error(GL_INVALID_VALUE);
5557 }
John Bauman66b8ab22014-05-06 15:57:45 -04005558
Nicolas Capensf160b172014-11-26 11:58:23 -05005559 if(target == GL_TEXTURE_2D)
5560 {
5561 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04005562
Nicolas Capensf160b172014-11-26 11:58:23 -05005563 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
5564 {
5565 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
5566 }
5567 }
5568 else if(es2::IsCubemapTextureTarget(target))
5569 {
5570 es2::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens08e90f02014-11-21 12:49:12 -05005571
Nicolas Capensf160b172014-11-26 11:58:23 -05005572 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
5573 {
5574 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
5575 }
5576 }
5577 else
5578 {
5579 UNREACHABLE();
5580 }
5581 }
John Bauman66b8ab22014-05-06 15:57:45 -04005582}
5583
5584void GL_APIENTRY glUniform1f(GLint location, GLfloat x)
5585{
Nicolas Capensf160b172014-11-26 11:58:23 -05005586 glUniform1fv(location, 1, &x);
John Bauman66b8ab22014-05-06 15:57:45 -04005587}
5588
5589void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5590{
Nicolas Capensf160b172014-11-26 11:58:23 -05005591 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005592
Nicolas Capensf160b172014-11-26 11:58:23 -05005593 if(count < 0)
5594 {
5595 return error(GL_INVALID_VALUE);
5596 }
John Bauman66b8ab22014-05-06 15:57:45 -04005597
Nicolas Capensf160b172014-11-26 11:58:23 -05005598 if(location == -1)
5599 {
5600 return;
5601 }
John Bauman66b8ab22014-05-06 15:57:45 -04005602
Nicolas Capensf160b172014-11-26 11:58:23 -05005603 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005604
Nicolas Capensf160b172014-11-26 11:58:23 -05005605 if(context)
5606 {
5607 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005608
Nicolas Capensf160b172014-11-26 11:58:23 -05005609 if(!program)
5610 {
5611 return error(GL_INVALID_OPERATION);
5612 }
John Bauman66b8ab22014-05-06 15:57:45 -04005613
Nicolas Capensf160b172014-11-26 11:58:23 -05005614 if(!program->setUniform1fv(location, count, v))
5615 {
5616 return error(GL_INVALID_OPERATION);
5617 }
5618 }
John Bauman66b8ab22014-05-06 15:57:45 -04005619}
5620
5621void GL_APIENTRY glUniform1i(GLint location, GLint x)
5622{
Nicolas Capensf160b172014-11-26 11:58:23 -05005623 glUniform1iv(location, 1, &x);
John Bauman66b8ab22014-05-06 15:57:45 -04005624}
5625
5626void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
5627{
Nicolas Capensf160b172014-11-26 11:58:23 -05005628 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005629
Nicolas Capensf160b172014-11-26 11:58:23 -05005630 if(count < 0)
5631 {
5632 return error(GL_INVALID_VALUE);
5633 }
John Bauman66b8ab22014-05-06 15:57:45 -04005634
Nicolas Capensf160b172014-11-26 11:58:23 -05005635 if(location == -1)
5636 {
5637 return;
5638 }
John Bauman66b8ab22014-05-06 15:57:45 -04005639
Nicolas Capensf160b172014-11-26 11:58:23 -05005640 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005641
Nicolas Capensf160b172014-11-26 11:58:23 -05005642 if(context)
5643 {
5644 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005645
Nicolas Capensf160b172014-11-26 11:58:23 -05005646 if(!program)
5647 {
5648 return error(GL_INVALID_OPERATION);
5649 }
John Bauman66b8ab22014-05-06 15:57:45 -04005650
Nicolas Capensf160b172014-11-26 11:58:23 -05005651 if(!program->setUniform1iv(location, count, v))
5652 {
5653 return error(GL_INVALID_OPERATION);
5654 }
5655 }
John Bauman66b8ab22014-05-06 15:57:45 -04005656}
5657
5658void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
5659{
Nicolas Capensf160b172014-11-26 11:58:23 -05005660 GLfloat xy[2] = {x, y};
John Bauman66b8ab22014-05-06 15:57:45 -04005661
Nicolas Capensf160b172014-11-26 11:58:23 -05005662 glUniform2fv(location, 1, (GLfloat*)&xy);
John Bauman66b8ab22014-05-06 15:57:45 -04005663}
5664
5665void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5666{
Nicolas Capensf160b172014-11-26 11:58:23 -05005667 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005668
Nicolas Capensf160b172014-11-26 11:58:23 -05005669 if(count < 0)
5670 {
5671 return error(GL_INVALID_VALUE);
5672 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05005673
Nicolas Capensf160b172014-11-26 11:58:23 -05005674 if(location == -1)
5675 {
5676 return;
5677 }
John Bauman66b8ab22014-05-06 15:57:45 -04005678
Nicolas Capensf160b172014-11-26 11:58:23 -05005679 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005680
Nicolas Capensf160b172014-11-26 11:58:23 -05005681 if(context)
5682 {
5683 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005684
Nicolas Capensf160b172014-11-26 11:58:23 -05005685 if(!program)
5686 {
5687 return error(GL_INVALID_OPERATION);
5688 }
John Bauman66b8ab22014-05-06 15:57:45 -04005689
Nicolas Capensf160b172014-11-26 11:58:23 -05005690 if(!program->setUniform2fv(location, count, v))
5691 {
5692 return error(GL_INVALID_OPERATION);
5693 }
5694 }
John Bauman66b8ab22014-05-06 15:57:45 -04005695}
5696
5697void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y)
5698{
Nicolas Capensf160b172014-11-26 11:58:23 -05005699 GLint xy[4] = {x, y};
John Bauman66b8ab22014-05-06 15:57:45 -04005700
Nicolas Capensf160b172014-11-26 11:58:23 -05005701 glUniform2iv(location, 1, (GLint*)&xy);
John Bauman66b8ab22014-05-06 15:57:45 -04005702}
5703
5704void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
5705{
Nicolas Capensf160b172014-11-26 11:58:23 -05005706 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005707
Nicolas Capensf160b172014-11-26 11:58:23 -05005708 if(count < 0)
5709 {
5710 return error(GL_INVALID_VALUE);
5711 }
John Bauman66b8ab22014-05-06 15:57:45 -04005712
Nicolas Capensf160b172014-11-26 11:58:23 -05005713 if(location == -1)
5714 {
5715 return;
5716 }
John Bauman66b8ab22014-05-06 15:57:45 -04005717
Nicolas Capensf160b172014-11-26 11:58:23 -05005718 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005719
Nicolas Capensf160b172014-11-26 11:58:23 -05005720 if(context)
5721 {
5722 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005723
Nicolas Capensf160b172014-11-26 11:58:23 -05005724 if(!program)
5725 {
5726 return error(GL_INVALID_OPERATION);
5727 }
John Bauman66b8ab22014-05-06 15:57:45 -04005728
Nicolas Capensf160b172014-11-26 11:58:23 -05005729 if(!program->setUniform2iv(location, count, v))
5730 {
5731 return error(GL_INVALID_OPERATION);
5732 }
5733 }
John Bauman66b8ab22014-05-06 15:57:45 -04005734}
5735
5736void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5737{
Nicolas Capensf160b172014-11-26 11:58:23 -05005738 GLfloat xyz[3] = {x, y, z};
John Bauman66b8ab22014-05-06 15:57:45 -04005739
Nicolas Capensf160b172014-11-26 11:58:23 -05005740 glUniform3fv(location, 1, (GLfloat*)&xyz);
John Bauman66b8ab22014-05-06 15:57:45 -04005741}
5742
5743void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5744{
Nicolas Capensf160b172014-11-26 11:58:23 -05005745 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005746
Nicolas Capensf160b172014-11-26 11:58:23 -05005747 if(count < 0)
5748 {
5749 return error(GL_INVALID_VALUE);
5750 }
John Bauman66b8ab22014-05-06 15:57:45 -04005751
Nicolas Capensf160b172014-11-26 11:58:23 -05005752 if(location == -1)
5753 {
5754 return;
5755 }
John Bauman66b8ab22014-05-06 15:57:45 -04005756
Nicolas Capensf160b172014-11-26 11:58:23 -05005757 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005758
Nicolas Capensf160b172014-11-26 11:58:23 -05005759 if(context)
5760 {
5761 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005762
Nicolas Capensf160b172014-11-26 11:58:23 -05005763 if(!program)
5764 {
5765 return error(GL_INVALID_OPERATION);
5766 }
John Bauman66b8ab22014-05-06 15:57:45 -04005767
Nicolas Capensf160b172014-11-26 11:58:23 -05005768 if(!program->setUniform3fv(location, count, v))
5769 {
5770 return error(GL_INVALID_OPERATION);
5771 }
5772 }
John Bauman66b8ab22014-05-06 15:57:45 -04005773}
5774
5775void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
5776{
Nicolas Capensf160b172014-11-26 11:58:23 -05005777 GLint xyz[3] = {x, y, z};
John Bauman66b8ab22014-05-06 15:57:45 -04005778
Nicolas Capensf160b172014-11-26 11:58:23 -05005779 glUniform3iv(location, 1, (GLint*)&xyz);
John Bauman66b8ab22014-05-06 15:57:45 -04005780}
5781
5782void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
5783{
Nicolas Capensf160b172014-11-26 11:58:23 -05005784 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005785
Nicolas Capensf160b172014-11-26 11:58:23 -05005786 if(count < 0)
5787 {
5788 return error(GL_INVALID_VALUE);
5789 }
John Bauman66b8ab22014-05-06 15:57:45 -04005790
Nicolas Capensf160b172014-11-26 11:58:23 -05005791 if(location == -1)
5792 {
5793 return;
5794 }
John Bauman66b8ab22014-05-06 15:57:45 -04005795
Nicolas Capensf160b172014-11-26 11:58:23 -05005796 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005797
Nicolas Capensf160b172014-11-26 11:58:23 -05005798 if(context)
5799 {
5800 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005801
Nicolas Capensf160b172014-11-26 11:58:23 -05005802 if(!program)
5803 {
5804 return error(GL_INVALID_OPERATION);
5805 }
John Bauman66b8ab22014-05-06 15:57:45 -04005806
Nicolas Capensf160b172014-11-26 11:58:23 -05005807 if(!program->setUniform3iv(location, count, v))
5808 {
5809 return error(GL_INVALID_OPERATION);
5810 }
5811 }
John Bauman66b8ab22014-05-06 15:57:45 -04005812}
5813
5814void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5815{
Nicolas Capensf160b172014-11-26 11:58:23 -05005816 GLfloat xyzw[4] = {x, y, z, w};
John Bauman66b8ab22014-05-06 15:57:45 -04005817
Nicolas Capensf160b172014-11-26 11:58:23 -05005818 glUniform4fv(location, 1, (GLfloat*)&xyzw);
John Bauman66b8ab22014-05-06 15:57:45 -04005819}
5820
5821void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5822{
Nicolas Capensf160b172014-11-26 11:58:23 -05005823 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005824
Nicolas Capensf160b172014-11-26 11:58:23 -05005825 if(count < 0)
5826 {
5827 return error(GL_INVALID_VALUE);
5828 }
John Bauman66b8ab22014-05-06 15:57:45 -04005829
Nicolas Capensf160b172014-11-26 11:58:23 -05005830 if(location == -1)
5831 {
5832 return;
5833 }
John Bauman66b8ab22014-05-06 15:57:45 -04005834
Nicolas Capensf160b172014-11-26 11:58:23 -05005835 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005836
Nicolas Capensf160b172014-11-26 11:58:23 -05005837 if(context)
5838 {
5839 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005840
Nicolas Capensf160b172014-11-26 11:58:23 -05005841 if(!program)
5842 {
5843 return error(GL_INVALID_OPERATION);
5844 }
John Bauman66b8ab22014-05-06 15:57:45 -04005845
Nicolas Capensf160b172014-11-26 11:58:23 -05005846 if(!program->setUniform4fv(location, count, v))
5847 {
5848 return error(GL_INVALID_OPERATION);
5849 }
5850 }
John Bauman66b8ab22014-05-06 15:57:45 -04005851}
5852
5853void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5854{
Nicolas Capensf160b172014-11-26 11:58:23 -05005855 GLint xyzw[4] = {x, y, z, w};
John Bauman66b8ab22014-05-06 15:57:45 -04005856
Nicolas Capensf160b172014-11-26 11:58:23 -05005857 glUniform4iv(location, 1, (GLint*)&xyzw);
John Bauman66b8ab22014-05-06 15:57:45 -04005858}
5859
5860void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
5861{
Nicolas Capensf160b172014-11-26 11:58:23 -05005862 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04005863
Nicolas Capensf160b172014-11-26 11:58:23 -05005864 if(count < 0)
5865 {
5866 return error(GL_INVALID_VALUE);
5867 }
John Bauman66b8ab22014-05-06 15:57:45 -04005868
Nicolas Capensf160b172014-11-26 11:58:23 -05005869 if(location == -1)
5870 {
5871 return;
5872 }
John Bauman66b8ab22014-05-06 15:57:45 -04005873
Nicolas Capensf160b172014-11-26 11:58:23 -05005874 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005875
Nicolas Capensf160b172014-11-26 11:58:23 -05005876 if(context)
5877 {
5878 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005879
Nicolas Capensf160b172014-11-26 11:58:23 -05005880 if(!program)
5881 {
5882 return error(GL_INVALID_OPERATION);
5883 }
John Bauman66b8ab22014-05-06 15:57:45 -04005884
Nicolas Capensf160b172014-11-26 11:58:23 -05005885 if(!program->setUniform4iv(location, count, v))
5886 {
5887 return error(GL_INVALID_OPERATION);
5888 }
5889 }
John Bauman66b8ab22014-05-06 15:57:45 -04005890}
5891
5892void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5893{
Nicolas Capensf160b172014-11-26 11:58:23 -05005894 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5895 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04005896
Nicolas Capensf160b172014-11-26 11:58:23 -05005897 if(count < 0 || transpose != GL_FALSE)
5898 {
5899 return error(GL_INVALID_VALUE);
5900 }
John Bauman66b8ab22014-05-06 15:57:45 -04005901
Nicolas Capensf160b172014-11-26 11:58:23 -05005902 if(location == -1)
5903 {
5904 return;
5905 }
John Bauman66b8ab22014-05-06 15:57:45 -04005906
Nicolas Capensf160b172014-11-26 11:58:23 -05005907 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005908
Nicolas Capensf160b172014-11-26 11:58:23 -05005909 if(context)
5910 {
5911 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005912
Nicolas Capensf160b172014-11-26 11:58:23 -05005913 if(!program)
5914 {
5915 return error(GL_INVALID_OPERATION);
5916 }
John Bauman66b8ab22014-05-06 15:57:45 -04005917
Nicolas Capensf160b172014-11-26 11:58:23 -05005918 if(!program->setUniformMatrix2fv(location, count, value))
5919 {
5920 return error(GL_INVALID_OPERATION);
5921 }
5922 }
John Bauman66b8ab22014-05-06 15:57:45 -04005923}
5924
5925void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5926{
Nicolas Capensf160b172014-11-26 11:58:23 -05005927 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5928 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04005929
Nicolas Capensf160b172014-11-26 11:58:23 -05005930 if(count < 0 || transpose != GL_FALSE)
5931 {
5932 return error(GL_INVALID_VALUE);
5933 }
John Bauman66b8ab22014-05-06 15:57:45 -04005934
Nicolas Capensf160b172014-11-26 11:58:23 -05005935 if(location == -1)
5936 {
5937 return;
5938 }
John Bauman66b8ab22014-05-06 15:57:45 -04005939
Nicolas Capensf160b172014-11-26 11:58:23 -05005940 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005941
Nicolas Capensf160b172014-11-26 11:58:23 -05005942 if(context)
5943 {
5944 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005945
Nicolas Capensf160b172014-11-26 11:58:23 -05005946 if(!program)
5947 {
5948 return error(GL_INVALID_OPERATION);
5949 }
John Bauman66b8ab22014-05-06 15:57:45 -04005950
Nicolas Capensf160b172014-11-26 11:58:23 -05005951 if(!program->setUniformMatrix3fv(location, count, value))
5952 {
5953 return error(GL_INVALID_OPERATION);
5954 }
5955 }
John Bauman66b8ab22014-05-06 15:57:45 -04005956}
5957
5958void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5959{
Nicolas Capensf160b172014-11-26 11:58:23 -05005960 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5961 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04005962
Nicolas Capensf160b172014-11-26 11:58:23 -05005963 if(count < 0 || transpose != GL_FALSE)
5964 {
5965 return error(GL_INVALID_VALUE);
5966 }
John Bauman66b8ab22014-05-06 15:57:45 -04005967
Nicolas Capensf160b172014-11-26 11:58:23 -05005968 if(location == -1)
5969 {
5970 return;
5971 }
John Bauman66b8ab22014-05-06 15:57:45 -04005972
Nicolas Capensf160b172014-11-26 11:58:23 -05005973 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005974
Nicolas Capensf160b172014-11-26 11:58:23 -05005975 if(context)
5976 {
5977 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04005978
Nicolas Capensf160b172014-11-26 11:58:23 -05005979 if(!program)
5980 {
5981 return error(GL_INVALID_OPERATION);
5982 }
John Bauman66b8ab22014-05-06 15:57:45 -04005983
Nicolas Capensf160b172014-11-26 11:58:23 -05005984 if(!program->setUniformMatrix4fv(location, count, value))
5985 {
5986 return error(GL_INVALID_OPERATION);
5987 }
5988 }
John Bauman66b8ab22014-05-06 15:57:45 -04005989}
5990
5991void GL_APIENTRY glUseProgram(GLuint program)
5992{
Nicolas Capensf160b172014-11-26 11:58:23 -05005993 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04005994
Nicolas Capensf160b172014-11-26 11:58:23 -05005995 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005996
Nicolas Capensf160b172014-11-26 11:58:23 -05005997 if(context)
5998 {
5999 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04006000
Nicolas Capensf160b172014-11-26 11:58:23 -05006001 if(!programObject && program != 0)
6002 {
6003 if(context->getShader(program))
6004 {
6005 return error(GL_INVALID_OPERATION);
6006 }
6007 else
6008 {
6009 return error(GL_INVALID_VALUE);
6010 }
6011 }
John Bauman66b8ab22014-05-06 15:57:45 -04006012
Nicolas Capensf160b172014-11-26 11:58:23 -05006013 if(program != 0 && !programObject->isLinked())
6014 {
6015 return error(GL_INVALID_OPERATION);
6016 }
John Bauman66b8ab22014-05-06 15:57:45 -04006017
Nicolas Capensf160b172014-11-26 11:58:23 -05006018 context->useProgram(program);
6019 }
John Bauman66b8ab22014-05-06 15:57:45 -04006020}
6021
6022void GL_APIENTRY glValidateProgram(GLuint program)
6023{
Nicolas Capensf160b172014-11-26 11:58:23 -05006024 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04006025
Nicolas Capensf160b172014-11-26 11:58:23 -05006026 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006027
Nicolas Capensf160b172014-11-26 11:58:23 -05006028 if(context)
6029 {
6030 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04006031
Nicolas Capensf160b172014-11-26 11:58:23 -05006032 if(!programObject)
6033 {
6034 if(context->getShader(program))
6035 {
6036 return error(GL_INVALID_OPERATION);
6037 }
6038 else
6039 {
6040 return error(GL_INVALID_VALUE);
6041 }
6042 }
John Bauman66b8ab22014-05-06 15:57:45 -04006043
Nicolas Capensf160b172014-11-26 11:58:23 -05006044 programObject->validate();
6045 }
John Bauman66b8ab22014-05-06 15:57:45 -04006046}
6047
6048void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
6049{
Nicolas Capensf160b172014-11-26 11:58:23 -05006050 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
John Bauman66b8ab22014-05-06 15:57:45 -04006051
Nicolas Capensf160b172014-11-26 11:58:23 -05006052 if(index >= es2::MAX_VERTEX_ATTRIBS)
6053 {
6054 return error(GL_INVALID_VALUE);
6055 }
John Bauman66b8ab22014-05-06 15:57:45 -04006056
Nicolas Capensf160b172014-11-26 11:58:23 -05006057 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006058
Nicolas Capensf160b172014-11-26 11:58:23 -05006059 if(context)
6060 {
6061 GLfloat vals[4] = { x, 0, 0, 1 };
6062 context->setVertexAttrib(index, vals);
6063 }
John Bauman66b8ab22014-05-06 15:57:45 -04006064}
6065
6066void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
6067{
Nicolas Capensf160b172014-11-26 11:58:23 -05006068 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006069
Nicolas Capensf160b172014-11-26 11:58:23 -05006070 if(index >= es2::MAX_VERTEX_ATTRIBS)
6071 {
6072 return error(GL_INVALID_VALUE);
6073 }
John Bauman66b8ab22014-05-06 15:57:45 -04006074
Nicolas Capensf160b172014-11-26 11:58:23 -05006075 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006076
Nicolas Capensf160b172014-11-26 11:58:23 -05006077 if(context)
6078 {
6079 GLfloat vals[4] = { values[0], 0, 0, 1 };
6080 context->setVertexAttrib(index, vals);
6081 }
John Bauman66b8ab22014-05-06 15:57:45 -04006082}
6083
6084void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6085{
Nicolas Capensf160b172014-11-26 11:58:23 -05006086 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
John Bauman66b8ab22014-05-06 15:57:45 -04006087
Nicolas Capensf160b172014-11-26 11:58:23 -05006088 if(index >= es2::MAX_VERTEX_ATTRIBS)
6089 {
6090 return error(GL_INVALID_VALUE);
6091 }
John Bauman66b8ab22014-05-06 15:57:45 -04006092
Nicolas Capensf160b172014-11-26 11:58:23 -05006093 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006094
Nicolas Capensf160b172014-11-26 11:58:23 -05006095 if(context)
6096 {
6097 GLfloat vals[4] = { x, y, 0, 1 };
6098 context->setVertexAttrib(index, vals);
6099 }
John Bauman66b8ab22014-05-06 15:57:45 -04006100}
6101
6102void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
6103{
Nicolas Capensf160b172014-11-26 11:58:23 -05006104 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006105
Nicolas Capensf160b172014-11-26 11:58:23 -05006106 if(index >= es2::MAX_VERTEX_ATTRIBS)
6107 {
6108 return error(GL_INVALID_VALUE);
6109 }
John Bauman66b8ab22014-05-06 15:57:45 -04006110
Nicolas Capensf160b172014-11-26 11:58:23 -05006111 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006112
Nicolas Capensf160b172014-11-26 11:58:23 -05006113 if(context)
6114 {
6115 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6116 context->setVertexAttrib(index, vals);
6117 }
John Bauman66b8ab22014-05-06 15:57:45 -04006118}
6119
6120void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6121{
Nicolas Capensf160b172014-11-26 11:58:23 -05006122 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
John Bauman66b8ab22014-05-06 15:57:45 -04006123
Nicolas Capensf160b172014-11-26 11:58:23 -05006124 if(index >= es2::MAX_VERTEX_ATTRIBS)
6125 {
6126 return error(GL_INVALID_VALUE);
6127 }
John Bauman66b8ab22014-05-06 15:57:45 -04006128
Nicolas Capensf160b172014-11-26 11:58:23 -05006129 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006130
Nicolas Capensf160b172014-11-26 11:58:23 -05006131 if(context)
6132 {
6133 GLfloat vals[4] = { x, y, z, 1 };
6134 context->setVertexAttrib(index, vals);
6135 }
John Bauman66b8ab22014-05-06 15:57:45 -04006136}
6137
6138void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
6139{
Nicolas Capensf160b172014-11-26 11:58:23 -05006140 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006141
Nicolas Capensf160b172014-11-26 11:58:23 -05006142 if(index >= es2::MAX_VERTEX_ATTRIBS)
6143 {
6144 return error(GL_INVALID_VALUE);
6145 }
John Bauman66b8ab22014-05-06 15:57:45 -04006146
Nicolas Capensf160b172014-11-26 11:58:23 -05006147 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006148
Nicolas Capensf160b172014-11-26 11:58:23 -05006149 if(context)
6150 {
6151 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6152 context->setVertexAttrib(index, vals);
6153 }
John Bauman66b8ab22014-05-06 15:57:45 -04006154}
6155
6156void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6157{
Nicolas Capensf160b172014-11-26 11:58:23 -05006158 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 -04006159
Nicolas Capensf160b172014-11-26 11:58:23 -05006160 if(index >= es2::MAX_VERTEX_ATTRIBS)
6161 {
6162 return error(GL_INVALID_VALUE);
6163 }
John Bauman66b8ab22014-05-06 15:57:45 -04006164
Nicolas Capensf160b172014-11-26 11:58:23 -05006165 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006166
Nicolas Capensf160b172014-11-26 11:58:23 -05006167 if(context)
6168 {
6169 GLfloat vals[4] = { x, y, z, w };
6170 context->setVertexAttrib(index, vals);
6171 }
John Bauman66b8ab22014-05-06 15:57:45 -04006172}
6173
6174void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
6175{
Nicolas Capensf160b172014-11-26 11:58:23 -05006176 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006177
Nicolas Capensf160b172014-11-26 11:58:23 -05006178 if(index >= es2::MAX_VERTEX_ATTRIBS)
6179 {
6180 return error(GL_INVALID_VALUE);
6181 }
John Bauman66b8ab22014-05-06 15:57:45 -04006182
Nicolas Capensf160b172014-11-26 11:58:23 -05006183 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006184
Nicolas Capensf160b172014-11-26 11:58:23 -05006185 if(context)
6186 {
6187 context->setVertexAttrib(index, values);
6188 }
John Bauman66b8ab22014-05-06 15:57:45 -04006189}
6190
6191void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
6192{
Nicolas Capensf160b172014-11-26 11:58:23 -05006193 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
6194 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
6195 index, size, type, normalized, stride, ptr);
John Bauman66b8ab22014-05-06 15:57:45 -04006196
Nicolas Capensf160b172014-11-26 11:58:23 -05006197 if(index >= es2::MAX_VERTEX_ATTRIBS)
6198 {
6199 return error(GL_INVALID_VALUE);
6200 }
John Bauman66b8ab22014-05-06 15:57:45 -04006201
Nicolas Capensf160b172014-11-26 11:58:23 -05006202 if(size < 1 || size > 4)
6203 {
6204 return error(GL_INVALID_VALUE);
6205 }
John Bauman66b8ab22014-05-06 15:57:45 -04006206
Alexis Hetued306182015-04-02 12:02:28 -04006207 egl::GLint clientVersion = egl::getClientVersion();
6208
Nicolas Capensf160b172014-11-26 11:58:23 -05006209 switch(type)
6210 {
6211 case GL_BYTE:
6212 case GL_UNSIGNED_BYTE:
6213 case GL_SHORT:
6214 case GL_UNSIGNED_SHORT:
6215 case GL_FIXED:
6216 case GL_FLOAT:
6217 break;
Alexis Hetued306182015-04-02 12:02:28 -04006218 case GL_INT_2_10_10_10_REV:
6219 case GL_UNSIGNED_INT_2_10_10_10_REV:
6220 if(clientVersion >= 3)
6221 {
6222 if(size != 4)
6223 {
6224 return error(GL_INVALID_OPERATION);
6225 }
6226 break;
6227 }
6228 else return error(GL_INVALID_ENUM);
6229 case GL_INT:
6230 case GL_UNSIGNED_INT:
6231 case GL_HALF_FLOAT:
6232 if(clientVersion >= 3)
6233 {
6234 break;
6235 }
6236 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05006237 default:
6238 return error(GL_INVALID_ENUM);
6239 }
John Bauman66b8ab22014-05-06 15:57:45 -04006240
Nicolas Capensf160b172014-11-26 11:58:23 -05006241 if(stride < 0)
6242 {
6243 return error(GL_INVALID_VALUE);
6244 }
John Bauman66b8ab22014-05-06 15:57:45 -04006245
Nicolas Capensf160b172014-11-26 11:58:23 -05006246 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006247
Nicolas Capensf160b172014-11-26 11:58:23 -05006248 if(context)
6249 {
6250 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
6251 }
John Bauman66b8ab22014-05-06 15:57:45 -04006252}
6253
6254void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6255{
Nicolas Capensf160b172014-11-26 11:58:23 -05006256 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04006257
Nicolas Capensf160b172014-11-26 11:58:23 -05006258 if(width < 0 || height < 0)
6259 {
6260 return error(GL_INVALID_VALUE);
6261 }
John Bauman66b8ab22014-05-06 15:57:45 -04006262
Nicolas Capensf160b172014-11-26 11:58:23 -05006263 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006264
Nicolas Capensf160b172014-11-26 11:58:23 -05006265 if(context)
6266 {
6267 context->setViewportParams(x, y, width, height);
6268 }
John Bauman66b8ab22014-05-06 15:57:45 -04006269}
6270
Alexis Hetue9233fb2015-02-11 10:31:58 -05006271void 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 -04006272{
Nicolas Capensf160b172014-11-26 11:58:23 -05006273 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
6274 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6275 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6276 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
John Bauman66b8ab22014-05-06 15:57:45 -04006277
Nicolas Capensf160b172014-11-26 11:58:23 -05006278 switch(filter)
6279 {
6280 case GL_NEAREST:
6281 break;
6282 default:
6283 return error(GL_INVALID_ENUM);
6284 }
John Bauman66b8ab22014-05-06 15:57:45 -04006285
Nicolas Capensf160b172014-11-26 11:58:23 -05006286 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6287 {
6288 return error(GL_INVALID_VALUE);
6289 }
John Bauman66b8ab22014-05-06 15:57:45 -04006290
Nicolas Capensf160b172014-11-26 11:58:23 -05006291 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006292
Nicolas Capensf160b172014-11-26 11:58:23 -05006293 if(context)
6294 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006295 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
Nicolas Capensf160b172014-11-26 11:58:23 -05006296 {
6297 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6298 return error(GL_INVALID_OPERATION);
6299 }
John Bauman66b8ab22014-05-06 15:57:45 -04006300
Nicolas Capensf160b172014-11-26 11:58:23 -05006301 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6302 }
John Bauman66b8ab22014-05-06 15:57:45 -04006303}
6304
Alexis Hetue9233fb2015-02-11 10:31:58 -05006305void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6306 GLbitfield mask, GLenum filter)
6307{
6308 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6309 {
6310 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6311 return error(GL_INVALID_OPERATION);
6312 }
6313
6314 glBlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6315}
6316
John Bauman66b8ab22014-05-06 15:57:45 -04006317void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
Nicolas Capensf160b172014-11-26 11:58:23 -05006318 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04006319{
Nicolas Capensf160b172014-11-26 11:58:23 -05006320 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
6321 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
6322 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
6323 target, level, internalformat, width, height, depth, border, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04006324
Alexis Hetub027aa92015-01-19 15:56:12 -05006325 switch(target)
6326 {
6327 case GL_TEXTURE_3D_OES:
6328 switch(format)
6329 {
6330 case GL_DEPTH_COMPONENT:
6331 case GL_DEPTH_STENCIL_OES:
6332 return error(GL_INVALID_OPERATION);
6333 default:
6334 break;
6335 }
6336 break;
6337 default:
6338 return error(GL_INVALID_ENUM);
6339 }
6340
6341 if(!ValidateType3D(type) || !ValidateFormat3D(format))
6342 {
6343 return error(GL_INVALID_ENUM);
6344 }
6345
6346 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6347 {
6348 return error(GL_INVALID_VALUE);
6349 }
6350
6351 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6352 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
6353 {
6354 return error(GL_INVALID_VALUE);
6355 }
6356
6357 if(border != 0)
6358 {
6359 return error(GL_INVALID_VALUE);
6360 }
6361
6362 if(!ValidateInternalFormat3D(internalformat, format, type))
6363 {
6364 return error(GL_INVALID_OPERATION);
6365 }
6366
6367 es2::Context *context = es2::getContext();
6368
6369 if(context)
6370 {
6371 es2::Texture3D *texture = context->getTexture3D();
6372
6373 if(!texture)
6374 {
6375 return error(GL_INVALID_OPERATION);
6376 }
6377
6378 texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackAlignment(), pixels);
6379 }
John Bauman66b8ab22014-05-06 15:57:45 -04006380}
6381
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006382void 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)
6383{
Alexis Hetub027aa92015-01-19 15:56:12 -05006384 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6385 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6386 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006387 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
6388
Alexis Hetub027aa92015-01-19 15:56:12 -05006389 switch(target)
6390 {
6391 case GL_TEXTURE_3D_OES:
6392 break;
6393 default:
6394 return error(GL_INVALID_ENUM);
6395 }
6396
6397 if(!ValidateType3D(type) || !ValidateFormat3D(format))
6398 {
6399 return error(GL_INVALID_ENUM);
6400 }
6401
6402 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6403 {
6404 return error(GL_INVALID_VALUE);
6405 }
6406
6407 if((width < 0) || (height < 0) || (depth < 0))
6408 {
6409 return error(GL_INVALID_VALUE);
6410 }
6411
6412 es2::Context *context = es2::getContext();
6413
6414 if(context)
6415 {
6416 es2::Texture3D *texture = context->getTexture3D();
6417
6418 if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))
6419 {
6420 texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackAlignment(), pixels);
6421 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006422 }
6423}
6424
6425void GL_APIENTRY glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
6426{
Alexis Hetub027aa92015-01-19 15:56:12 -05006427 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6428 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006429 target, level, xoffset, yoffset, zoffset, x, y, width, height);
6430
Alexis Hetub027aa92015-01-19 15:56:12 -05006431 switch(target)
6432 {
6433 case GL_TEXTURE_3D_OES:
6434 break;
6435 default:
6436 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006437 }
6438
Alexis Hetub027aa92015-01-19 15:56:12 -05006439 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6440 {
6441 return error(GL_INVALID_VALUE);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006442 }
6443
Alexis Hetub027aa92015-01-19 15:56:12 -05006444 es2::Context *context = es2::getContext();
6445
6446 if(context)
6447 {
6448 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
6449
6450 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
6451 {
6452 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
6453 }
6454
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006455 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Alexis Hetub027aa92015-01-19 15:56:12 -05006456 {
6457 return error(GL_INVALID_OPERATION);
6458 }
6459
6460 es2::Renderbuffer *source = framebuffer->getColorbuffer();
6461 GLenum colorbufferFormat = source->getFormat();
6462 es2::Texture3D *texture = context->getTexture3D();
6463
6464 if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))
6465 {
6466 return;
6467 }
6468
6469 GLenum textureFormat = texture->getFormat(target, level);
6470
6471 if(!validateColorBufferFormat(textureFormat, colorbufferFormat))
6472 {
6473 return;
6474 }
6475
6476 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006477 }
6478}
6479
6480void GL_APIENTRY glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
6481{
Alexis Hetub027aa92015-01-19 15:56:12 -05006482 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
6483 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
6484 target, level, internalformat, width, height, depth, border, imageSize, data);
6485
6486 switch(target)
6487 {
6488 case GL_TEXTURE_3D_OES:
6489 break;
6490 default:
6491 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006492 }
Alexis Hetub027aa92015-01-19 15:56:12 -05006493
6494 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6495 {
6496 return error(GL_INVALID_VALUE);
6497 }
6498
6499 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6500 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
6501 {
6502 return error(GL_INVALID_VALUE);
6503 }
6504
6505 switch(internalformat)
6506 {
6507 case GL_ETC1_RGB8_OES:
6508 break;
6509 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6510 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
6511 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
6512 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
6513 if(!S3TC_SUPPORT)
6514 {
6515 return error(GL_INVALID_ENUM);
6516 }
6517 break;
6518 case GL_DEPTH_COMPONENT:
6519 case GL_DEPTH_COMPONENT16:
6520 case GL_DEPTH_COMPONENT32_OES:
6521 case GL_DEPTH_STENCIL_OES:
6522 case GL_DEPTH24_STENCIL8_OES:
6523 return error(GL_INVALID_OPERATION);
6524 default:
6525 return error(GL_INVALID_ENUM);
6526 }
6527
6528 if(imageSize != es2::ComputeCompressedSize(width, height, internalformat) * depth)
6529 {
6530 return error(GL_INVALID_VALUE);
6531 }
6532
6533 es2::Context *context = es2::getContext();
6534
6535 if(context)
6536 {
6537 es2::Texture3D *texture = context->getTexture3D();
6538
6539 if(!texture)
6540 {
6541 return error(GL_INVALID_OPERATION);
6542 }
6543
6544 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006545 }
6546}
6547
6548void 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)
6549{
Alexis Hetub027aa92015-01-19 15:56:12 -05006550 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6551 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6552 "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = 0x%0.8p)",
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006553 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6554
Alexis Hetub027aa92015-01-19 15:56:12 -05006555 switch(target)
6556 {
6557 case GL_TEXTURE_3D_OES:
6558 break;
6559 default:
6560 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006561 }
Alexis Hetub027aa92015-01-19 15:56:12 -05006562
6563 if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
6564 {
6565 return error(GL_INVALID_VALUE);
6566 }
6567
6568 switch(format)
6569 {
6570 case GL_ETC1_RGB8_OES:
6571 break;
6572 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
6573 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
6574 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
6575 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
6576 if(!S3TC_SUPPORT)
6577 {
6578 return error(GL_INVALID_ENUM);
6579 }
6580 break;
6581 default:
6582 return error(GL_INVALID_ENUM);
6583 }
6584
6585 if(width == 0 || height == 0 || depth == 0 || data == NULL)
6586 {
6587 return;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006588 }
6589
Alexis Hetub027aa92015-01-19 15:56:12 -05006590 es2::Context *context = es2::getContext();
6591
6592 if(context)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006593 {
Alexis Hetub027aa92015-01-19 15:56:12 -05006594 es2::Texture3D *texture = context->getTexture3D();
6595
6596 if(!texture)
6597 {
6598 return error(GL_INVALID_OPERATION);
6599 }
6600
6601 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6602 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006603}
6604
6605void GL_APIENTRY glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
6606{
Alexis Hetub027aa92015-01-19 15:56:12 -05006607 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
6608 "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
6609
6610 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
6611 {
6612 return error(GL_INVALID_ENUM);
6613 }
6614
6615 switch(attachment)
6616 {
6617 case GL_COLOR_ATTACHMENT0:
6618 case GL_DEPTH_ATTACHMENT:
6619 case GL_STENCIL_ATTACHMENT:
6620 break;
6621 default:
6622 return error(GL_INVALID_ENUM);
6623 }
6624
6625 es2::Context *context = es2::getContext();
6626
6627 if(context)
6628 {
6629 if(texture == 0)
6630 {
6631 textarget = GL_NONE;
6632 }
6633 else
6634 {
6635 es2::Texture *tex = context->getTexture(texture);
6636
6637 if(tex == NULL)
6638 {
6639 return error(GL_INVALID_OPERATION);
6640 }
6641
6642 if(tex->isCompressed(textarget, level))
6643 {
6644 return error(GL_INVALID_OPERATION);
6645 }
6646
6647 switch(textarget)
6648 {
6649 case GL_TEXTURE_3D_OES:
6650 if(tex->getTarget() != GL_TEXTURE_3D_OES)
6651 {
6652 return error(GL_INVALID_OPERATION);
6653 }
6654 break;
6655 default:
6656 return error(GL_INVALID_ENUM);
6657 }
6658
6659 if(level != 0)
6660 {
6661 return error(GL_INVALID_VALUE);
6662 }
6663 }
6664
6665 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006666 GLuint framebufferName = 0;
Alexis Hetub027aa92015-01-19 15:56:12 -05006667 if(target == GL_READ_FRAMEBUFFER_ANGLE)
6668 {
6669 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006670 framebufferName = context->getReadFramebufferName();
Alexis Hetub027aa92015-01-19 15:56:12 -05006671 }
6672 else
6673 {
6674 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006675 framebufferName = context->getDrawFramebufferName();
Alexis Hetub027aa92015-01-19 15:56:12 -05006676 }
6677
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006678 if(framebufferName == 0 || !framebuffer)
Alexis Hetub027aa92015-01-19 15:56:12 -05006679 {
6680 return error(GL_INVALID_OPERATION);
6681 }
6682
6683 switch(attachment)
6684 {
6685 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
6686 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
6687 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
6688 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006689 }
6690}
Alexis Hetub027aa92015-01-19 15:56:12 -05006691
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006692void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
6693{
Nicolas Capensd76b5df2014-10-28 15:54:46 -04006694 if(egl::getClientVersion() == 1)
6695 {
Nicolas Capensf3d2efd2014-10-29 11:27:55 -04006696 static auto glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)es1::getProcAddress("glEGLImageTargetTexture2DOES");
Nicolas Capensd76b5df2014-10-28 15:54:46 -04006697 return glEGLImageTargetTexture2DOES(target, image);
6698 }
6699
Nicolas Capensf160b172014-11-26 11:58:23 -05006700 TRACE("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006701
Nicolas Capensf160b172014-11-26 11:58:23 -05006702 switch(target)
6703 {
6704 case GL_TEXTURE_2D:
6705 case GL_TEXTURE_EXTERNAL_OES:
6706 break;
6707 default:
6708 return error(GL_INVALID_ENUM);
6709 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006710
Nicolas Capensf160b172014-11-26 11:58:23 -05006711 if(!image)
6712 {
6713 return error(GL_INVALID_OPERATION);
6714 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006715
Nicolas Capensf160b172014-11-26 11:58:23 -05006716 es2::Context *context = es2::getContext();
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006717
Nicolas Capensf160b172014-11-26 11:58:23 -05006718 if(context)
6719 {
6720 es2::Texture2D *texture = 0;
Nicolas Capens08e90f02014-11-21 12:49:12 -05006721
Nicolas Capensf160b172014-11-26 11:58:23 -05006722 switch(target)
6723 {
6724 case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
6725 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
6726 default: UNREACHABLE();
6727 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006728
Nicolas Capensf160b172014-11-26 11:58:23 -05006729 if(!texture)
6730 {
6731 return error(GL_INVALID_OPERATION);
6732 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006733
Nicolas Capensf160b172014-11-26 11:58:23 -05006734 egl::Image *glImage = static_cast<egl::Image*>(image);
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006735
Nicolas Capensf160b172014-11-26 11:58:23 -05006736 texture->setImage(glImage);
6737 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04006738}
6739
Nicolas Capens7e12ac62014-11-05 17:07:53 -05006740void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
6741{
6742 TRACE("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);
6743
6744 UNIMPLEMENTED();
6745}
6746
John Bauman66b8ab22014-05-06 15:57:45 -04006747__eglMustCastToProperFunctionPointerType glGetProcAddress(const char *procname)
6748{
Nicolas Capensf160b172014-11-26 11:58:23 -05006749 struct Extension
6750 {
6751 const char *name;
6752 __eglMustCastToProperFunctionPointerType address;
6753 };
John Bauman66b8ab22014-05-06 15:57:45 -04006754
Nicolas Capensf160b172014-11-26 11:58:23 -05006755 static const Extension glExtensions[] =
6756 {
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006757 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
6758
Nicolas Capensf160b172014-11-26 11:58:23 -05006759 EXTENSION(glTexImage3DOES),
6760 EXTENSION(glBlitFramebufferANGLE),
Alexis Hetue9233fb2015-02-11 10:31:58 -05006761 EXTENSION(glBlitFramebufferNV),
Nicolas Capensf160b172014-11-26 11:58:23 -05006762 EXTENSION(glRenderbufferStorageMultisampleANGLE),
6763 EXTENSION(glDeleteFencesNV),
6764 EXTENSION(glGenFencesNV),
6765 EXTENSION(glIsFenceNV),
6766 EXTENSION(glTestFenceNV),
6767 EXTENSION(glGetFenceivNV),
6768 EXTENSION(glFinishFenceNV),
6769 EXTENSION(glSetFenceNV),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006770 EXTENSION(glGetGraphicsResetStatusEXT),
Nicolas Capensf160b172014-11-26 11:58:23 -05006771 EXTENSION(glReadnPixelsEXT),
6772 EXTENSION(glGetnUniformfvEXT),
6773 EXTENSION(glGetnUniformivEXT),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006774 EXTENSION(glGenQueriesEXT),
Nicolas Capensf160b172014-11-26 11:58:23 -05006775 EXTENSION(glDeleteQueriesEXT),
6776 EXTENSION(glIsQueryEXT),
6777 EXTENSION(glBeginQueryEXT),
6778 EXTENSION(glEndQueryEXT),
6779 EXTENSION(glGetQueryivEXT),
6780 EXTENSION(glGetQueryObjectuivEXT),
6781 EXTENSION(glEGLImageTargetTexture2DOES),
Nicolas Capens7e12ac62014-11-05 17:07:53 -05006782 EXTENSION(glEGLImageTargetRenderbufferStorageOES),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05006783
6784 #undef EXTENSION
Nicolas Capensf160b172014-11-26 11:58:23 -05006785 };
John Bauman66b8ab22014-05-06 15:57:45 -04006786
Nicolas Capensf160b172014-11-26 11:58:23 -05006787 for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6788 {
6789 if(strcmp(procname, glExtensions[ext].name) == 0)
6790 {
6791 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6792 }
6793 }
John Bauman66b8ab22014-05-06 15:57:45 -04006794
Nicolas Capensf160b172014-11-26 11:58:23 -05006795 return NULL;
John Bauman66b8ab22014-05-06 15:57:45 -04006796}
6797
John Baumand4ae8632014-05-06 16:18:33 -04006798void GL_APIENTRY Register(const char *licenseKey)
6799{
6800 RegisterLicenseKey(licenseKey);
6801}
6802
John Bauman66b8ab22014-05-06 15:57:45 -04006803}