blob: b5364b93e7d45685840d8e4b93e460a8822b9bc1 [file] [log] [blame]
John Bauman66b8ab22014-05-06 15:57:45 -04001// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2013 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
12
13#include "main.h"
14#include "mathutil.h"
15#include "utilities.h"
16#include "Buffer.h"
17#include "Context.h"
18#include "Fence.h"
19#include "Framebuffer.h"
20#include "Program.h"
21#include "Renderbuffer.h"
22#include "Shader.h"
23#include "Texture.h"
24#include "Query.h"
25#include "common/debug.h"
26#include "Common/Version.h"
27
John Bauman66b8ab22014-05-06 15:57:45 -040028#include <GLES2/gl2.h>
29#include <GLES2/gl2ext.h>
Alexis Hetufceb1832015-03-10 16:42:04 -040030#include <GLES3/gl3.h>
John Bauman66b8ab22014-05-06 15:57:45 -040031
John Bauman66b8ab22014-05-06 15:57:45 -040032#include <limits>
33
Greg Hartman6074f122015-04-08 09:57:16 -070034#ifdef ANDROID
35#include <cutils/log.h>
36#endif
37
Nicolas Capenseb195b62015-04-28 17:18:42 -070038namespace es2
39{
Nicolas Capensa2308052015-04-15 16:50:21 -040040
Alexis Hetub027aa92015-01-19 15:56:12 -050041typedef std::pair<GLenum, GLenum> InternalFormatTypePair;
42typedef std::map<InternalFormatTypePair, GLenum> FormatMap;
43
44// A helper function to insert data into the format map with fewer characters.
45static void InsertFormatMapping(FormatMap& map, GLenum internalformat, GLenum format, GLenum type)
46{
47 map[InternalFormatTypePair(internalformat, type)] = format;
48}
49
John Bauman66b8ab22014-05-06 15:57:45 -040050static bool validImageSize(GLint level, GLsizei width, GLsizei height)
51{
Nicolas Capensf160b172014-11-26 11:58:23 -050052 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
53 {
54 return false;
55 }
John Bauman66b8ab22014-05-06 15:57:45 -040056
Nicolas Capensf160b172014-11-26 11:58:23 -050057 return true;
John Bauman66b8ab22014-05-06 15:57:45 -040058}
59
Alexis Hetub027aa92015-01-19 15:56:12 -050060static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)
61{
Alexis Hetud9a2e7b2015-10-15 17:22:57 -040062 GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);
63 if(validationError != GL_NONE)
Alexis Hetu460e41f2015-09-01 10:58:37 -040064 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -040065 return error(validationError, false);
Alexis Hetu460e41f2015-09-01 10:58:37 -040066 }
67
Alexis Hetub027aa92015-01-19 15:56:12 -050068 // [OpenGL ES 2.0.24] table 3.9
69 switch(textureFormat)
70 {
71 case GL_ALPHA:
72 if(colorbufferFormat != GL_ALPHA &&
Nicolas Capenseb195b62015-04-28 17:18:42 -070073 colorbufferFormat != GL_RGBA &&
74 colorbufferFormat != GL_RGBA4 &&
75 colorbufferFormat != GL_RGB5_A1 &&
76 colorbufferFormat != GL_RGBA8_OES)
Alexis Hetub027aa92015-01-19 15:56:12 -050077 {
78 return error(GL_INVALID_OPERATION, false);
79 }
80 break;
81 case GL_LUMINANCE:
82 case GL_RGB:
83 if(colorbufferFormat != GL_RGB &&
Nicolas Capenseb195b62015-04-28 17:18:42 -070084 colorbufferFormat != GL_RGB565 &&
85 colorbufferFormat != GL_RGB8_OES &&
86 colorbufferFormat != GL_RGBA &&
87 colorbufferFormat != GL_RGBA4 &&
88 colorbufferFormat != GL_RGB5_A1 &&
89 colorbufferFormat != GL_RGBA8_OES)
Alexis Hetub027aa92015-01-19 15:56:12 -050090 {
91 return error(GL_INVALID_OPERATION, false);
92 }
93 break;
94 case GL_LUMINANCE_ALPHA:
95 case GL_RGBA:
96 if(colorbufferFormat != GL_RGBA &&
Nicolas Capenseb195b62015-04-28 17:18:42 -070097 colorbufferFormat != GL_RGBA4 &&
98 colorbufferFormat != GL_RGB5_A1 &&
99 colorbufferFormat != GL_RGBA8_OES)
Alexis Hetub027aa92015-01-19 15:56:12 -0500100 {
101 return error(GL_INVALID_OPERATION, false);
102 }
103 break;
Alexis Hetub027aa92015-01-19 15:56:12 -0500104 case GL_DEPTH_COMPONENT:
105 case GL_DEPTH_STENCIL_OES:
106 return error(GL_INVALID_OPERATION, false);
107 default:
108 return error(GL_INVALID_ENUM, false);
109 }
110 return true;
111}
112
113static FormatMap BuildFormatMap3D()
114{
115 FormatMap map;
116
117 // Internal format | Format | Type
118 InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE);
119 InsertFormatMapping(map, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
120 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
121 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
122 InsertFormatMapping(map, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
123 InsertFormatMapping(map, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
124 InsertFormatMapping(map, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE);
125 InsertFormatMapping(map, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
126 InsertFormatMapping(map, GL_R8_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE);
Alexis Hetu61161502015-05-21 11:45:03 -0400127 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT);
Alexis Hetub027aa92015-01-19 15:56:12 -0500128 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
129 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_FLOAT);
130 InsertFormatMapping(map, GL_R32F_EXT, GL_RED_EXT, GL_FLOAT);
131 InsertFormatMapping(map, GL_RG8_EXT, GL_RG_EXT, GL_UNSIGNED_BYTE);
Alexis Hetu61161502015-05-21 11:45:03 -0400132 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT);
Alexis Hetub027aa92015-01-19 15:56:12 -0500133 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_OES);
134 InsertFormatMapping(map, GL_R16F_EXT, GL_RED_EXT, GL_FLOAT);
135 InsertFormatMapping(map, GL_RG32F_EXT, GL_RG_EXT, GL_FLOAT);
136 InsertFormatMapping(map, GL_RGB8_OES, GL_RGB, GL_UNSIGNED_BYTE);
137 InsertFormatMapping(map, GL_SRGB8_NV, GL_RGB, GL_UNSIGNED_BYTE);
138 InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE);
139 InsertFormatMapping(map, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
Alexis Hetu61161502015-05-21 11:45:03 -0400140 InsertFormatMapping(map, GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT);
Alexis Hetu0300e3c2015-03-12 17:33:07 -0400141 InsertFormatMapping(map, GL_RGB16F_EXT, GL_RGB, GL_HALF_FLOAT_OES);
142 InsertFormatMapping(map, GL_RGB16F_EXT, GL_RGB, GL_FLOAT);
Alexis Hetub027aa92015-01-19 15:56:12 -0500143 InsertFormatMapping(map, GL_RGB32F_EXT, GL_RGB, GL_FLOAT);
144 InsertFormatMapping(map, GL_RGBA8_OES, GL_RGBA, GL_UNSIGNED_BYTE);
145 InsertFormatMapping(map, GL_SRGB8_ALPHA8_EXT, GL_RGBA, GL_UNSIGNED_BYTE);
146 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE);
147 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
148 InsertFormatMapping(map, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT);
149 InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE);
150 InsertFormatMapping(map, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
151 InsertFormatMapping(map, GL_RGB10_A2_EXT, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT);
Alexis Hetu61161502015-05-21 11:45:03 -0400152 InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT);
Alexis Hetub027aa92015-01-19 15:56:12 -0500153 InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_HALF_FLOAT_OES);
154 InsertFormatMapping(map, GL_RGBA16F_EXT, GL_RGBA, GL_FLOAT);
155 InsertFormatMapping(map, GL_RGBA32F_EXT, GL_RGBA, GL_FLOAT);
156
157 return map;
158}
159
160static bool ValidateType3D(GLenum type)
161{
162 switch(type)
163 {
164 case GL_UNSIGNED_BYTE:
165 case GL_BYTE:
166 case GL_UNSIGNED_SHORT:
167 case GL_SHORT:
168 case GL_UNSIGNED_INT:
169 case GL_INT:
Alexis Hetu61161502015-05-21 11:45:03 -0400170 case GL_HALF_FLOAT:
Alexis Hetub027aa92015-01-19 15:56:12 -0500171 case GL_HALF_FLOAT_OES:
172 case GL_FLOAT:
173 case GL_UNSIGNED_SHORT_5_6_5:
174 case GL_UNSIGNED_SHORT_4_4_4_4:
175 case GL_UNSIGNED_SHORT_5_5_5_1:
176 case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
177 return true;
178 default:
179 break;
180 }
181 return false;
182}
183
184static bool ValidateFormat3D(GLenum format)
185{
186 switch(format)
187 {
188 case GL_RED_EXT:
189 case GL_RG_EXT:
190 case GL_RGB:
191 case GL_RGBA:
192 case GL_DEPTH_COMPONENT:
193 case GL_DEPTH_STENCIL_OES:
194 case GL_LUMINANCE_ALPHA:
195 case GL_LUMINANCE:
196 case GL_ALPHA:
197 return true;
198 default:
199 break;
200 }
201 return false;
202}
203
204static bool ValidateInternalFormat3D(GLenum internalformat, GLenum format, GLenum type)
205{
206 static const FormatMap formatMap = BuildFormatMap3D();
207 FormatMap::const_iterator iter = formatMap.find(InternalFormatTypePair(internalformat, type));
208 if(iter != formatMap.end())
209 {
210 return iter->second == format;
211 }
212 return false;
213}
214
Nicolas Capenseb195b62015-04-28 17:18:42 -0700215void ActiveTexture(GLenum texture)
John Bauman66b8ab22014-05-06 15:57:45 -0400216{
Nicolas Capensf160b172014-11-26 11:58:23 -0500217 TRACE("(GLenum texture = 0x%X)", texture);
John Bauman66b8ab22014-05-06 15:57:45 -0400218
Nicolas Capensf160b172014-11-26 11:58:23 -0500219 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400220
Nicolas Capensf160b172014-11-26 11:58:23 -0500221 if(context)
222 {
223 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
224 {
225 return error(GL_INVALID_ENUM);
226 }
John Bauman66b8ab22014-05-06 15:57:45 -0400227
Nicolas Capensf160b172014-11-26 11:58:23 -0500228 context->setActiveSampler(texture - GL_TEXTURE0);
229 }
John Bauman66b8ab22014-05-06 15:57:45 -0400230}
231
Nicolas Capenseb195b62015-04-28 17:18:42 -0700232void AttachShader(GLuint program, GLuint shader)
John Bauman66b8ab22014-05-06 15:57:45 -0400233{
Nicolas Capensf160b172014-11-26 11:58:23 -0500234 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400235
Nicolas Capensf160b172014-11-26 11:58:23 -0500236 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400237
Nicolas Capensf160b172014-11-26 11:58:23 -0500238 if(context)
239 {
240 es2::Program *programObject = context->getProgram(program);
241 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400242
Nicolas Capensf160b172014-11-26 11:58:23 -0500243 if(!programObject)
244 {
245 if(context->getShader(program))
246 {
247 return error(GL_INVALID_OPERATION);
248 }
249 else
250 {
251 return error(GL_INVALID_VALUE);
252 }
253 }
John Bauman66b8ab22014-05-06 15:57:45 -0400254
Nicolas Capensf160b172014-11-26 11:58:23 -0500255 if(!shaderObject)
256 {
257 if(context->getProgram(shader))
258 {
259 return error(GL_INVALID_OPERATION);
260 }
261 else
262 {
263 return error(GL_INVALID_VALUE);
264 }
265 }
John Bauman66b8ab22014-05-06 15:57:45 -0400266
Nicolas Capensf160b172014-11-26 11:58:23 -0500267 if(!programObject->attachShader(shaderObject))
268 {
269 return error(GL_INVALID_OPERATION);
270 }
271 }
John Bauman66b8ab22014-05-06 15:57:45 -0400272}
273
Nicolas Capenseb195b62015-04-28 17:18:42 -0700274void BeginQueryEXT(GLenum target, GLuint name)
John Bauman66b8ab22014-05-06 15:57:45 -0400275{
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500276 TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
John Bauman66b8ab22014-05-06 15:57:45 -0400277
Nicolas Capensf160b172014-11-26 11:58:23 -0500278 switch(target)
279 {
280 case GL_ANY_SAMPLES_PASSED_EXT:
281 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
282 break;
283 default:
284 return error(GL_INVALID_ENUM);
285 }
John Bauman66b8ab22014-05-06 15:57:45 -0400286
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500287 if(name == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -0500288 {
289 return error(GL_INVALID_OPERATION);
290 }
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 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500296 context->beginQuery(target, name);
Nicolas Capensf160b172014-11-26 11:58:23 -0500297 }
John Bauman66b8ab22014-05-06 15:57:45 -0400298}
299
Nicolas Capenseb195b62015-04-28 17:18:42 -0700300void BindAttribLocation(GLuint program, GLuint index, const GLchar* name)
John Bauman66b8ab22014-05-06 15:57:45 -0400301{
Nicolas Capensf160b172014-11-26 11:58:23 -0500302 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
John Bauman66b8ab22014-05-06 15:57:45 -0400303
Nicolas Capensf160b172014-11-26 11:58:23 -0500304 if(index >= es2::MAX_VERTEX_ATTRIBS)
305 {
306 return error(GL_INVALID_VALUE);
307 }
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);
John Bauman66b8ab22014-05-06 15:57:45 -0400314
Nicolas Capensf160b172014-11-26 11:58:23 -0500315 if(!programObject)
316 {
317 if(context->getShader(program))
318 {
319 return error(GL_INVALID_OPERATION);
320 }
321 else
322 {
323 return error(GL_INVALID_VALUE);
324 }
325 }
John Bauman66b8ab22014-05-06 15:57:45 -0400326
Nicolas Capensf160b172014-11-26 11:58:23 -0500327 if(strncmp(name, "gl_", 3) == 0)
328 {
329 return error(GL_INVALID_OPERATION);
330 }
John Bauman66b8ab22014-05-06 15:57:45 -0400331
Nicolas Capensf160b172014-11-26 11:58:23 -0500332 programObject->bindAttributeLocation(index, name);
333 }
John Bauman66b8ab22014-05-06 15:57:45 -0400334}
335
Nicolas Capenseb195b62015-04-28 17:18:42 -0700336void BindBuffer(GLenum target, GLuint buffer)
John Bauman66b8ab22014-05-06 15:57:45 -0400337{
Nicolas Capensf160b172014-11-26 11:58:23 -0500338 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
John Bauman66b8ab22014-05-06 15:57:45 -0400339
Nicolas Capensf160b172014-11-26 11:58:23 -0500340 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400341
Nicolas Capensf160b172014-11-26 11:58:23 -0500342 if(context)
343 {
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400344 egl::GLint clientVersion = egl::getClientVersion();
345
Nicolas Capensf160b172014-11-26 11:58:23 -0500346 switch(target)
347 {
348 case GL_ARRAY_BUFFER:
349 context->bindArrayBuffer(buffer);
350 return;
351 case GL_ELEMENT_ARRAY_BUFFER:
352 context->bindElementArrayBuffer(buffer);
353 return;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400354 case GL_COPY_READ_BUFFER:
355 if(clientVersion >= 3)
356 {
357 context->bindCopyReadBuffer(buffer);
358 return;
359 }
360 else return error(GL_INVALID_ENUM);
361 case GL_COPY_WRITE_BUFFER:
362 if(clientVersion >= 3)
363 {
364 context->bindCopyWriteBuffer(buffer);
365 return;
366 }
367 else return error(GL_INVALID_ENUM);
368 case GL_PIXEL_PACK_BUFFER:
369 if(clientVersion >= 3)
370 {
371 context->bindPixelPackBuffer(buffer);
372 return;
373 }
374 else return error(GL_INVALID_ENUM);
375 case GL_PIXEL_UNPACK_BUFFER:
376 if(clientVersion >= 3)
377 {
378 context->bindPixelUnpackBuffer(buffer);
379 return;
380 }
381 else return error(GL_INVALID_ENUM);
382 case GL_TRANSFORM_FEEDBACK_BUFFER:
383 if(clientVersion >= 3)
384 {
Alexis Hetubcac6ff2015-04-22 08:29:22 -0400385 context->bindTransformFeedbackBuffer(buffer);
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400386 return;
387 }
388 else return error(GL_INVALID_ENUM);
389 case GL_UNIFORM_BUFFER:
390 if(clientVersion >= 3)
391 {
Alexis Hetuc2632d22015-05-01 14:16:47 -0400392 context->bindGenericUniformBuffer(buffer);
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400393 return;
394 }
395 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -0500396 default:
397 return error(GL_INVALID_ENUM);
398 }
399 }
John Bauman66b8ab22014-05-06 15:57:45 -0400400}
401
Nicolas Capenseb195b62015-04-28 17:18:42 -0700402void BindFramebuffer(GLenum target, GLuint framebuffer)
John Bauman66b8ab22014-05-06 15:57:45 -0400403{
Nicolas Capensf160b172014-11-26 11:58:23 -0500404 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -0400405
Nicolas Capensf160b172014-11-26 11:58:23 -0500406 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
407 {
408 return error(GL_INVALID_ENUM);
409 }
John Bauman66b8ab22014-05-06 15:57:45 -0400410
Nicolas Capensf160b172014-11-26 11:58:23 -0500411 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400412
Nicolas Capensf160b172014-11-26 11:58:23 -0500413 if(context)
414 {
415 if(target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
416 {
417 context->bindReadFramebuffer(framebuffer);
418 }
Nicolas Capens08e90f02014-11-21 12:49:12 -0500419
Nicolas Capensf160b172014-11-26 11:58:23 -0500420 if(target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
421 {
422 context->bindDrawFramebuffer(framebuffer);
423 }
424 }
John Bauman66b8ab22014-05-06 15:57:45 -0400425}
426
Nicolas Capenseb195b62015-04-28 17:18:42 -0700427void BindRenderbuffer(GLenum target, GLuint renderbuffer)
John Bauman66b8ab22014-05-06 15:57:45 -0400428{
Nicolas Capensf160b172014-11-26 11:58:23 -0500429 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -0400430
Nicolas Capensf160b172014-11-26 11:58:23 -0500431 if(target != GL_RENDERBUFFER)
432 {
433 return error(GL_INVALID_ENUM);
434 }
John Bauman66b8ab22014-05-06 15:57:45 -0400435
Nicolas Capensf160b172014-11-26 11:58:23 -0500436 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400437
Nicolas Capensf160b172014-11-26 11:58:23 -0500438 if(context)
439 {
Alexis Hetuc68dd272015-12-03 11:29:56 -0500440 // [OpenGL ES 2.0.25] Section 4.4.3 page 110
Alexis Hetu2ea6f552015-12-02 11:49:37 -0500441 // [OpenGL ES 3.0.4] Section 4.4.2 page 204
442 // If renderbuffer is not zero, then the resulting renderbuffer object
443 // is a new state vector, initialized with a zero-sized memory buffer.
Nicolas Capensf160b172014-11-26 11:58:23 -0500444 context->bindRenderbuffer(renderbuffer);
445 }
John Bauman66b8ab22014-05-06 15:57:45 -0400446}
447
Nicolas Capenseb195b62015-04-28 17:18:42 -0700448void BindTexture(GLenum target, GLuint texture)
John Bauman66b8ab22014-05-06 15:57:45 -0400449{
Nicolas Capensf160b172014-11-26 11:58:23 -0500450 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
John Bauman66b8ab22014-05-06 15:57:45 -0400451
Nicolas Capensf160b172014-11-26 11:58:23 -0500452 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400453
Nicolas Capensf160b172014-11-26 11:58:23 -0500454 if(context)
455 {
456 es2::Texture *textureObject = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -0400457
Nicolas Capensf160b172014-11-26 11:58:23 -0500458 if(textureObject && textureObject->getTarget() != target && texture != 0)
459 {
460 return error(GL_INVALID_OPERATION);
461 }
John Bauman66b8ab22014-05-06 15:57:45 -0400462
Alexis Hetued306182015-04-02 12:02:28 -0400463 egl::GLint clientVersion = context->getClientVersion();
464
Nicolas Capensf160b172014-11-26 11:58:23 -0500465 switch(target)
466 {
467 case GL_TEXTURE_2D:
468 context->bindTexture2D(texture);
Alexis Hetu778c28f2015-05-11 16:32:19 -0400469 break;
Nicolas Capensf160b172014-11-26 11:58:23 -0500470 case GL_TEXTURE_CUBE_MAP:
471 context->bindTextureCubeMap(texture);
Alexis Hetu778c28f2015-05-11 16:32:19 -0400472 break;
Nicolas Capensf160b172014-11-26 11:58:23 -0500473 case GL_TEXTURE_EXTERNAL_OES:
474 context->bindTextureExternal(texture);
Alexis Hetu778c28f2015-05-11 16:32:19 -0400475 break;
Alexis Hetued306182015-04-02 12:02:28 -0400476 case GL_TEXTURE_2D_ARRAY:
477 if(clientVersion < 3)
478 {
479 return error(GL_INVALID_ENUM);
480 }
Alexis Hetu778c28f2015-05-11 16:32:19 -0400481 context->bindTexture2DArray(texture);
482 break;
Alexis Hetub027aa92015-01-19 15:56:12 -0500483 case GL_TEXTURE_3D_OES:
484 context->bindTexture3D(texture);
Alexis Hetu778c28f2015-05-11 16:32:19 -0400485 break;
Nicolas Capensf160b172014-11-26 11:58:23 -0500486 default:
487 return error(GL_INVALID_ENUM);
488 }
489 }
John Bauman66b8ab22014-05-06 15:57:45 -0400490}
491
Nicolas Capenseb195b62015-04-28 17:18:42 -0700492void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
John Bauman66b8ab22014-05-06 15:57:45 -0400493{
Nicolas Capensf160b172014-11-26 11:58:23 -0500494 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
495 red, green, blue, alpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400496
Nicolas Capensf160b172014-11-26 11:58:23 -0500497 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400498
Nicolas Capensf160b172014-11-26 11:58:23 -0500499 if(context)
500 {
501 context->setBlendColor(es2::clamp01(red), es2::clamp01(green), es2::clamp01(blue), es2::clamp01(alpha));
502 }
John Bauman66b8ab22014-05-06 15:57:45 -0400503}
504
Nicolas Capenseb195b62015-04-28 17:18:42 -0700505void BlendEquation(GLenum mode)
John Bauman66b8ab22014-05-06 15:57:45 -0400506{
Nicolas Capensf160b172014-11-26 11:58:23 -0500507 glBlendEquationSeparate(mode, mode);
John Bauman66b8ab22014-05-06 15:57:45 -0400508}
509
Nicolas Capenseb195b62015-04-28 17:18:42 -0700510void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
John Bauman66b8ab22014-05-06 15:57:45 -0400511{
Nicolas Capensf160b172014-11-26 11:58:23 -0500512 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400513
Nicolas Capensf160b172014-11-26 11:58:23 -0500514 switch(modeRGB)
515 {
516 case GL_FUNC_ADD:
517 case GL_FUNC_SUBTRACT:
518 case GL_FUNC_REVERSE_SUBTRACT:
519 case GL_MIN_EXT:
520 case GL_MAX_EXT:
521 break;
522 default:
523 return error(GL_INVALID_ENUM);
524 }
John Bauman66b8ab22014-05-06 15:57:45 -0400525
Nicolas Capensf160b172014-11-26 11:58:23 -0500526 switch(modeAlpha)
527 {
528 case GL_FUNC_ADD:
529 case GL_FUNC_SUBTRACT:
530 case GL_FUNC_REVERSE_SUBTRACT:
531 case GL_MIN_EXT:
532 case GL_MAX_EXT:
533 break;
534 default:
535 return error(GL_INVALID_ENUM);
536 }
John Bauman66b8ab22014-05-06 15:57:45 -0400537
Nicolas Capensf160b172014-11-26 11:58:23 -0500538 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400539
Nicolas Capensf160b172014-11-26 11:58:23 -0500540 if(context)
541 {
542 context->setBlendEquation(modeRGB, modeAlpha);
543 }
John Bauman66b8ab22014-05-06 15:57:45 -0400544}
545
Nicolas Capenseb195b62015-04-28 17:18:42 -0700546void BlendFunc(GLenum sfactor, GLenum dfactor)
John Bauman66b8ab22014-05-06 15:57:45 -0400547{
Nicolas Capensf160b172014-11-26 11:58:23 -0500548 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
John Bauman66b8ab22014-05-06 15:57:45 -0400549}
550
Nicolas Capenseb195b62015-04-28 17:18:42 -0700551void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
John Bauman66b8ab22014-05-06 15:57:45 -0400552{
Nicolas Capensf160b172014-11-26 11:58:23 -0500553 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
554 srcRGB, dstRGB, srcAlpha, dstAlpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400555
Alexis Hetuff5e0522015-05-12 16:06:30 -0400556 egl::GLint clientVersion = egl::getClientVersion();
557
Nicolas Capensf160b172014-11-26 11:58:23 -0500558 switch(srcRGB)
559 {
560 case GL_ZERO:
561 case GL_ONE:
562 case GL_SRC_COLOR:
563 case GL_ONE_MINUS_SRC_COLOR:
564 case GL_DST_COLOR:
565 case GL_ONE_MINUS_DST_COLOR:
566 case GL_SRC_ALPHA:
567 case GL_ONE_MINUS_SRC_ALPHA:
568 case GL_DST_ALPHA:
569 case GL_ONE_MINUS_DST_ALPHA:
570 case GL_CONSTANT_COLOR:
571 case GL_ONE_MINUS_CONSTANT_COLOR:
572 case GL_CONSTANT_ALPHA:
573 case GL_ONE_MINUS_CONSTANT_ALPHA:
574 case GL_SRC_ALPHA_SATURATE:
575 break;
576 default:
577 return error(GL_INVALID_ENUM);
578 }
John Bauman66b8ab22014-05-06 15:57:45 -0400579
Nicolas Capensf160b172014-11-26 11:58:23 -0500580 switch(dstRGB)
581 {
582 case GL_ZERO:
583 case GL_ONE:
584 case GL_SRC_COLOR:
585 case GL_ONE_MINUS_SRC_COLOR:
586 case GL_DST_COLOR:
587 case GL_ONE_MINUS_DST_COLOR:
588 case GL_SRC_ALPHA:
589 case GL_ONE_MINUS_SRC_ALPHA:
590 case GL_DST_ALPHA:
591 case GL_ONE_MINUS_DST_ALPHA:
592 case GL_CONSTANT_COLOR:
593 case GL_ONE_MINUS_CONSTANT_COLOR:
594 case GL_CONSTANT_ALPHA:
595 case GL_ONE_MINUS_CONSTANT_ALPHA:
596 break;
Alexis Hetuff5e0522015-05-12 16:06:30 -0400597 case GL_SRC_ALPHA_SATURATE:
598 if(clientVersion < 3)
599 {
600 return error(GL_INVALID_ENUM);
601 }
602 break;
Nicolas Capensf160b172014-11-26 11:58:23 -0500603 default:
604 return error(GL_INVALID_ENUM);
605 }
John Bauman66b8ab22014-05-06 15:57:45 -0400606
Nicolas Capensf160b172014-11-26 11:58:23 -0500607 switch(srcAlpha)
608 {
609 case GL_ZERO:
610 case GL_ONE:
611 case GL_SRC_COLOR:
612 case GL_ONE_MINUS_SRC_COLOR:
613 case GL_DST_COLOR:
614 case GL_ONE_MINUS_DST_COLOR:
615 case GL_SRC_ALPHA:
616 case GL_ONE_MINUS_SRC_ALPHA:
617 case GL_DST_ALPHA:
618 case GL_ONE_MINUS_DST_ALPHA:
619 case GL_CONSTANT_COLOR:
620 case GL_ONE_MINUS_CONSTANT_COLOR:
621 case GL_CONSTANT_ALPHA:
622 case GL_ONE_MINUS_CONSTANT_ALPHA:
623 case GL_SRC_ALPHA_SATURATE:
624 break;
625 default:
626 return error(GL_INVALID_ENUM);
627 }
John Bauman66b8ab22014-05-06 15:57:45 -0400628
Nicolas Capensf160b172014-11-26 11:58:23 -0500629 switch(dstAlpha)
630 {
631 case GL_ZERO:
632 case GL_ONE:
633 case GL_SRC_COLOR:
634 case GL_ONE_MINUS_SRC_COLOR:
635 case GL_DST_COLOR:
636 case GL_ONE_MINUS_DST_COLOR:
637 case GL_SRC_ALPHA:
638 case GL_ONE_MINUS_SRC_ALPHA:
639 case GL_DST_ALPHA:
640 case GL_ONE_MINUS_DST_ALPHA:
641 case GL_CONSTANT_COLOR:
642 case GL_ONE_MINUS_CONSTANT_COLOR:
643 case GL_CONSTANT_ALPHA:
644 case GL_ONE_MINUS_CONSTANT_ALPHA:
645 break;
Alexis Hetuff5e0522015-05-12 16:06:30 -0400646 case GL_SRC_ALPHA_SATURATE:
647 if(clientVersion < 3)
648 {
649 return error(GL_INVALID_ENUM);
650 }
651 break;
Nicolas Capensf160b172014-11-26 11:58:23 -0500652 default:
653 return error(GL_INVALID_ENUM);
654 }
John Bauman66b8ab22014-05-06 15:57:45 -0400655
Nicolas Capensf160b172014-11-26 11:58:23 -0500656 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400657
Nicolas Capensf160b172014-11-26 11:58:23 -0500658 if(context)
659 {
660 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
661 }
John Bauman66b8ab22014-05-06 15:57:45 -0400662}
663
Nicolas Capenseb195b62015-04-28 17:18:42 -0700664void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
Nicolas Capens54b721d2014-12-12 12:50:04 -0500665{
666 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
Nicolas Capens4cadfe32014-12-10 22:26:26 -0500667
Nicolas Capens4be33702015-04-28 15:13:30 -0700668 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
Nicolas Capensf160b172014-11-26 11:58:23 -0500669 target, size, data, usage);
John Bauman66b8ab22014-05-06 15:57:45 -0400670
Nicolas Capensf160b172014-11-26 11:58:23 -0500671 if(size < 0)
672 {
673 return error(GL_INVALID_VALUE);
674 }
John Bauman66b8ab22014-05-06 15:57:45 -0400675
Alexis Hetued306182015-04-02 12:02:28 -0400676 egl::GLint clientVersion = egl::getClientVersion();
677
Nicolas Capensf160b172014-11-26 11:58:23 -0500678 switch(usage)
679 {
680 case GL_STREAM_DRAW:
681 case GL_STATIC_DRAW:
682 case GL_DYNAMIC_DRAW:
683 break;
Alexis Hetued306182015-04-02 12:02:28 -0400684 case GL_STREAM_READ:
685 case GL_STREAM_COPY:
686 case GL_STATIC_READ:
687 case GL_STATIC_COPY:
688 case GL_DYNAMIC_READ:
689 case GL_DYNAMIC_COPY:
690 if(clientVersion < 3)
691 {
692 return error(GL_INVALID_ENUM);
693 }
694 break;
Nicolas Capensf160b172014-11-26 11:58:23 -0500695 default:
696 return error(GL_INVALID_ENUM);
697 }
John Bauman66b8ab22014-05-06 15:57:45 -0400698
Nicolas Capensf160b172014-11-26 11:58:23 -0500699 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400700
Nicolas Capensf160b172014-11-26 11:58:23 -0500701 if(context)
702 {
Nicolas Capensb4d30d92015-12-04 12:09:28 -0500703 es2::Buffer *buffer = nullptr;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400704 if(!context->getBuffer(target, &buffer))
Nicolas Capensf160b172014-11-26 11:58:23 -0500705 {
Nicolas Capensf160b172014-11-26 11:58:23 -0500706 return error(GL_INVALID_ENUM);
707 }
John Bauman66b8ab22014-05-06 15:57:45 -0400708
Nicolas Capensf160b172014-11-26 11:58:23 -0500709 if(!buffer)
710 {
Alexis Hetued306182015-04-02 12:02:28 -0400711 // A null buffer means that "0" is bound to the requested buffer target
Nicolas Capensf160b172014-11-26 11:58:23 -0500712 return error(GL_INVALID_OPERATION);
713 }
John Bauman66b8ab22014-05-06 15:57:45 -0400714
Nicolas Capensf160b172014-11-26 11:58:23 -0500715 buffer->bufferData(data, size, usage);
716 }
John Bauman66b8ab22014-05-06 15:57:45 -0400717}
718
Nicolas Capenseb195b62015-04-28 17:18:42 -0700719void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
Nicolas Capens54b721d2014-12-12 12:50:04 -0500720{
721 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
722 offset = static_cast<GLint>(offset);
Nicolas Capens4cadfe32014-12-10 22:26:26 -0500723
Nicolas Capens4be33702015-04-28 15:13:30 -0700724 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -0500725 target, offset, size, data);
John Bauman66b8ab22014-05-06 15:57:45 -0400726
Nicolas Capensf160b172014-11-26 11:58:23 -0500727 if(size < 0 || offset < 0)
728 {
729 return error(GL_INVALID_VALUE);
730 }
John Bauman66b8ab22014-05-06 15:57:45 -0400731
Nicolas Capensf160b172014-11-26 11:58:23 -0500732 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400733
Nicolas Capensf160b172014-11-26 11:58:23 -0500734 if(context)
735 {
Nicolas Capensb4d30d92015-12-04 12:09:28 -0500736 es2::Buffer *buffer = nullptr;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -0400737 if(!context->getBuffer(target, &buffer))
Nicolas Capensf160b172014-11-26 11:58:23 -0500738 {
Nicolas Capensf160b172014-11-26 11:58:23 -0500739 return error(GL_INVALID_ENUM);
740 }
John Bauman66b8ab22014-05-06 15:57:45 -0400741
Nicolas Capensf160b172014-11-26 11:58:23 -0500742 if(!buffer)
743 {
Alexis Hetued306182015-04-02 12:02:28 -0400744 // A null buffer means that "0" is bound to the requested buffer target
Nicolas Capensf160b172014-11-26 11:58:23 -0500745 return error(GL_INVALID_OPERATION);
746 }
John Bauman66b8ab22014-05-06 15:57:45 -0400747
Nicolas Capensf160b172014-11-26 11:58:23 -0500748 if((size_t)size + offset > buffer->size())
John Bauman66b8ab22014-05-06 15:57:45 -0400749 {
750 return error(GL_INVALID_VALUE);
751 }
752
Nicolas Capensf160b172014-11-26 11:58:23 -0500753 buffer->bufferSubData(data, size, offset);
754 }
755}
John Bauman66b8ab22014-05-06 15:57:45 -0400756
Nicolas Capenseb195b62015-04-28 17:18:42 -0700757GLenum CheckFramebufferStatus(GLenum target)
Nicolas Capensf160b172014-11-26 11:58:23 -0500758{
759 TRACE("(GLenum target = 0x%X)", target);
760
761 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
762 {
763 return error(GL_INVALID_ENUM, 0);
764 }
765
766 es2::Context *context = es2::getContext();
767
768 if(context)
769 {
770 es2::Framebuffer *framebuffer = NULL;
771 if(target == GL_READ_FRAMEBUFFER_ANGLE)
772 {
773 framebuffer = context->getReadFramebuffer();
774 }
775 else
776 {
777 framebuffer = context->getDrawFramebuffer();
778 }
779
780 return framebuffer->completeness();
781 }
782
783 return 0;
784}
785
Nicolas Capenseb195b62015-04-28 17:18:42 -0700786void Clear(GLbitfield mask)
Nicolas Capensf160b172014-11-26 11:58:23 -0500787{
788 TRACE("(GLbitfield mask = %X)", mask);
789
790 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
791 {
792 return error(GL_INVALID_VALUE);
793 }
794
795 es2::Context *context = es2::getContext();
796
797 if(context)
798 {
799 context->clear(mask);
800 }
John Bauman66b8ab22014-05-06 15:57:45 -0400801}
802
Nicolas Capenseb195b62015-04-28 17:18:42 -0700803void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
John Bauman66b8ab22014-05-06 15:57:45 -0400804{
Nicolas Capensf160b172014-11-26 11:58:23 -0500805 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
806 red, green, blue, alpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400807
Nicolas Capensf160b172014-11-26 11:58:23 -0500808 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400809
Nicolas Capensf160b172014-11-26 11:58:23 -0500810 if(context)
811 {
812 context->setClearColor(red, green, blue, alpha);
813 }
John Bauman66b8ab22014-05-06 15:57:45 -0400814}
815
Nicolas Capenseb195b62015-04-28 17:18:42 -0700816void ClearDepthf(GLclampf depth)
John Bauman66b8ab22014-05-06 15:57:45 -0400817{
Nicolas Capensf160b172014-11-26 11:58:23 -0500818 TRACE("(GLclampf depth = %f)", depth);
John Bauman66b8ab22014-05-06 15:57:45 -0400819
Nicolas Capensf160b172014-11-26 11:58:23 -0500820 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400821
Nicolas Capensf160b172014-11-26 11:58:23 -0500822 if(context)
823 {
824 context->setClearDepth(depth);
825 }
John Bauman66b8ab22014-05-06 15:57:45 -0400826}
827
Nicolas Capenseb195b62015-04-28 17:18:42 -0700828void ClearStencil(GLint s)
John Bauman66b8ab22014-05-06 15:57:45 -0400829{
Nicolas Capensf160b172014-11-26 11:58:23 -0500830 TRACE("(GLint s = %d)", s);
John Bauman66b8ab22014-05-06 15:57:45 -0400831
Nicolas Capensf160b172014-11-26 11:58:23 -0500832 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400833
Nicolas Capensf160b172014-11-26 11:58:23 -0500834 if(context)
835 {
836 context->setClearStencil(s);
837 }
John Bauman66b8ab22014-05-06 15:57:45 -0400838}
839
Nicolas Capenseb195b62015-04-28 17:18:42 -0700840void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
John Bauman66b8ab22014-05-06 15:57:45 -0400841{
Nicolas Capensf160b172014-11-26 11:58:23 -0500842 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
843 red, green, blue, alpha);
John Bauman66b8ab22014-05-06 15:57:45 -0400844
Nicolas Capensf160b172014-11-26 11:58:23 -0500845 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400846
Nicolas Capensf160b172014-11-26 11:58:23 -0500847 if(context)
848 {
849 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
850 }
John Bauman66b8ab22014-05-06 15:57:45 -0400851}
852
Nicolas Capenseb195b62015-04-28 17:18:42 -0700853void CompileShader(GLuint shader)
John Bauman66b8ab22014-05-06 15:57:45 -0400854{
Nicolas Capensf160b172014-11-26 11:58:23 -0500855 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400856
Nicolas Capensf160b172014-11-26 11:58:23 -0500857 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400858
Nicolas Capensf160b172014-11-26 11:58:23 -0500859 if(context)
860 {
861 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -0400862
Nicolas Capensf160b172014-11-26 11:58:23 -0500863 if(!shaderObject)
864 {
865 if(context->getProgram(shader))
866 {
867 return error(GL_INVALID_OPERATION);
868 }
869 else
870 {
871 return error(GL_INVALID_VALUE);
872 }
873 }
John Bauman66b8ab22014-05-06 15:57:45 -0400874
Nicolas Capensf160b172014-11-26 11:58:23 -0500875 shaderObject->compile();
876 }
John Bauman66b8ab22014-05-06 15:57:45 -0400877}
878
Nicolas Capenseb195b62015-04-28 17:18:42 -0700879void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
880 GLint border, GLsizei imageSize, const GLvoid* data)
John Bauman66b8ab22014-05-06 15:57:45 -0400881{
Nicolas Capensf160b172014-11-26 11:58:23 -0500882 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -0700883 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -0500884 target, level, internalformat, width, height, border, imageSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -0400885
Nicolas Capensf160b172014-11-26 11:58:23 -0500886 if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
887 {
888 return error(GL_INVALID_VALUE);
889 }
John Bauman66b8ab22014-05-06 15:57:45 -0400890
Nicolas Capensf160b172014-11-26 11:58:23 -0500891 switch(internalformat)
892 {
Nicolas Capensf160b172014-11-26 11:58:23 -0500893 case GL_DEPTH_COMPONENT:
894 case GL_DEPTH_COMPONENT16:
895 case GL_DEPTH_COMPONENT32_OES:
896 case GL_DEPTH_STENCIL_OES:
897 case GL_DEPTH24_STENCIL8_OES:
898 return error(GL_INVALID_OPERATION);
899 default:
Alexis Hetu460e41f2015-09-01 10:58:37 -0400900 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -0400901 GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
902 if(validationError != GL_NONE)
Alexis Hetu460e41f2015-09-01 10:58:37 -0400903 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -0400904 return error(validationError);
Alexis Hetu460e41f2015-09-01 10:58:37 -0400905 }
906 }
907 break;
Nicolas Capensf160b172014-11-26 11:58:23 -0500908 }
John Bauman66b8ab22014-05-06 15:57:45 -0400909
Nicolas Capensf160b172014-11-26 11:58:23 -0500910 if(border != 0)
911 {
912 return error(GL_INVALID_VALUE);
913 }
John Bauman66b8ab22014-05-06 15:57:45 -0400914
Nicolas Capensf160b172014-11-26 11:58:23 -0500915 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400916
Nicolas Capensf160b172014-11-26 11:58:23 -0500917 if(context)
918 {
Alexis Hetub027aa92015-01-19 15:56:12 -0500919 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -0500920 {
921 return error(GL_INVALID_VALUE);
922 }
John Bauman66b8ab22014-05-06 15:57:45 -0400923
Nicolas Capensf160b172014-11-26 11:58:23 -0500924 switch(target)
925 {
926 case GL_TEXTURE_2D:
927 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
928 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
929 {
930 return error(GL_INVALID_VALUE);
931 }
932 break;
933 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
934 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
935 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
936 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
937 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
938 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
939 if(width != height)
940 {
941 return error(GL_INVALID_VALUE);
942 }
John Bauman66b8ab22014-05-06 15:57:45 -0400943
Nicolas Capensf160b172014-11-26 11:58:23 -0500944 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
945 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
946 {
947 return error(GL_INVALID_VALUE);
948 }
949 break;
950 default:
951 return error(GL_INVALID_ENUM);
952 }
John Bauman66b8ab22014-05-06 15:57:45 -0400953
Nicolas Capensdeda34b2015-04-28 15:21:53 -0700954 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))
Nicolas Capensf160b172014-11-26 11:58:23 -0500955 {
956 return error(GL_INVALID_VALUE);
957 }
John Bauman66b8ab22014-05-06 15:57:45 -0400958
Nicolas Capensf160b172014-11-26 11:58:23 -0500959 if(target == GL_TEXTURE_2D)
960 {
961 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -0400962
Nicolas Capensf160b172014-11-26 11:58:23 -0500963 if(!texture)
964 {
965 return error(GL_INVALID_OPERATION);
966 }
John Bauman66b8ab22014-05-06 15:57:45 -0400967
Nicolas Capensf160b172014-11-26 11:58:23 -0500968 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
969 }
970 else
971 {
972 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -0400973
Nicolas Capensf160b172014-11-26 11:58:23 -0500974 if(!texture)
975 {
976 return error(GL_INVALID_OPERATION);
977 }
John Bauman66b8ab22014-05-06 15:57:45 -0400978
Nicolas Capensf160b172014-11-26 11:58:23 -0500979 switch(target)
980 {
981 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
982 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
983 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
984 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
985 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
986 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
987 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
988 break;
Nicolas Capens3713cd42015-06-22 10:41:54 -0400989 default: UNREACHABLE(target);
Nicolas Capensf160b172014-11-26 11:58:23 -0500990 }
991 }
992 }
John Bauman66b8ab22014-05-06 15:57:45 -0400993}
994
Nicolas Capenseb195b62015-04-28 17:18:42 -0700995void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
996 GLenum format, GLsizei imageSize, const GLvoid* data)
John Bauman66b8ab22014-05-06 15:57:45 -0400997{
Nicolas Capensf160b172014-11-26 11:58:23 -0500998 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
999 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07001000 "GLsizei imageSize = %d, const GLvoid* data = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05001001 target, level, xoffset, yoffset, width, height, format, imageSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -04001002
Nicolas Capensf160b172014-11-26 11:58:23 -05001003 if(!es2::IsTextureTarget(target))
1004 {
1005 return error(GL_INVALID_ENUM);
1006 }
John Bauman66b8ab22014-05-06 15:57:45 -04001007
Nicolas Capensf160b172014-11-26 11:58:23 -05001008 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
1009 {
1010 return error(GL_INVALID_VALUE);
1011 }
John Bauman66b8ab22014-05-06 15:57:45 -04001012
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04001013 GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
1014 if(validationError != GL_NONE)
Nicolas Capensf160b172014-11-26 11:58:23 -05001015 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04001016 return error(validationError);
Nicolas Capensf160b172014-11-26 11:58:23 -05001017 }
John Bauman66b8ab22014-05-06 15:57:45 -04001018
Nicolas Capensf160b172014-11-26 11:58:23 -05001019 if(width == 0 || height == 0 || data == NULL)
1020 {
1021 return;
1022 }
John Bauman66b8ab22014-05-06 15:57:45 -04001023
Nicolas Capensf160b172014-11-26 11:58:23 -05001024 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001025
Nicolas Capensf160b172014-11-26 11:58:23 -05001026 if(context)
1027 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001028 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05001029 {
1030 return error(GL_INVALID_VALUE);
1031 }
John Bauman66b8ab22014-05-06 15:57:45 -04001032
Nicolas Capensdeda34b2015-04-28 15:21:53 -07001033 if(imageSize != egl::ComputeCompressedSize(width, height, format))
Nicolas Capensf160b172014-11-26 11:58:23 -05001034 {
1035 return error(GL_INVALID_VALUE);
1036 }
John Bauman66b8ab22014-05-06 15:57:45 -04001037
Nicolas Capensf160b172014-11-26 11:58:23 -05001038 if(xoffset % 4 != 0 || yoffset % 4 != 0)
1039 {
1040 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
1041 return error(GL_INVALID_OPERATION);
1042 }
John Bauman66b8ab22014-05-06 15:57:45 -04001043
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04001044 GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_NONE);
1045
Nicolas Capensf160b172014-11-26 11:58:23 -05001046 if(target == GL_TEXTURE_2D)
1047 {
1048 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04001049
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04001050 GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
1051
1052 if(validationError == GL_NONE)
Nicolas Capensf160b172014-11-26 11:58:23 -05001053 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04001054 texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
1055 }
1056 else
1057 {
1058 return error(validationError);
Nicolas Capensf160b172014-11-26 11:58:23 -05001059 }
1060 }
1061 else if(es2::IsCubemapTextureTarget(target))
1062 {
1063 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04001064
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04001065 GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
1066
1067 if(validationError == GL_NONE)
Nicolas Capensf160b172014-11-26 11:58:23 -05001068 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04001069 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);
1070 }
1071 else
1072 {
1073 return error(validationError);
Nicolas Capensf160b172014-11-26 11:58:23 -05001074 }
1075 }
Nicolas Capens3713cd42015-06-22 10:41:54 -04001076 else UNREACHABLE(target);
Nicolas Capensf160b172014-11-26 11:58:23 -05001077 }
John Bauman66b8ab22014-05-06 15:57:45 -04001078}
1079
Nicolas Capenseb195b62015-04-28 17:18:42 -07001080void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
John Bauman66b8ab22014-05-06 15:57:45 -04001081{
Nicolas Capensf160b172014-11-26 11:58:23 -05001082 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
1083 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
1084 target, level, internalformat, x, y, width, height, border);
John Bauman66b8ab22014-05-06 15:57:45 -04001085
Nicolas Capensf160b172014-11-26 11:58:23 -05001086 if(!validImageSize(level, width, height))
1087 {
1088 return error(GL_INVALID_VALUE);
1089 }
John Bauman66b8ab22014-05-06 15:57:45 -04001090
Nicolas Capensf160b172014-11-26 11:58:23 -05001091 if(border != 0)
1092 {
1093 return error(GL_INVALID_VALUE);
1094 }
John Bauman66b8ab22014-05-06 15:57:45 -04001095
Nicolas Capensf160b172014-11-26 11:58:23 -05001096 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001097
Nicolas Capensf160b172014-11-26 11:58:23 -05001098 if(context)
1099 {
1100 switch(target)
1101 {
1102 case GL_TEXTURE_2D:
1103 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
1104 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
1105 {
1106 return error(GL_INVALID_VALUE);
1107 }
1108 break;
1109 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1110 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1111 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1112 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1113 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1114 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1115 if(width != height)
1116 {
1117 return error(GL_INVALID_VALUE);
1118 }
John Bauman66b8ab22014-05-06 15:57:45 -04001119
Nicolas Capensf160b172014-11-26 11:58:23 -05001120 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1121 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
1122 {
1123 return error(GL_INVALID_VALUE);
1124 }
1125 break;
1126 default:
1127 return error(GL_INVALID_ENUM);
1128 }
John Bauman66b8ab22014-05-06 15:57:45 -04001129
Nicolas Capensf160b172014-11-26 11:58:23 -05001130 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
John Bauman66b8ab22014-05-06 15:57:45 -04001131
Nicolas Capensf160b172014-11-26 11:58:23 -05001132 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1133 {
1134 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1135 }
John Bauman66b8ab22014-05-06 15:57:45 -04001136
Alexis Hetu1b2f6282015-04-16 16:27:42 -04001137 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
1138
1139 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
Nicolas Capensf160b172014-11-26 11:58:23 -05001140 {
1141 return error(GL_INVALID_OPERATION);
1142 }
John Bauman66b8ab22014-05-06 15:57:45 -04001143
Nicolas Capensf160b172014-11-26 11:58:23 -05001144 GLenum colorbufferFormat = source->getFormat();
John Bauman66b8ab22014-05-06 15:57:45 -04001145
Alexis Hetub027aa92015-01-19 15:56:12 -05001146 if(!validateColorBufferFormat(internalformat, colorbufferFormat))
Nicolas Capensf160b172014-11-26 11:58:23 -05001147 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001148 return;
Nicolas Capensf160b172014-11-26 11:58:23 -05001149 }
John Bauman66b8ab22014-05-06 15:57:45 -04001150
Nicolas Capensf160b172014-11-26 11:58:23 -05001151 if(target == GL_TEXTURE_2D)
1152 {
1153 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04001154
Nicolas Capensf160b172014-11-26 11:58:23 -05001155 if(!texture)
1156 {
1157 return error(GL_INVALID_OPERATION);
1158 }
John Bauman66b8ab22014-05-06 15:57:45 -04001159
Nicolas Capensf160b172014-11-26 11:58:23 -05001160 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
1161 }
1162 else if(es2::IsCubemapTextureTarget(target))
1163 {
1164 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04001165
Nicolas Capensf160b172014-11-26 11:58:23 -05001166 if(!texture)
1167 {
1168 return error(GL_INVALID_OPERATION);
1169 }
John Bauman66b8ab22014-05-06 15:57:45 -04001170
Nicolas Capensf160b172014-11-26 11:58:23 -05001171 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
1172 }
Nicolas Capens3713cd42015-06-22 10:41:54 -04001173 else UNREACHABLE(target);
Nicolas Capensf160b172014-11-26 11:58:23 -05001174 }
John Bauman66b8ab22014-05-06 15:57:45 -04001175}
1176
Nicolas Capenseb195b62015-04-28 17:18:42 -07001177void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
John Bauman66b8ab22014-05-06 15:57:45 -04001178{
Nicolas Capensf160b172014-11-26 11:58:23 -05001179 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1180 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
1181 target, level, xoffset, yoffset, x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04001182
Nicolas Capensf160b172014-11-26 11:58:23 -05001183 if(!es2::IsTextureTarget(target))
1184 {
1185 return error(GL_INVALID_ENUM);
1186 }
John Bauman66b8ab22014-05-06 15:57:45 -04001187
Nicolas Capensf160b172014-11-26 11:58:23 -05001188 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
1189 {
1190 return error(GL_INVALID_VALUE);
1191 }
John Bauman66b8ab22014-05-06 15:57:45 -04001192
Nicolas Capensf160b172014-11-26 11:58:23 -05001193 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1194 {
1195 return error(GL_INVALID_VALUE);
1196 }
John Bauman66b8ab22014-05-06 15:57:45 -04001197
Nicolas Capensf160b172014-11-26 11:58:23 -05001198 if(width == 0 || height == 0)
1199 {
1200 return;
1201 }
John Bauman66b8ab22014-05-06 15:57:45 -04001202
Nicolas Capensf160b172014-11-26 11:58:23 -05001203 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001204
Nicolas Capensf160b172014-11-26 11:58:23 -05001205 if(context)
1206 {
Alexis Hetub027aa92015-01-19 15:56:12 -05001207 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05001208 {
1209 return error(GL_INVALID_VALUE);
1210 }
John Bauman66b8ab22014-05-06 15:57:45 -04001211
Nicolas Capensf160b172014-11-26 11:58:23 -05001212 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
John Bauman66b8ab22014-05-06 15:57:45 -04001213
Nicolas Capensf160b172014-11-26 11:58:23 -05001214 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1215 {
1216 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1217 }
John Bauman66b8ab22014-05-06 15:57:45 -04001218
Alexis Hetu1b2f6282015-04-16 16:27:42 -04001219 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
1220
1221 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
Nicolas Capensf160b172014-11-26 11:58:23 -05001222 {
1223 return error(GL_INVALID_OPERATION);
1224 }
John Bauman66b8ab22014-05-06 15:57:45 -04001225
Nicolas Capensf160b172014-11-26 11:58:23 -05001226 es2::Texture *texture = NULL;
John Bauman66b8ab22014-05-06 15:57:45 -04001227
Nicolas Capensf160b172014-11-26 11:58:23 -05001228 if(target == GL_TEXTURE_2D)
1229 {
1230 texture = context->getTexture2D();
1231 }
1232 else if(es2::IsCubemapTextureTarget(target))
1233 {
1234 texture = context->getTextureCubeMap();
1235 }
Nicolas Capens3713cd42015-06-22 10:41:54 -04001236 else UNREACHABLE(target);
John Bauman66b8ab22014-05-06 15:57:45 -04001237
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04001238 GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture);
1239 if(validationError != GL_NONE)
Nicolas Capensf160b172014-11-26 11:58:23 -05001240 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04001241 return error(validationError);
Nicolas Capensf160b172014-11-26 11:58:23 -05001242 }
1243
Alexis Hetub027aa92015-01-19 15:56:12 -05001244 texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
Nicolas Capensf160b172014-11-26 11:58:23 -05001245 }
John Bauman66b8ab22014-05-06 15:57:45 -04001246}
1247
Nicolas Capenseb195b62015-04-28 17:18:42 -07001248GLuint CreateProgram(void)
John Bauman66b8ab22014-05-06 15:57:45 -04001249{
Nicolas Capensf160b172014-11-26 11:58:23 -05001250 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04001251
Nicolas Capensf160b172014-11-26 11:58:23 -05001252 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001253
Nicolas Capensf160b172014-11-26 11:58:23 -05001254 if(context)
1255 {
1256 return context->createProgram();
1257 }
John Bauman66b8ab22014-05-06 15:57:45 -04001258
Nicolas Capensf160b172014-11-26 11:58:23 -05001259 return 0;
John Bauman66b8ab22014-05-06 15:57:45 -04001260}
1261
Nicolas Capenseb195b62015-04-28 17:18:42 -07001262GLuint CreateShader(GLenum type)
John Bauman66b8ab22014-05-06 15:57:45 -04001263{
Nicolas Capensf160b172014-11-26 11:58:23 -05001264 TRACE("(GLenum type = 0x%X)", type);
John Bauman66b8ab22014-05-06 15:57:45 -04001265
Nicolas Capensf160b172014-11-26 11:58:23 -05001266 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001267
Nicolas Capensf160b172014-11-26 11:58:23 -05001268 if(context)
1269 {
1270 switch(type)
1271 {
1272 case GL_FRAGMENT_SHADER:
1273 case GL_VERTEX_SHADER:
1274 return context->createShader(type);
1275 default:
1276 return error(GL_INVALID_ENUM, 0);
1277 }
1278 }
John Bauman66b8ab22014-05-06 15:57:45 -04001279
Nicolas Capensf160b172014-11-26 11:58:23 -05001280 return 0;
John Bauman66b8ab22014-05-06 15:57:45 -04001281}
1282
Nicolas Capenseb195b62015-04-28 17:18:42 -07001283void CullFace(GLenum mode)
John Bauman66b8ab22014-05-06 15:57:45 -04001284{
Nicolas Capensf160b172014-11-26 11:58:23 -05001285 TRACE("(GLenum mode = 0x%X)", mode);
John Bauman66b8ab22014-05-06 15:57:45 -04001286
Nicolas Capensf160b172014-11-26 11:58:23 -05001287 switch(mode)
1288 {
1289 case GL_FRONT:
1290 case GL_BACK:
1291 case GL_FRONT_AND_BACK:
1292 {
1293 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001294
Nicolas Capensf160b172014-11-26 11:58:23 -05001295 if(context)
1296 {
1297 context->setCullMode(mode);
1298 }
1299 }
1300 break;
1301 default:
1302 return error(GL_INVALID_ENUM);
1303 }
John Bauman66b8ab22014-05-06 15:57:45 -04001304}
1305
Nicolas Capenseb195b62015-04-28 17:18:42 -07001306void DeleteBuffers(GLsizei n, const GLuint* buffers)
John Bauman66b8ab22014-05-06 15:57:45 -04001307{
Nicolas Capens4be33702015-04-28 15:13:30 -07001308 TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
John Bauman66b8ab22014-05-06 15:57:45 -04001309
Nicolas Capensf160b172014-11-26 11:58:23 -05001310 if(n < 0)
1311 {
1312 return error(GL_INVALID_VALUE);
1313 }
John Bauman66b8ab22014-05-06 15:57:45 -04001314
Nicolas Capensf160b172014-11-26 11:58:23 -05001315 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001316
Nicolas Capensf160b172014-11-26 11:58:23 -05001317 if(context)
1318 {
1319 for(int i = 0; i < n; i++)
1320 {
1321 context->deleteBuffer(buffers[i]);
1322 }
1323 }
John Bauman66b8ab22014-05-06 15:57:45 -04001324}
1325
Nicolas Capenseb195b62015-04-28 17:18:42 -07001326void DeleteFencesNV(GLsizei n, const GLuint* fences)
John Bauman66b8ab22014-05-06 15:57:45 -04001327{
Nicolas Capens4be33702015-04-28 15:13:30 -07001328 TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);
John Bauman66b8ab22014-05-06 15:57:45 -04001329
Nicolas Capensf160b172014-11-26 11:58:23 -05001330 if(n < 0)
1331 {
1332 return error(GL_INVALID_VALUE);
1333 }
John Bauman66b8ab22014-05-06 15:57:45 -04001334
Nicolas Capensf160b172014-11-26 11:58:23 -05001335 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001336
Nicolas Capensf160b172014-11-26 11:58:23 -05001337 if(context)
1338 {
1339 for(int i = 0; i < n; i++)
1340 {
1341 context->deleteFence(fences[i]);
1342 }
1343 }
John Bauman66b8ab22014-05-06 15:57:45 -04001344}
1345
Nicolas Capenseb195b62015-04-28 17:18:42 -07001346void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
John Bauman66b8ab22014-05-06 15:57:45 -04001347{
Nicolas Capens4be33702015-04-28 15:13:30 -07001348 TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04001349
Nicolas Capensf160b172014-11-26 11:58:23 -05001350 if(n < 0)
1351 {
1352 return error(GL_INVALID_VALUE);
1353 }
John Bauman66b8ab22014-05-06 15:57:45 -04001354
Nicolas Capensf160b172014-11-26 11:58:23 -05001355 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001356
Nicolas Capensf160b172014-11-26 11:58:23 -05001357 if(context)
1358 {
1359 for(int i = 0; i < n; i++)
1360 {
1361 if(framebuffers[i] != 0)
1362 {
1363 context->deleteFramebuffer(framebuffers[i]);
1364 }
1365 }
1366 }
John Bauman66b8ab22014-05-06 15:57:45 -04001367}
1368
Nicolas Capenseb195b62015-04-28 17:18:42 -07001369void DeleteProgram(GLuint program)
John Bauman66b8ab22014-05-06 15:57:45 -04001370{
Nicolas Capensf160b172014-11-26 11:58:23 -05001371 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04001372
Nicolas Capensf160b172014-11-26 11:58:23 -05001373 if(program == 0)
1374 {
1375 return;
1376 }
John Bauman66b8ab22014-05-06 15:57:45 -04001377
Nicolas Capensf160b172014-11-26 11:58:23 -05001378 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001379
Nicolas Capensf160b172014-11-26 11:58:23 -05001380 if(context)
1381 {
1382 if(!context->getProgram(program))
1383 {
1384 if(context->getShader(program))
1385 {
1386 return error(GL_INVALID_OPERATION);
1387 }
1388 else
1389 {
1390 return error(GL_INVALID_VALUE);
1391 }
1392 }
John Bauman66b8ab22014-05-06 15:57:45 -04001393
Nicolas Capensf160b172014-11-26 11:58:23 -05001394 context->deleteProgram(program);
1395 }
John Bauman66b8ab22014-05-06 15:57:45 -04001396}
1397
Nicolas Capenseb195b62015-04-28 17:18:42 -07001398void DeleteQueriesEXT(GLsizei n, const GLuint *ids)
John Bauman66b8ab22014-05-06 15:57:45 -04001399{
Nicolas Capens4be33702015-04-28 15:13:30 -07001400 TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
John Bauman66b8ab22014-05-06 15:57:45 -04001401
Nicolas Capensf160b172014-11-26 11:58:23 -05001402 if(n < 0)
1403 {
1404 return error(GL_INVALID_VALUE);
1405 }
John Bauman66b8ab22014-05-06 15:57:45 -04001406
Nicolas Capensf160b172014-11-26 11:58:23 -05001407 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001408
Nicolas Capensf160b172014-11-26 11:58:23 -05001409 if(context)
1410 {
1411 for(int i = 0; i < n; i++)
1412 {
1413 context->deleteQuery(ids[i]);
1414 }
1415 }
John Bauman66b8ab22014-05-06 15:57:45 -04001416}
1417
Nicolas Capenseb195b62015-04-28 17:18:42 -07001418void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
John Bauman66b8ab22014-05-06 15:57:45 -04001419{
Nicolas Capens4be33702015-04-28 15:13:30 -07001420 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04001421
Nicolas Capensf160b172014-11-26 11:58:23 -05001422 if(n < 0)
1423 {
1424 return error(GL_INVALID_VALUE);
1425 }
John Bauman66b8ab22014-05-06 15:57:45 -04001426
Nicolas Capensf160b172014-11-26 11:58:23 -05001427 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001428
Nicolas Capensf160b172014-11-26 11:58:23 -05001429 if(context)
1430 {
1431 for(int i = 0; i < n; i++)
1432 {
1433 context->deleteRenderbuffer(renderbuffers[i]);
1434 }
1435 }
John Bauman66b8ab22014-05-06 15:57:45 -04001436}
1437
Nicolas Capenseb195b62015-04-28 17:18:42 -07001438void DeleteShader(GLuint shader)
John Bauman66b8ab22014-05-06 15:57:45 -04001439{
Nicolas Capensf160b172014-11-26 11:58:23 -05001440 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -04001441
Nicolas Capensf160b172014-11-26 11:58:23 -05001442 if(shader == 0)
1443 {
1444 return;
1445 }
John Bauman66b8ab22014-05-06 15:57:45 -04001446
Nicolas Capensf160b172014-11-26 11:58:23 -05001447 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001448
Nicolas Capensf160b172014-11-26 11:58:23 -05001449 if(context)
1450 {
1451 if(!context->getShader(shader))
1452 {
1453 if(context->getProgram(shader))
1454 {
1455 return error(GL_INVALID_OPERATION);
1456 }
1457 else
1458 {
1459 return error(GL_INVALID_VALUE);
1460 }
1461 }
John Bauman66b8ab22014-05-06 15:57:45 -04001462
Nicolas Capensf160b172014-11-26 11:58:23 -05001463 context->deleteShader(shader);
1464 }
John Bauman66b8ab22014-05-06 15:57:45 -04001465}
1466
Nicolas Capenseb195b62015-04-28 17:18:42 -07001467void DeleteTextures(GLsizei n, const GLuint* textures)
John Bauman66b8ab22014-05-06 15:57:45 -04001468{
Nicolas Capens4be33702015-04-28 15:13:30 -07001469 TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
John Bauman66b8ab22014-05-06 15:57:45 -04001470
Nicolas Capensf160b172014-11-26 11:58:23 -05001471 if(n < 0)
1472 {
1473 return error(GL_INVALID_VALUE);
1474 }
John Bauman66b8ab22014-05-06 15:57:45 -04001475
Nicolas Capensf160b172014-11-26 11:58:23 -05001476 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001477
Nicolas Capensf160b172014-11-26 11:58:23 -05001478 if(context)
1479 {
1480 for(int i = 0; i < n; i++)
1481 {
1482 if(textures[i] != 0)
1483 {
1484 context->deleteTexture(textures[i]);
1485 }
1486 }
1487 }
John Bauman66b8ab22014-05-06 15:57:45 -04001488}
1489
Nicolas Capenseb195b62015-04-28 17:18:42 -07001490void DepthFunc(GLenum func)
John Bauman66b8ab22014-05-06 15:57:45 -04001491{
Nicolas Capensf160b172014-11-26 11:58:23 -05001492 TRACE("(GLenum func = 0x%X)", func);
John Bauman66b8ab22014-05-06 15:57:45 -04001493
Nicolas Capensf160b172014-11-26 11:58:23 -05001494 switch(func)
1495 {
1496 case GL_NEVER:
1497 case GL_ALWAYS:
1498 case GL_LESS:
1499 case GL_LEQUAL:
1500 case GL_EQUAL:
1501 case GL_GREATER:
1502 case GL_GEQUAL:
1503 case GL_NOTEQUAL:
1504 break;
1505 default:
1506 return error(GL_INVALID_ENUM);
1507 }
John Bauman66b8ab22014-05-06 15:57:45 -04001508
Nicolas Capensf160b172014-11-26 11:58:23 -05001509 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001510
Nicolas Capensf160b172014-11-26 11:58:23 -05001511 if(context)
1512 {
1513 context->setDepthFunc(func);
1514 }
John Bauman66b8ab22014-05-06 15:57:45 -04001515}
1516
Nicolas Capenseb195b62015-04-28 17:18:42 -07001517void DepthMask(GLboolean flag)
John Bauman66b8ab22014-05-06 15:57:45 -04001518{
Nicolas Capensf160b172014-11-26 11:58:23 -05001519 TRACE("(GLboolean flag = %d)", flag);
John Bauman66b8ab22014-05-06 15:57:45 -04001520
Nicolas Capensf160b172014-11-26 11:58:23 -05001521 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001522
Nicolas Capensf160b172014-11-26 11:58:23 -05001523 if(context)
1524 {
1525 context->setDepthMask(flag != GL_FALSE);
1526 }
John Bauman66b8ab22014-05-06 15:57:45 -04001527}
1528
Nicolas Capenseb195b62015-04-28 17:18:42 -07001529void DepthRangef(GLclampf zNear, GLclampf zFar)
John Bauman66b8ab22014-05-06 15:57:45 -04001530{
Nicolas Capensf160b172014-11-26 11:58:23 -05001531 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
John Bauman66b8ab22014-05-06 15:57:45 -04001532
Nicolas Capensf160b172014-11-26 11:58:23 -05001533 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001534
Nicolas Capensf160b172014-11-26 11:58:23 -05001535 if(context)
1536 {
1537 context->setDepthRange(zNear, zFar);
1538 }
John Bauman66b8ab22014-05-06 15:57:45 -04001539}
1540
Nicolas Capenseb195b62015-04-28 17:18:42 -07001541void DetachShader(GLuint program, GLuint shader)
John Bauman66b8ab22014-05-06 15:57:45 -04001542{
Nicolas Capensf160b172014-11-26 11:58:23 -05001543 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
John Bauman66b8ab22014-05-06 15:57:45 -04001544
Nicolas Capensf160b172014-11-26 11:58:23 -05001545 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001546
Nicolas Capensf160b172014-11-26 11:58:23 -05001547 if(context)
1548 {
John Bauman66b8ab22014-05-06 15:57:45 -04001549
Nicolas Capensf160b172014-11-26 11:58:23 -05001550 es2::Program *programObject = context->getProgram(program);
1551 es2::Shader *shaderObject = context->getShader(shader);
Nicolas Capens08e90f02014-11-21 12:49:12 -05001552
Nicolas Capensf160b172014-11-26 11:58:23 -05001553 if(!programObject)
1554 {
1555 es2::Shader *shaderByProgramHandle;
1556 shaderByProgramHandle = context->getShader(program);
1557 if(!shaderByProgramHandle)
1558 {
1559 return error(GL_INVALID_VALUE);
1560 }
1561 else
1562 {
1563 return error(GL_INVALID_OPERATION);
1564 }
1565 }
John Bauman66b8ab22014-05-06 15:57:45 -04001566
Nicolas Capensf160b172014-11-26 11:58:23 -05001567 if(!shaderObject)
1568 {
1569 es2::Program *programByShaderHandle = context->getProgram(shader);
1570 if(!programByShaderHandle)
1571 {
1572 return error(GL_INVALID_VALUE);
1573 }
1574 else
1575 {
1576 return error(GL_INVALID_OPERATION);
1577 }
1578 }
John Bauman66b8ab22014-05-06 15:57:45 -04001579
Nicolas Capensf160b172014-11-26 11:58:23 -05001580 if(!programObject->detachShader(shaderObject))
1581 {
1582 return error(GL_INVALID_OPERATION);
1583 }
1584 }
John Bauman66b8ab22014-05-06 15:57:45 -04001585}
1586
Nicolas Capenseb195b62015-04-28 17:18:42 -07001587void Disable(GLenum cap)
John Bauman66b8ab22014-05-06 15:57:45 -04001588{
Nicolas Capensf160b172014-11-26 11:58:23 -05001589 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04001590
Nicolas Capensf160b172014-11-26 11:58:23 -05001591 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001592
Nicolas Capensf160b172014-11-26 11:58:23 -05001593 if(context)
1594 {
1595 switch(cap)
1596 {
Nicolas Capensd55a0952015-08-03 16:36:58 -04001597 case GL_CULL_FACE: context->setCullFaceEnabled(false); break;
1598 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(false); break;
1599 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break;
1600 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(false); break;
1601 case GL_SCISSOR_TEST: context->setScissorTestEnabled(false); break;
1602 case GL_STENCIL_TEST: context->setStencilTestEnabled(false); break;
1603 case GL_DEPTH_TEST: context->setDepthTestEnabled(false); break;
1604 case GL_BLEND: context->setBlendEnabled(false); break;
1605 case GL_DITHER: context->setDitherEnabled(false); break;
1606 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(false); break;
1607 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscardEnabled(false); break;
Nicolas Capensf160b172014-11-26 11:58:23 -05001608 default:
1609 return error(GL_INVALID_ENUM);
1610 }
1611 }
John Bauman66b8ab22014-05-06 15:57:45 -04001612}
1613
Nicolas Capenseb195b62015-04-28 17:18:42 -07001614void DisableVertexAttribArray(GLuint index)
John Bauman66b8ab22014-05-06 15:57:45 -04001615{
Nicolas Capensf160b172014-11-26 11:58:23 -05001616 TRACE("(GLuint index = %d)", index);
John Bauman66b8ab22014-05-06 15:57:45 -04001617
Nicolas Capensf160b172014-11-26 11:58:23 -05001618 if(index >= es2::MAX_VERTEX_ATTRIBS)
1619 {
1620 return error(GL_INVALID_VALUE);
1621 }
John Bauman66b8ab22014-05-06 15:57:45 -04001622
Nicolas Capensf160b172014-11-26 11:58:23 -05001623 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001624
Nicolas Capensf160b172014-11-26 11:58:23 -05001625 if(context)
1626 {
Nicolas Capensd55a0952015-08-03 16:36:58 -04001627 context->setVertexAttribArrayEnabled(index, false);
Nicolas Capensf160b172014-11-26 11:58:23 -05001628 }
John Bauman66b8ab22014-05-06 15:57:45 -04001629}
1630
Nicolas Capenseb195b62015-04-28 17:18:42 -07001631void DrawArrays(GLenum mode, GLint first, GLsizei count)
John Bauman66b8ab22014-05-06 15:57:45 -04001632{
Nicolas Capensf160b172014-11-26 11:58:23 -05001633 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
John Bauman66b8ab22014-05-06 15:57:45 -04001634
Alexis Hetued306182015-04-02 12:02:28 -04001635 switch(mode)
1636 {
1637 case GL_POINTS:
1638 case GL_LINES:
1639 case GL_LINE_LOOP:
1640 case GL_LINE_STRIP:
1641 case GL_TRIANGLES:
1642 case GL_TRIANGLE_FAN:
1643 case GL_TRIANGLE_STRIP:
1644 break;
1645 default:
1646 return error(GL_INVALID_ENUM);
1647 }
1648
Nicolas Capensf160b172014-11-26 11:58:23 -05001649 if(count < 0 || first < 0)
1650 {
1651 return error(GL_INVALID_VALUE);
1652 }
John Bauman66b8ab22014-05-06 15:57:45 -04001653
Nicolas Capensf160b172014-11-26 11:58:23 -05001654 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001655
Nicolas Capensf160b172014-11-26 11:58:23 -05001656 if(context)
1657 {
Alexis Hetubcac6ff2015-04-22 08:29:22 -04001658 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1659 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1660 {
1661 return error(GL_INVALID_OPERATION);
1662 }
1663
Nicolas Capensf160b172014-11-26 11:58:23 -05001664 context->drawArrays(mode, first, count);
1665 }
John Bauman66b8ab22014-05-06 15:57:45 -04001666}
1667
Nicolas Capenseb195b62015-04-28 17:18:42 -07001668void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
John Bauman66b8ab22014-05-06 15:57:45 -04001669{
Nicolas Capens4be33702015-04-28 15:13:30 -07001670 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05001671 mode, count, type, indices);
John Bauman66b8ab22014-05-06 15:57:45 -04001672
Alexis Hetued306182015-04-02 12:02:28 -04001673 switch(mode)
1674 {
1675 case GL_POINTS:
1676 case GL_LINES:
1677 case GL_LINE_LOOP:
1678 case GL_LINE_STRIP:
1679 case GL_TRIANGLES:
1680 case GL_TRIANGLE_FAN:
1681 case GL_TRIANGLE_STRIP:
1682 break;
1683 default:
1684 return error(GL_INVALID_ENUM);
1685 }
1686
Nicolas Capensf160b172014-11-26 11:58:23 -05001687 if(count < 0)
1688 {
1689 return error(GL_INVALID_VALUE);
1690 }
John Bauman66b8ab22014-05-06 15:57:45 -04001691
Nicolas Capensf160b172014-11-26 11:58:23 -05001692 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001693
Nicolas Capensf160b172014-11-26 11:58:23 -05001694 if(context)
1695 {
Alexis Hetubcac6ff2015-04-22 08:29:22 -04001696 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1697 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1698 {
1699 return error(GL_INVALID_OPERATION);
1700 }
1701
Nicolas Capensf160b172014-11-26 11:58:23 -05001702 switch(type)
1703 {
1704 case GL_UNSIGNED_BYTE:
1705 case GL_UNSIGNED_SHORT:
1706 case GL_UNSIGNED_INT:
1707 break;
1708 default:
1709 return error(GL_INVALID_ENUM);
1710 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05001711
Nicolas Capens22d07662015-04-25 11:34:50 -07001712 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices);
Nicolas Capensf160b172014-11-26 11:58:23 -05001713 }
John Bauman66b8ab22014-05-06 15:57:45 -04001714}
1715
Nicolas Capenseb195b62015-04-28 17:18:42 -07001716void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Alexis Hetue8af6d12015-04-17 16:58:45 -04001717{
1718 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1719 mode, first, count, instanceCount);
1720
1721 switch(mode)
1722 {
1723 case GL_POINTS:
1724 case GL_LINES:
1725 case GL_LINE_LOOP:
1726 case GL_LINE_STRIP:
1727 case GL_TRIANGLES:
1728 case GL_TRIANGLE_FAN:
1729 case GL_TRIANGLE_STRIP:
1730 break;
1731 default:
1732 return error(GL_INVALID_ENUM);
1733 }
1734
1735 if(count < 0 || instanceCount < 0)
1736 {
1737 return error(GL_INVALID_VALUE);
1738 }
1739
1740 es2::Context *context = es2::getContext();
1741
1742 if(context)
1743 {
1744 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1745 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1746 {
1747 return error(GL_INVALID_OPERATION);
1748 }
1749
1750 context->drawArrays(mode, first, count, instanceCount);
1751 }
1752}
1753
Nicolas Capenseb195b62015-04-28 17:18:42 -07001754void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
Alexis Hetue8af6d12015-04-17 16:58:45 -04001755{
Nicolas Capens4be33702015-04-28 15:13:30 -07001756 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
Alexis Hetue8af6d12015-04-17 16:58:45 -04001757 mode, count, type, indices, instanceCount);
1758
1759 switch(mode)
1760 {
1761 case GL_POINTS:
1762 case GL_LINES:
1763 case GL_LINE_LOOP:
1764 case GL_LINE_STRIP:
1765 case GL_TRIANGLES:
1766 case GL_TRIANGLE_FAN:
1767 case GL_TRIANGLE_STRIP:
1768 break;
1769 default:
1770 return error(GL_INVALID_ENUM);
1771 }
1772
1773 switch(type)
1774 {
1775 case GL_UNSIGNED_BYTE:
1776 case GL_UNSIGNED_SHORT:
1777 case GL_UNSIGNED_INT:
1778 break;
1779 default:
1780 return error(GL_INVALID_ENUM);
1781 }
1782
1783 if(count < 0 || instanceCount < 0)
1784 {
1785 return error(GL_INVALID_VALUE);
1786 }
1787
1788 es2::Context *context = es2::getContext();
1789
1790 if(context)
1791 {
1792 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1793 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1794 {
1795 return error(GL_INVALID_OPERATION);
1796 }
1797
Nicolas Capens22d07662015-04-25 11:34:50 -07001798 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
Alexis Hetue8af6d12015-04-17 16:58:45 -04001799 }
1800}
1801
Nicolas Capenseb195b62015-04-28 17:18:42 -07001802void VertexAttribDivisorEXT(GLuint index, GLuint divisor)
Alexis Hetue8af6d12015-04-17 16:58:45 -04001803{
1804 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
1805
1806 es2::Context *context = es2::getContext();
1807
1808 if(context)
1809 {
1810 if(index >= es2::MAX_VERTEX_ATTRIBS)
1811 {
1812 return error(GL_INVALID_VALUE);
1813 }
1814
1815 context->setVertexAttribDivisor(index, divisor);
1816 }
1817}
1818
Nicolas Capenseb195b62015-04-28 17:18:42 -07001819void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
Alexis Hetub4d557d2015-04-24 17:25:10 -04001820{
1821 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1822 mode, first, count, instanceCount);
1823
1824 switch(mode)
1825 {
1826 case GL_POINTS:
1827 case GL_LINES:
1828 case GL_LINE_LOOP:
1829 case GL_LINE_STRIP:
1830 case GL_TRIANGLES:
1831 case GL_TRIANGLE_FAN:
1832 case GL_TRIANGLE_STRIP:
1833 break;
1834 default:
1835 return error(GL_INVALID_ENUM);
1836 }
1837
1838 if(count < 0 || instanceCount < 0)
1839 {
1840 return error(GL_INVALID_VALUE);
1841 }
1842
1843 es2::Context *context = es2::getContext();
1844
1845 if(context)
1846 {
1847 if(!context->hasZeroDivisor())
1848 {
1849 return error(GL_INVALID_OPERATION);
1850 }
1851
1852 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1853 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))
1854 {
1855 return error(GL_INVALID_OPERATION);
1856 }
1857
1858 context->drawArrays(mode, first, count, instanceCount);
1859 }
1860}
1861
Nicolas Capenseb195b62015-04-28 17:18:42 -07001862void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
Alexis Hetub4d557d2015-04-24 17:25:10 -04001863{
Nicolas Capens4be33702015-04-28 15:13:30 -07001864 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",
Alexis Hetub4d557d2015-04-24 17:25:10 -04001865 mode, count, type, indices, instanceCount);
1866
1867 switch(mode)
1868 {
1869 case GL_POINTS:
1870 case GL_LINES:
1871 case GL_LINE_LOOP:
1872 case GL_LINE_STRIP:
1873 case GL_TRIANGLES:
1874 case GL_TRIANGLE_FAN:
1875 case GL_TRIANGLE_STRIP:
1876 break;
1877 default:
1878 return error(GL_INVALID_ENUM);
1879 }
1880
1881 switch(type)
1882 {
1883 case GL_UNSIGNED_BYTE:
1884 case GL_UNSIGNED_SHORT:
1885 case GL_UNSIGNED_INT:
1886 break;
1887 default:
1888 return error(GL_INVALID_ENUM);
1889 }
1890
1891 if(count < 0 || instanceCount < 0)
1892 {
1893 return error(GL_INVALID_VALUE);
1894 }
1895
1896 es2::Context *context = es2::getContext();
1897
1898 if(context)
1899 {
1900 if(!context->hasZeroDivisor())
1901 {
1902 return error(GL_INVALID_OPERATION);
1903 }
1904
1905 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
1906 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
1907 {
1908 return error(GL_INVALID_OPERATION);
1909 }
1910
Nicolas Capens0416e5c2015-04-28 15:30:28 -07001911 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);
Alexis Hetub4d557d2015-04-24 17:25:10 -04001912 }
1913}
1914
Nicolas Capenseb195b62015-04-28 17:18:42 -07001915void VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
Alexis Hetub4d557d2015-04-24 17:25:10 -04001916{
1917 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
1918
1919 es2::Context *context = es2::getContext();
1920
1921 if(context)
1922 {
1923 if(index >= MAX_VERTEX_ATTRIBS)
1924 {
1925 return error(GL_INVALID_VALUE);
1926 }
1927
1928 context->setVertexAttribDivisor(index, divisor);
1929 }
1930}
1931
Nicolas Capenseb195b62015-04-28 17:18:42 -07001932void Enable(GLenum cap)
John Bauman66b8ab22014-05-06 15:57:45 -04001933{
Nicolas Capensf160b172014-11-26 11:58:23 -05001934 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04001935
Nicolas Capensf160b172014-11-26 11:58:23 -05001936 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001937
Nicolas Capensf160b172014-11-26 11:58:23 -05001938 if(context)
1939 {
1940 switch(cap)
1941 {
Nicolas Capensd55a0952015-08-03 16:36:58 -04001942 case GL_CULL_FACE: context->setCullFaceEnabled(true); break;
1943 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(true); break;
1944 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break;
1945 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(true); break;
1946 case GL_SCISSOR_TEST: context->setScissorTestEnabled(true); break;
1947 case GL_STENCIL_TEST: context->setStencilTestEnabled(true); break;
1948 case GL_DEPTH_TEST: context->setDepthTestEnabled(true); break;
1949 case GL_BLEND: context->setBlendEnabled(true); break;
1950 case GL_DITHER: context->setDitherEnabled(true); break;
1951 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(true); break;
1952 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscardEnabled(true); break;
Nicolas Capensf160b172014-11-26 11:58:23 -05001953 default:
1954 return error(GL_INVALID_ENUM);
1955 }
1956 }
John Bauman66b8ab22014-05-06 15:57:45 -04001957}
1958
Nicolas Capenseb195b62015-04-28 17:18:42 -07001959void EnableVertexAttribArray(GLuint index)
John Bauman66b8ab22014-05-06 15:57:45 -04001960{
Nicolas Capensf160b172014-11-26 11:58:23 -05001961 TRACE("(GLuint index = %d)", index);
John Bauman66b8ab22014-05-06 15:57:45 -04001962
Nicolas Capensf160b172014-11-26 11:58:23 -05001963 if(index >= es2::MAX_VERTEX_ATTRIBS)
1964 {
1965 return error(GL_INVALID_VALUE);
1966 }
John Bauman66b8ab22014-05-06 15:57:45 -04001967
Nicolas Capensf160b172014-11-26 11:58:23 -05001968 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001969
Nicolas Capensf160b172014-11-26 11:58:23 -05001970 if(context)
1971 {
Nicolas Capensd55a0952015-08-03 16:36:58 -04001972 context->setVertexAttribArrayEnabled(index, true);
Nicolas Capensf160b172014-11-26 11:58:23 -05001973 }
John Bauman66b8ab22014-05-06 15:57:45 -04001974}
1975
Nicolas Capenseb195b62015-04-28 17:18:42 -07001976void EndQueryEXT(GLenum target)
John Bauman66b8ab22014-05-06 15:57:45 -04001977{
Nicolas Capensf160b172014-11-26 11:58:23 -05001978 TRACE("GLenum target = 0x%X)", target);
John Bauman66b8ab22014-05-06 15:57:45 -04001979
Nicolas Capensf160b172014-11-26 11:58:23 -05001980 switch(target)
1981 {
1982 case GL_ANY_SAMPLES_PASSED_EXT:
1983 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1984 break;
1985 default:
1986 return error(GL_INVALID_ENUM);
1987 }
John Bauman66b8ab22014-05-06 15:57:45 -04001988
Nicolas Capensf160b172014-11-26 11:58:23 -05001989 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04001990
Nicolas Capensf160b172014-11-26 11:58:23 -05001991 if(context)
1992 {
1993 context->endQuery(target);
1994 }
John Bauman66b8ab22014-05-06 15:57:45 -04001995}
1996
Nicolas Capenseb195b62015-04-28 17:18:42 -07001997void FinishFenceNV(GLuint fence)
John Bauman66b8ab22014-05-06 15:57:45 -04001998{
Nicolas Capensf160b172014-11-26 11:58:23 -05001999 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002000
Nicolas Capensf160b172014-11-26 11:58:23 -05002001 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002002
Nicolas Capensf160b172014-11-26 11:58:23 -05002003 if(context)
2004 {
2005 es2::Fence* fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002006
Nicolas Capensf160b172014-11-26 11:58:23 -05002007 if(fenceObject == NULL)
2008 {
2009 return error(GL_INVALID_OPERATION);
2010 }
John Bauman66b8ab22014-05-06 15:57:45 -04002011
Nicolas Capensf160b172014-11-26 11:58:23 -05002012 fenceObject->finishFence();
2013 }
John Bauman66b8ab22014-05-06 15:57:45 -04002014}
2015
Nicolas Capenseb195b62015-04-28 17:18:42 -07002016void Finish(void)
John Bauman66b8ab22014-05-06 15:57:45 -04002017{
Nicolas Capensf160b172014-11-26 11:58:23 -05002018 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002019
Nicolas Capensf160b172014-11-26 11:58:23 -05002020 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002021
Nicolas Capensf160b172014-11-26 11:58:23 -05002022 if(context)
2023 {
2024 context->finish();
2025 }
John Bauman66b8ab22014-05-06 15:57:45 -04002026}
2027
Nicolas Capenseb195b62015-04-28 17:18:42 -07002028void Flush(void)
John Bauman66b8ab22014-05-06 15:57:45 -04002029{
Nicolas Capensf160b172014-11-26 11:58:23 -05002030 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002031
Nicolas Capensf160b172014-11-26 11:58:23 -05002032 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002033
Nicolas Capensf160b172014-11-26 11:58:23 -05002034 if(context)
2035 {
2036 context->flush();
2037 }
John Bauman66b8ab22014-05-06 15:57:45 -04002038}
2039
Nicolas Capenseb195b62015-04-28 17:18:42 -07002040void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
John Bauman66b8ab22014-05-06 15:57:45 -04002041{
Nicolas Capensf160b172014-11-26 11:58:23 -05002042 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
2043 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04002044
Nicolas Capensf160b172014-11-26 11:58:23 -05002045 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) ||
2046 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
2047 {
2048 return error(GL_INVALID_ENUM);
2049 }
John Bauman66b8ab22014-05-06 15:57:45 -04002050
Nicolas Capensf160b172014-11-26 11:58:23 -05002051 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002052
Nicolas Capensf160b172014-11-26 11:58:23 -05002053 if(context)
2054 {
2055 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002056 GLuint framebufferName = 0;
Nicolas Capensf160b172014-11-26 11:58:23 -05002057 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2058 {
2059 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002060 framebufferName = context->getReadFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002061 }
2062 else
2063 {
2064 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002065 framebufferName = context->getDrawFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002066 }
John Bauman66b8ab22014-05-06 15:57:45 -04002067
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002068 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
Nicolas Capensf160b172014-11-26 11:58:23 -05002069 {
2070 return error(GL_INVALID_OPERATION);
2071 }
John Bauman66b8ab22014-05-06 15:57:45 -04002072
Alexis Hetu5dcf88b2015-12-02 15:29:43 -05002073 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
2074 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
2075 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
2076 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
2077 if(renderbuffer != 0)
2078 {
2079 if(!context->getRenderbuffer(renderbuffer))
2080 {
2081 return error(GL_INVALID_OPERATION);
2082 }
2083 }
2084
Alexis Hetu1b2f6282015-04-16 16:27:42 -04002085 egl::GLint clientVersion = context->getClientVersion();
2086
Nicolas Capensf160b172014-11-26 11:58:23 -05002087 switch(attachment)
2088 {
Alexis Hetu1b2f6282015-04-16 16:27:42 -04002089 case GL_COLOR_ATTACHMENT1:
2090 case GL_COLOR_ATTACHMENT2:
2091 case GL_COLOR_ATTACHMENT3:
2092 case GL_COLOR_ATTACHMENT4:
2093 case GL_COLOR_ATTACHMENT5:
2094 case GL_COLOR_ATTACHMENT6:
2095 case GL_COLOR_ATTACHMENT7:
2096 case GL_COLOR_ATTACHMENT8:
2097 case GL_COLOR_ATTACHMENT9:
2098 case GL_COLOR_ATTACHMENT10:
2099 case GL_COLOR_ATTACHMENT11:
2100 case GL_COLOR_ATTACHMENT12:
2101 case GL_COLOR_ATTACHMENT13:
2102 case GL_COLOR_ATTACHMENT14:
2103 case GL_COLOR_ATTACHMENT15:
Alexis Hetu3e02f682015-12-02 12:53:42 -05002104 case GL_COLOR_ATTACHMENT16:
2105 case GL_COLOR_ATTACHMENT17:
2106 case GL_COLOR_ATTACHMENT18:
2107 case GL_COLOR_ATTACHMENT19:
2108 case GL_COLOR_ATTACHMENT20:
2109 case GL_COLOR_ATTACHMENT21:
2110 case GL_COLOR_ATTACHMENT22:
2111 case GL_COLOR_ATTACHMENT23:
2112 case GL_COLOR_ATTACHMENT24:
2113 case GL_COLOR_ATTACHMENT25:
2114 case GL_COLOR_ATTACHMENT26:
2115 case GL_COLOR_ATTACHMENT27:
2116 case GL_COLOR_ATTACHMENT28:
2117 case GL_COLOR_ATTACHMENT29:
2118 case GL_COLOR_ATTACHMENT30:
2119 case GL_COLOR_ATTACHMENT31:
Alexis Hetu1b2f6282015-04-16 16:27:42 -04002120 if(clientVersion < 3)
2121 {
2122 return error(GL_INVALID_ENUM);
2123 }
2124 // fall through
Nicolas Capensf160b172014-11-26 11:58:23 -05002125 case GL_COLOR_ATTACHMENT0:
Alexis Hetu1b2f6282015-04-16 16:27:42 -04002126 if((attachment - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)
2127 {
2128 return error(GL_INVALID_ENUM);
2129 }
2130 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer, attachment - GL_COLOR_ATTACHMENT0);
Nicolas Capensf160b172014-11-26 11:58:23 -05002131 break;
2132 case GL_DEPTH_ATTACHMENT:
2133 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2134 break;
2135 case GL_STENCIL_ATTACHMENT:
2136 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2137 break;
Alexis Hetu696a8182015-06-23 11:18:17 -04002138 case GL_DEPTH_STENCIL_ATTACHMENT:
2139 if(clientVersion >= 3)
2140 {
2141 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2142 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2143 break;
2144 }
2145 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05002146 default:
2147 return error(GL_INVALID_ENUM);
2148 }
2149 }
John Bauman66b8ab22014-05-06 15:57:45 -04002150}
2151
Nicolas Capenseb195b62015-04-28 17:18:42 -07002152void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
John Bauman66b8ab22014-05-06 15:57:45 -04002153{
Nicolas Capensf160b172014-11-26 11:58:23 -05002154 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
2155 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
John Bauman66b8ab22014-05-06 15:57:45 -04002156
Nicolas Capensf160b172014-11-26 11:58:23 -05002157 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2158 {
2159 return error(GL_INVALID_ENUM);
2160 }
John Bauman66b8ab22014-05-06 15:57:45 -04002161
Nicolas Capensf160b172014-11-26 11:58:23 -05002162 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002163
Nicolas Capensf160b172014-11-26 11:58:23 -05002164 if(context)
2165 {
2166 if(texture == 0)
2167 {
2168 textarget = GL_NONE;
2169 }
2170 else
2171 {
2172 es2::Texture *tex = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -04002173
Nicolas Capensf160b172014-11-26 11:58:23 -05002174 if(tex == NULL)
2175 {
2176 return error(GL_INVALID_OPERATION);
2177 }
John Bauman66b8ab22014-05-06 15:57:45 -04002178
Nicolas Capensf160b172014-11-26 11:58:23 -05002179 switch(textarget)
2180 {
2181 case GL_TEXTURE_2D:
2182 if(tex->getTarget() != GL_TEXTURE_2D)
2183 {
2184 return error(GL_INVALID_OPERATION);
2185 }
2186 break;
2187 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2188 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2189 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2190 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2191 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2192 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2193 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2194 {
2195 return error(GL_INVALID_OPERATION);
2196 }
2197 break;
2198 default:
2199 return error(GL_INVALID_ENUM);
2200 }
John Bauman66b8ab22014-05-06 15:57:45 -04002201
Alexis Hetu5dcf88b2015-12-02 15:29:43 -05002202 if(tex->isCompressed(textarget, level))
2203 {
2204 return error(GL_INVALID_OPERATION);
2205 }
2206
Alexis Hetu8af50072015-04-29 14:29:49 -04002207 if((level != 0) && (context->getClientVersion() < 3))
2208 {
2209 return error(GL_INVALID_VALUE);
2210 }
2211
2212 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
Nicolas Capensf160b172014-11-26 11:58:23 -05002213 {
2214 return error(GL_INVALID_VALUE);
2215 }
2216 }
John Bauman66b8ab22014-05-06 15:57:45 -04002217
Nicolas Capensf160b172014-11-26 11:58:23 -05002218 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002219 GLuint framebufferName = 0;
Nicolas Capensf160b172014-11-26 11:58:23 -05002220 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2221 {
2222 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002223 framebufferName = context->getReadFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002224 }
2225 else
2226 {
2227 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002228 framebufferName = context->getDrawFramebufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05002229 }
John Bauman66b8ab22014-05-06 15:57:45 -04002230
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002231 if(framebufferName == 0 || !framebuffer)
Nicolas Capensf160b172014-11-26 11:58:23 -05002232 {
2233 return error(GL_INVALID_OPERATION);
2234 }
John Bauman66b8ab22014-05-06 15:57:45 -04002235
Alexis Hetu1b2f6282015-04-16 16:27:42 -04002236 egl::GLint clientVersion = context->getClientVersion();
2237
Nicolas Capensf160b172014-11-26 11:58:23 -05002238 switch(attachment)
2239 {
Alexis Hetu1b2f6282015-04-16 16:27:42 -04002240 case GL_COLOR_ATTACHMENT1:
2241 case GL_COLOR_ATTACHMENT2:
2242 case GL_COLOR_ATTACHMENT3:
2243 case GL_COLOR_ATTACHMENT4:
2244 case GL_COLOR_ATTACHMENT5:
2245 case GL_COLOR_ATTACHMENT6:
2246 case GL_COLOR_ATTACHMENT7:
2247 case GL_COLOR_ATTACHMENT8:
2248 case GL_COLOR_ATTACHMENT9:
2249 case GL_COLOR_ATTACHMENT10:
2250 case GL_COLOR_ATTACHMENT11:
2251 case GL_COLOR_ATTACHMENT12:
2252 case GL_COLOR_ATTACHMENT13:
2253 case GL_COLOR_ATTACHMENT14:
2254 case GL_COLOR_ATTACHMENT15:
Alexis Hetu3e02f682015-12-02 12:53:42 -05002255 case GL_COLOR_ATTACHMENT16:
2256 case GL_COLOR_ATTACHMENT17:
2257 case GL_COLOR_ATTACHMENT18:
2258 case GL_COLOR_ATTACHMENT19:
2259 case GL_COLOR_ATTACHMENT20:
2260 case GL_COLOR_ATTACHMENT21:
2261 case GL_COLOR_ATTACHMENT22:
2262 case GL_COLOR_ATTACHMENT23:
2263 case GL_COLOR_ATTACHMENT24:
2264 case GL_COLOR_ATTACHMENT25:
2265 case GL_COLOR_ATTACHMENT26:
2266 case GL_COLOR_ATTACHMENT27:
2267 case GL_COLOR_ATTACHMENT28:
2268 case GL_COLOR_ATTACHMENT29:
2269 case GL_COLOR_ATTACHMENT30:
2270 case GL_COLOR_ATTACHMENT31:
Alexis Hetu1b2f6282015-04-16 16:27:42 -04002271 if(clientVersion < 3)
2272 {
2273 return error(GL_INVALID_ENUM);
2274 }
2275 // fall through
2276 case GL_COLOR_ATTACHMENT0:
2277 if((attachment - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)
2278 {
2279 return error(GL_INVALID_ENUM);
2280 }
Alexis Hetu8af50072015-04-29 14:29:49 -04002281 framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level);
Alexis Hetu1b2f6282015-04-16 16:27:42 -04002282 break;
Alexis Hetu8af50072015-04-29 14:29:49 -04002283 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level); break;
2284 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level); break;
Alexis Hetudcbabfa2015-07-13 13:31:05 -04002285 default:
2286 return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05002287 }
2288 }
John Bauman66b8ab22014-05-06 15:57:45 -04002289}
2290
Nicolas Capenseb195b62015-04-28 17:18:42 -07002291void FrontFace(GLenum mode)
John Bauman66b8ab22014-05-06 15:57:45 -04002292{
Nicolas Capensf160b172014-11-26 11:58:23 -05002293 TRACE("(GLenum mode = 0x%X)", mode);
John Bauman66b8ab22014-05-06 15:57:45 -04002294
Nicolas Capensf160b172014-11-26 11:58:23 -05002295 switch(mode)
2296 {
2297 case GL_CW:
2298 case GL_CCW:
2299 {
2300 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002301
Nicolas Capensf160b172014-11-26 11:58:23 -05002302 if(context)
2303 {
2304 context->setFrontFace(mode);
2305 }
2306 }
2307 break;
2308 default:
2309 return error(GL_INVALID_ENUM);
2310 }
John Bauman66b8ab22014-05-06 15:57:45 -04002311}
2312
Nicolas Capenseb195b62015-04-28 17:18:42 -07002313void GenBuffers(GLsizei n, GLuint* buffers)
John Bauman66b8ab22014-05-06 15:57:45 -04002314{
Nicolas Capens4be33702015-04-28 15:13:30 -07002315 TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002316
Nicolas Capensf160b172014-11-26 11:58:23 -05002317 if(n < 0)
2318 {
2319 return error(GL_INVALID_VALUE);
2320 }
John Bauman66b8ab22014-05-06 15:57:45 -04002321
Nicolas Capensf160b172014-11-26 11:58:23 -05002322 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002323
Nicolas Capensf160b172014-11-26 11:58:23 -05002324 if(context)
2325 {
2326 for(int i = 0; i < n; i++)
2327 {
2328 buffers[i] = context->createBuffer();
2329 }
2330 }
John Bauman66b8ab22014-05-06 15:57:45 -04002331}
2332
Nicolas Capenseb195b62015-04-28 17:18:42 -07002333void GenerateMipmap(GLenum target)
John Bauman66b8ab22014-05-06 15:57:45 -04002334{
Nicolas Capensf160b172014-11-26 11:58:23 -05002335 TRACE("(GLenum target = 0x%X)", target);
John Bauman66b8ab22014-05-06 15:57:45 -04002336
Nicolas Capensf160b172014-11-26 11:58:23 -05002337 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002338
Nicolas Capensf160b172014-11-26 11:58:23 -05002339 if(context)
2340 {
Alexis Hetued306182015-04-02 12:02:28 -04002341 es2::Texture *texture = nullptr;
2342
2343 egl::GLint clientVersion = context->getClientVersion();
John Bauman66b8ab22014-05-06 15:57:45 -04002344
Nicolas Capensf160b172014-11-26 11:58:23 -05002345 switch(target)
2346 {
2347 case GL_TEXTURE_2D:
2348 texture = context->getTexture2D();
2349 break;
2350 case GL_TEXTURE_CUBE_MAP:
2351 texture = context->getTextureCubeMap();
2352 break;
Alexis Hetued306182015-04-02 12:02:28 -04002353 case GL_TEXTURE_2D_ARRAY:
2354 if(clientVersion < 3)
2355 {
2356 return error(GL_INVALID_ENUM);
2357 }
2358 else
2359 {
Alexis Hetuf15e8942015-12-01 15:13:23 -05002360 texture = context->getTexture2DArray();
Alexis Hetued306182015-04-02 12:02:28 -04002361 }
Alexis Hetuf15e8942015-12-01 15:13:23 -05002362 break;
Alexis Hetued306182015-04-02 12:02:28 -04002363 case GL_TEXTURE_3D_OES:
2364 texture = context->getTexture3D();
2365 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05002366 default:
2367 return error(GL_INVALID_ENUM);
2368 }
John Bauman66b8ab22014-05-06 15:57:45 -04002369
Nicolas Capensf160b172014-11-26 11:58:23 -05002370 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2371 {
2372 return error(GL_INVALID_OPERATION);
2373 }
John Bauman66b8ab22014-05-06 15:57:45 -04002374
Nicolas Capensf160b172014-11-26 11:58:23 -05002375 texture->generateMipmaps();
2376 }
John Bauman66b8ab22014-05-06 15:57:45 -04002377}
2378
Nicolas Capenseb195b62015-04-28 17:18:42 -07002379void GenFencesNV(GLsizei n, GLuint* fences)
John Bauman66b8ab22014-05-06 15:57:45 -04002380{
Nicolas Capens4be33702015-04-28 15:13:30 -07002381 TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);
John Bauman66b8ab22014-05-06 15:57:45 -04002382
Nicolas Capensf160b172014-11-26 11:58:23 -05002383 if(n < 0)
2384 {
2385 return error(GL_INVALID_VALUE);
2386 }
John Bauman66b8ab22014-05-06 15:57:45 -04002387
Nicolas Capensf160b172014-11-26 11:58:23 -05002388 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002389
Nicolas Capensf160b172014-11-26 11:58:23 -05002390 if(context)
2391 {
2392 for(int i = 0; i < n; i++)
2393 {
2394 fences[i] = context->createFence();
2395 }
2396 }
John Bauman66b8ab22014-05-06 15:57:45 -04002397}
2398
Nicolas Capenseb195b62015-04-28 17:18:42 -07002399void GenFramebuffers(GLsizei n, GLuint* framebuffers)
John Bauman66b8ab22014-05-06 15:57:45 -04002400{
Nicolas Capens4be33702015-04-28 15:13:30 -07002401 TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002402
Nicolas Capensf160b172014-11-26 11:58:23 -05002403 if(n < 0)
2404 {
2405 return error(GL_INVALID_VALUE);
2406 }
John Bauman66b8ab22014-05-06 15:57:45 -04002407
Nicolas Capensf160b172014-11-26 11:58:23 -05002408 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002409
Nicolas Capensf160b172014-11-26 11:58:23 -05002410 if(context)
2411 {
2412 for(int i = 0; i < n; i++)
2413 {
2414 framebuffers[i] = context->createFramebuffer();
2415 }
2416 }
John Bauman66b8ab22014-05-06 15:57:45 -04002417}
2418
Nicolas Capenseb195b62015-04-28 17:18:42 -07002419void GenQueriesEXT(GLsizei n, GLuint* ids)
John Bauman66b8ab22014-05-06 15:57:45 -04002420{
Nicolas Capens4be33702015-04-28 15:13:30 -07002421 TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
John Bauman66b8ab22014-05-06 15:57:45 -04002422
Nicolas Capensf160b172014-11-26 11:58:23 -05002423 if(n < 0)
2424 {
2425 return error(GL_INVALID_VALUE);
2426 }
John Bauman66b8ab22014-05-06 15:57:45 -04002427
Nicolas Capensf160b172014-11-26 11:58:23 -05002428 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002429
Nicolas Capensf160b172014-11-26 11:58:23 -05002430 if(context)
2431 {
2432 for(int i = 0; i < n; i++)
2433 {
2434 ids[i] = context->createQuery();
2435 }
2436 }
John Bauman66b8ab22014-05-06 15:57:45 -04002437}
2438
Nicolas Capenseb195b62015-04-28 17:18:42 -07002439void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
John Bauman66b8ab22014-05-06 15:57:45 -04002440{
Nicolas Capens4be33702015-04-28 15:13:30 -07002441 TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
John Bauman66b8ab22014-05-06 15:57:45 -04002442
Nicolas Capensf160b172014-11-26 11:58:23 -05002443 if(n < 0)
2444 {
2445 return error(GL_INVALID_VALUE);
2446 }
John Bauman66b8ab22014-05-06 15:57:45 -04002447
Nicolas Capensf160b172014-11-26 11:58:23 -05002448 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002449
Nicolas Capensf160b172014-11-26 11:58:23 -05002450 if(context)
2451 {
2452 for(int i = 0; i < n; i++)
2453 {
2454 renderbuffers[i] = context->createRenderbuffer();
2455 }
2456 }
John Bauman66b8ab22014-05-06 15:57:45 -04002457}
2458
Nicolas Capenseb195b62015-04-28 17:18:42 -07002459void GenTextures(GLsizei n, GLuint* textures)
John Bauman66b8ab22014-05-06 15:57:45 -04002460{
Nicolas Capens4be33702015-04-28 15:13:30 -07002461 TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
John Bauman66b8ab22014-05-06 15:57:45 -04002462
Nicolas Capensf160b172014-11-26 11:58:23 -05002463 if(n < 0)
2464 {
2465 return error(GL_INVALID_VALUE);
2466 }
John Bauman66b8ab22014-05-06 15:57:45 -04002467
Nicolas Capensf160b172014-11-26 11:58:23 -05002468 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002469
Nicolas Capensf160b172014-11-26 11:58:23 -05002470 if(context)
2471 {
2472 for(int i = 0; i < n; i++)
2473 {
2474 textures[i] = context->createTexture();
2475 }
2476 }
John Bauman66b8ab22014-05-06 15:57:45 -04002477}
2478
Nicolas Capenseb195b62015-04-28 17:18:42 -07002479void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
John Bauman66b8ab22014-05-06 15:57:45 -04002480{
Nicolas Capens4be33702015-04-28 15:13:30 -07002481 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
2482 "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05002483 program, index, bufsize, length, size, type, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002484
Nicolas Capensf160b172014-11-26 11:58:23 -05002485 if(bufsize < 0)
2486 {
2487 return error(GL_INVALID_VALUE);
2488 }
John Bauman66b8ab22014-05-06 15:57:45 -04002489
Nicolas Capensf160b172014-11-26 11:58:23 -05002490 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002491
Nicolas Capensf160b172014-11-26 11:58:23 -05002492 if(context)
2493 {
2494 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002495
Nicolas Capensf160b172014-11-26 11:58:23 -05002496 if(!programObject)
2497 {
2498 if(context->getShader(program))
2499 {
2500 return error(GL_INVALID_OPERATION);
2501 }
2502 else
2503 {
2504 return error(GL_INVALID_VALUE);
2505 }
2506 }
John Bauman66b8ab22014-05-06 15:57:45 -04002507
Alexis Hetu0085c442015-06-12 15:19:20 -04002508 if(index >= programObject->getActiveAttributeCount())
Nicolas Capensf160b172014-11-26 11:58:23 -05002509 {
2510 return error(GL_INVALID_VALUE);
2511 }
John Bauman66b8ab22014-05-06 15:57:45 -04002512
Nicolas Capensf160b172014-11-26 11:58:23 -05002513 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2514 }
John Bauman66b8ab22014-05-06 15:57:45 -04002515}
2516
Nicolas Capenseb195b62015-04-28 17:18:42 -07002517void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
John Bauman66b8ab22014-05-06 15:57:45 -04002518{
Nicolas Capensf160b172014-11-26 11:58:23 -05002519 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07002520 "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
Nicolas Capensf160b172014-11-26 11:58:23 -05002521 program, index, bufsize, length, size, type, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002522
Nicolas Capensf160b172014-11-26 11:58:23 -05002523 if(bufsize < 0)
2524 {
2525 return error(GL_INVALID_VALUE);
2526 }
John Bauman66b8ab22014-05-06 15:57:45 -04002527
Nicolas Capensf160b172014-11-26 11:58:23 -05002528 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002529
Nicolas Capensf160b172014-11-26 11:58:23 -05002530 if(context)
2531 {
2532 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002533
Nicolas Capensf160b172014-11-26 11:58:23 -05002534 if(!programObject)
2535 {
2536 if(context->getShader(program))
2537 {
2538 return error(GL_INVALID_OPERATION);
2539 }
2540 else
2541 {
2542 return error(GL_INVALID_VALUE);
2543 }
2544 }
John Bauman66b8ab22014-05-06 15:57:45 -04002545
Alexis Hetu0085c442015-06-12 15:19:20 -04002546 if(index >= programObject->getActiveUniformCount())
Nicolas Capensf160b172014-11-26 11:58:23 -05002547 {
2548 return error(GL_INVALID_VALUE);
2549 }
John Bauman66b8ab22014-05-06 15:57:45 -04002550
Nicolas Capensf160b172014-11-26 11:58:23 -05002551 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2552 }
John Bauman66b8ab22014-05-06 15:57:45 -04002553}
2554
Nicolas Capenseb195b62015-04-28 17:18:42 -07002555void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
John Bauman66b8ab22014-05-06 15:57:45 -04002556{
Nicolas Capens4be33702015-04-28 15:13:30 -07002557 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05002558 program, maxcount, count, shaders);
John Bauman66b8ab22014-05-06 15:57:45 -04002559
Nicolas Capensf160b172014-11-26 11:58:23 -05002560 if(maxcount < 0)
2561 {
2562 return error(GL_INVALID_VALUE);
2563 }
John Bauman66b8ab22014-05-06 15:57:45 -04002564
Nicolas Capensf160b172014-11-26 11:58:23 -05002565 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002566
Nicolas Capensf160b172014-11-26 11:58:23 -05002567 if(context)
2568 {
2569 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002570
Nicolas Capensf160b172014-11-26 11:58:23 -05002571 if(!programObject)
2572 {
2573 if(context->getShader(program))
2574 {
2575 return error(GL_INVALID_OPERATION);
2576 }
2577 else
2578 {
2579 return error(GL_INVALID_VALUE);
2580 }
2581 }
John Bauman66b8ab22014-05-06 15:57:45 -04002582
Nicolas Capensf160b172014-11-26 11:58:23 -05002583 return programObject->getAttachedShaders(maxcount, count, shaders);
2584 }
John Bauman66b8ab22014-05-06 15:57:45 -04002585}
2586
Nicolas Capenseb195b62015-04-28 17:18:42 -07002587int GetAttribLocation(GLuint program, const GLchar* name)
John Bauman66b8ab22014-05-06 15:57:45 -04002588{
Nicolas Capensf160b172014-11-26 11:58:23 -05002589 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
John Bauman66b8ab22014-05-06 15:57:45 -04002590
Nicolas Capensf160b172014-11-26 11:58:23 -05002591 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002592
Nicolas Capensf160b172014-11-26 11:58:23 -05002593 if(context)
2594 {
John Bauman66b8ab22014-05-06 15:57:45 -04002595
Nicolas Capensf160b172014-11-26 11:58:23 -05002596 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04002597
Nicolas Capensf160b172014-11-26 11:58:23 -05002598 if(!programObject)
2599 {
2600 if(context->getShader(program))
2601 {
2602 return error(GL_INVALID_OPERATION, -1);
2603 }
2604 else
2605 {
2606 return error(GL_INVALID_VALUE, -1);
2607 }
2608 }
John Bauman66b8ab22014-05-06 15:57:45 -04002609
Nicolas Capensf160b172014-11-26 11:58:23 -05002610 if(!programObject->isLinked())
2611 {
2612 return error(GL_INVALID_OPERATION, -1);
2613 }
John Bauman66b8ab22014-05-06 15:57:45 -04002614
Nicolas Capensf160b172014-11-26 11:58:23 -05002615 return programObject->getAttributeLocation(name);
2616 }
John Bauman66b8ab22014-05-06 15:57:45 -04002617
Nicolas Capensf160b172014-11-26 11:58:23 -05002618 return -1;
John Bauman66b8ab22014-05-06 15:57:45 -04002619}
2620
Nicolas Capenseb195b62015-04-28 17:18:42 -07002621void GetBooleanv(GLenum pname, GLboolean* params)
John Bauman66b8ab22014-05-06 15:57:45 -04002622{
Nicolas Capens4be33702015-04-28 15:13:30 -07002623 TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002624
Nicolas Capensf160b172014-11-26 11:58:23 -05002625 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002626
Nicolas Capensf160b172014-11-26 11:58:23 -05002627 if(context)
2628 {
2629 if(!(context->getBooleanv(pname, params)))
2630 {
2631 GLenum nativeType;
2632 unsigned int numParams = 0;
2633 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2634 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002635
Nicolas Capensf160b172014-11-26 11:58:23 -05002636 if(numParams == 0)
2637 return; // it is known that the pname is valid, but there are no parameters to return
John Bauman66b8ab22014-05-06 15:57:45 -04002638
Nicolas Capensf160b172014-11-26 11:58:23 -05002639 if(nativeType == GL_FLOAT)
2640 {
2641 GLfloat *floatParams = NULL;
2642 floatParams = new GLfloat[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002643
Nicolas Capensf160b172014-11-26 11:58:23 -05002644 context->getFloatv(pname, floatParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002645
Nicolas Capensf160b172014-11-26 11:58:23 -05002646 for(unsigned int i = 0; i < numParams; ++i)
2647 {
2648 if(floatParams[i] == 0.0f)
2649 params[i] = GL_FALSE;
2650 else
2651 params[i] = GL_TRUE;
2652 }
John Bauman66b8ab22014-05-06 15:57:45 -04002653
Nicolas Capensf160b172014-11-26 11:58:23 -05002654 delete [] floatParams;
2655 }
2656 else if(nativeType == GL_INT)
2657 {
2658 GLint *intParams = NULL;
2659 intParams = new GLint[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002660
Nicolas Capensf160b172014-11-26 11:58:23 -05002661 context->getIntegerv(pname, intParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002662
Nicolas Capensf160b172014-11-26 11:58:23 -05002663 for(unsigned int i = 0; i < numParams; ++i)
2664 {
2665 if(intParams[i] == 0)
2666 params[i] = GL_FALSE;
2667 else
2668 params[i] = GL_TRUE;
2669 }
John Bauman66b8ab22014-05-06 15:57:45 -04002670
Nicolas Capensf160b172014-11-26 11:58:23 -05002671 delete [] intParams;
2672 }
2673 }
2674 }
John Bauman66b8ab22014-05-06 15:57:45 -04002675}
2676
Nicolas Capenseb195b62015-04-28 17:18:42 -07002677void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04002678{
Nicolas Capens4be33702015-04-28 15:13:30 -07002679 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002680
Nicolas Capensf160b172014-11-26 11:58:23 -05002681 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002682
Nicolas Capensf160b172014-11-26 11:58:23 -05002683 if(context)
2684 {
2685 es2::Buffer *buffer;
Alexis Hetuf9b7cb12015-04-10 13:44:36 -04002686 if(!context->getBuffer(target, &buffer))
Nicolas Capensf160b172014-11-26 11:58:23 -05002687 {
Nicolas Capensf160b172014-11-26 11:58:23 -05002688 return error(GL_INVALID_ENUM);
2689 }
John Bauman66b8ab22014-05-06 15:57:45 -04002690
Nicolas Capensf160b172014-11-26 11:58:23 -05002691 if(!buffer)
2692 {
2693 // A null buffer means that "0" is bound to the requested buffer target
2694 return error(GL_INVALID_OPERATION);
2695 }
John Bauman66b8ab22014-05-06 15:57:45 -04002696
Alexis Hetued306182015-04-02 12:02:28 -04002697 egl::GLint clientVersion = context->getClientVersion();
2698
Nicolas Capensf160b172014-11-26 11:58:23 -05002699 switch(pname)
2700 {
2701 case GL_BUFFER_USAGE:
2702 *params = buffer->usage();
2703 break;
2704 case GL_BUFFER_SIZE:
2705 *params = buffer->size();
2706 break;
Alexis Hetued306182015-04-02 12:02:28 -04002707 case GL_BUFFER_ACCESS_FLAGS:
2708 if(clientVersion >= 3)
2709 {
2710 *params = buffer->access();
2711 break;
2712 }
2713 else return error(GL_INVALID_ENUM);
2714 case GL_BUFFER_MAPPED:
2715 if(clientVersion >= 3)
2716 {
2717 *params = buffer->isMapped();
2718 break;
2719 }
2720 else return error(GL_INVALID_ENUM);
2721 case GL_BUFFER_MAP_LENGTH:
2722 if(clientVersion >= 3)
2723 {
2724 *params = buffer->length();
2725 break;
2726 }
2727 else return error(GL_INVALID_ENUM);
2728 case GL_BUFFER_MAP_OFFSET:
2729 if(clientVersion >= 3)
2730 {
2731 *params = buffer->offset();
2732 break;
2733 }
2734 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05002735 default:
2736 return error(GL_INVALID_ENUM);
2737 }
2738 }
John Bauman66b8ab22014-05-06 15:57:45 -04002739}
2740
Nicolas Capenseb195b62015-04-28 17:18:42 -07002741GLenum GetError(void)
John Bauman66b8ab22014-05-06 15:57:45 -04002742{
Nicolas Capensf160b172014-11-26 11:58:23 -05002743 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04002744
Nicolas Capensf160b172014-11-26 11:58:23 -05002745 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002746
Nicolas Capensf160b172014-11-26 11:58:23 -05002747 if(context)
2748 {
2749 return context->getError();
2750 }
John Bauman66b8ab22014-05-06 15:57:45 -04002751
Nicolas Capensf160b172014-11-26 11:58:23 -05002752 return GL_NO_ERROR;
John Bauman66b8ab22014-05-06 15:57:45 -04002753}
2754
Nicolas Capenseb195b62015-04-28 17:18:42 -07002755void GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
John Bauman66b8ab22014-05-06 15:57:45 -04002756{
Nicolas Capens4be33702015-04-28 15:13:30 -07002757 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002758
Nicolas Capensf160b172014-11-26 11:58:23 -05002759 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002760
Nicolas Capensf160b172014-11-26 11:58:23 -05002761 if(context)
2762 {
2763 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04002764
Nicolas Capensf160b172014-11-26 11:58:23 -05002765 if(fenceObject == NULL)
2766 {
2767 return error(GL_INVALID_OPERATION);
2768 }
John Bauman66b8ab22014-05-06 15:57:45 -04002769
Nicolas Capensf160b172014-11-26 11:58:23 -05002770 fenceObject->getFenceiv(pname, params);
2771 }
John Bauman66b8ab22014-05-06 15:57:45 -04002772}
2773
Nicolas Capenseb195b62015-04-28 17:18:42 -07002774void GetFloatv(GLenum pname, GLfloat* params)
John Bauman66b8ab22014-05-06 15:57:45 -04002775{
Nicolas Capens4be33702015-04-28 15:13:30 -07002776 TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002777
Nicolas Capensf160b172014-11-26 11:58:23 -05002778 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002779
Nicolas Capensf160b172014-11-26 11:58:23 -05002780 if(context)
2781 {
2782 if(!(context->getFloatv(pname, params)))
2783 {
2784 GLenum nativeType;
2785 unsigned int numParams = 0;
2786 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2787 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04002788
Nicolas Capensf160b172014-11-26 11:58:23 -05002789 if(numParams == 0)
2790 return; // it is known that the pname is valid, but that there are no parameters to return.
John Bauman66b8ab22014-05-06 15:57:45 -04002791
Nicolas Capensf160b172014-11-26 11:58:23 -05002792 if(nativeType == GL_BOOL)
2793 {
2794 GLboolean *boolParams = NULL;
2795 boolParams = new GLboolean[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002796
Nicolas Capensf160b172014-11-26 11:58:23 -05002797 context->getBooleanv(pname, boolParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002798
Nicolas Capensf160b172014-11-26 11:58:23 -05002799 for(unsigned int i = 0; i < numParams; ++i)
2800 {
2801 if(boolParams[i] == GL_FALSE)
2802 params[i] = 0.0f;
2803 else
2804 params[i] = 1.0f;
2805 }
John Bauman66b8ab22014-05-06 15:57:45 -04002806
Nicolas Capensf160b172014-11-26 11:58:23 -05002807 delete [] boolParams;
2808 }
2809 else if(nativeType == GL_INT)
2810 {
2811 GLint *intParams = NULL;
2812 intParams = new GLint[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04002813
Nicolas Capensf160b172014-11-26 11:58:23 -05002814 context->getIntegerv(pname, intParams);
John Bauman66b8ab22014-05-06 15:57:45 -04002815
Nicolas Capensf160b172014-11-26 11:58:23 -05002816 for(unsigned int i = 0; i < numParams; ++i)
2817 {
2818 params[i] = (GLfloat)intParams[i];
2819 }
John Bauman66b8ab22014-05-06 15:57:45 -04002820
Nicolas Capensf160b172014-11-26 11:58:23 -05002821 delete [] intParams;
2822 }
2823 }
2824 }
John Bauman66b8ab22014-05-06 15:57:45 -04002825}
2826
Nicolas Capenseb195b62015-04-28 17:18:42 -07002827void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04002828{
Nicolas Capens4be33702015-04-28 15:13:30 -07002829 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05002830 target, attachment, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04002831
Nicolas Capensf160b172014-11-26 11:58:23 -05002832 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04002833
Nicolas Capensf160b172014-11-26 11:58:23 -05002834 if(context)
2835 {
2836 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2837 {
2838 return error(GL_INVALID_ENUM);
2839 }
John Bauman66b8ab22014-05-06 15:57:45 -04002840
Alexis Hetua734c0f2015-07-03 10:42:25 -04002841 egl::GLint clientVersion = context->getClientVersion();
2842
Nicolas Capensf160b172014-11-26 11:58:23 -05002843 es2::Framebuffer *framebuffer = NULL;
2844 if(target == GL_READ_FRAMEBUFFER_ANGLE)
2845 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002846 if(context->getReadFramebufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002847 {
Alexis Hetua734c0f2015-07-03 10:42:25 -04002848 switch(attachment)
2849 {
2850 case GL_BACK:
2851 case GL_DEPTH:
2852 case GL_STENCIL:
2853 if(clientVersion >= 3)
2854 {
2855 break;
2856 }
2857 // fall through
2858 default:
Alexis Hetu5dcf88b2015-12-02 15:29:43 -05002859 return error(GL_INVALID_ENUM);
Alexis Hetua734c0f2015-07-03 10:42:25 -04002860 }
Nicolas Capensf160b172014-11-26 11:58:23 -05002861 }
John Bauman66b8ab22014-05-06 15:57:45 -04002862
Nicolas Capensf160b172014-11-26 11:58:23 -05002863 framebuffer = context->getReadFramebuffer();
2864 }
2865 else
2866 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002867 if(context->getDrawFramebufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05002868 {
Alexis Hetua734c0f2015-07-03 10:42:25 -04002869 switch(attachment)
2870 {
2871 case GL_BACK:
2872 case GL_DEPTH:
2873 case GL_STENCIL:
2874 if(clientVersion >= 3)
2875 {
2876 break;
2877 }
2878 // fall through
2879 default:
Alexis Hetu5dcf88b2015-12-02 15:29:43 -05002880 return error(GL_INVALID_ENUM);
Alexis Hetua734c0f2015-07-03 10:42:25 -04002881 }
Nicolas Capensf160b172014-11-26 11:58:23 -05002882 }
John Bauman66b8ab22014-05-06 15:57:45 -04002883
Nicolas Capensf160b172014-11-26 11:58:23 -05002884 framebuffer = context->getDrawFramebuffer();
2885 }
John Bauman66b8ab22014-05-06 15:57:45 -04002886
Nicolas Capensf160b172014-11-26 11:58:23 -05002887 GLenum attachmentType;
2888 GLuint attachmentHandle;
Alexis Hetu0fecd6f2015-07-22 16:49:31 -04002889 GLint attachmentLayer;
Alexis Hetua734c0f2015-07-03 10:42:25 -04002890 Renderbuffer* renderbuffer = nullptr;
Nicolas Capensf160b172014-11-26 11:58:23 -05002891 switch(attachment)
2892 {
Alexis Hetua734c0f2015-07-03 10:42:25 -04002893 case GL_BACK:
2894 if(clientVersion >= 3)
2895 {
2896 attachmentType = framebuffer->getColorbufferType(0);
2897 attachmentHandle = framebuffer->getColorbufferName(0);
Alexis Hetu0fecd6f2015-07-22 16:49:31 -04002898 attachmentLayer = framebuffer->getColorbufferLayer(0);
Alexis Hetua734c0f2015-07-03 10:42:25 -04002899 renderbuffer = framebuffer->getColorbuffer(0);
2900 }
2901 else return error(GL_INVALID_ENUM);
2902 break;
Alexis Hetu1b2f6282015-04-16 16:27:42 -04002903 case GL_COLOR_ATTACHMENT1:
2904 case GL_COLOR_ATTACHMENT2:
2905 case GL_COLOR_ATTACHMENT3:
2906 case GL_COLOR_ATTACHMENT4:
2907 case GL_COLOR_ATTACHMENT5:
2908 case GL_COLOR_ATTACHMENT6:
2909 case GL_COLOR_ATTACHMENT7:
2910 case GL_COLOR_ATTACHMENT8:
2911 case GL_COLOR_ATTACHMENT9:
2912 case GL_COLOR_ATTACHMENT10:
2913 case GL_COLOR_ATTACHMENT11:
2914 case GL_COLOR_ATTACHMENT12:
2915 case GL_COLOR_ATTACHMENT13:
2916 case GL_COLOR_ATTACHMENT14:
2917 case GL_COLOR_ATTACHMENT15:
Alexis Hetu3e02f682015-12-02 12:53:42 -05002918 case GL_COLOR_ATTACHMENT16:
2919 case GL_COLOR_ATTACHMENT17:
2920 case GL_COLOR_ATTACHMENT18:
2921 case GL_COLOR_ATTACHMENT19:
2922 case GL_COLOR_ATTACHMENT20:
2923 case GL_COLOR_ATTACHMENT21:
2924 case GL_COLOR_ATTACHMENT22:
2925 case GL_COLOR_ATTACHMENT23:
2926 case GL_COLOR_ATTACHMENT24:
2927 case GL_COLOR_ATTACHMENT25:
2928 case GL_COLOR_ATTACHMENT26:
2929 case GL_COLOR_ATTACHMENT27:
2930 case GL_COLOR_ATTACHMENT28:
2931 case GL_COLOR_ATTACHMENT29:
2932 case GL_COLOR_ATTACHMENT30:
2933 case GL_COLOR_ATTACHMENT31:
Alexis Hetu1b2f6282015-04-16 16:27:42 -04002934 if(clientVersion < 3)
2935 {
2936 return error(GL_INVALID_ENUM);
2937 }
2938 // fall through
Nicolas Capensf160b172014-11-26 11:58:23 -05002939 case GL_COLOR_ATTACHMENT0:
Alexis Hetu1b2f6282015-04-16 16:27:42 -04002940 if((attachment - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)
2941 {
2942 return error(GL_INVALID_ENUM);
2943 }
2944 attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);
2945 attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);
Alexis Hetu074c6412015-06-22 15:57:27 -04002946 attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);
Alexis Hetua734c0f2015-07-03 10:42:25 -04002947 renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
Nicolas Capensf160b172014-11-26 11:58:23 -05002948 break;
Alexis Hetua734c0f2015-07-03 10:42:25 -04002949 case GL_DEPTH:
2950 if(clientVersion < 3)
2951 {
2952 return error(GL_INVALID_ENUM);
2953 }
2954 // fall through
Nicolas Capensf160b172014-11-26 11:58:23 -05002955 case GL_DEPTH_ATTACHMENT:
2956 attachmentType = framebuffer->getDepthbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002957 attachmentHandle = framebuffer->getDepthbufferName();
Alexis Hetu0fecd6f2015-07-22 16:49:31 -04002958 attachmentLayer = framebuffer->getDepthbufferLayer();
Alexis Hetua734c0f2015-07-03 10:42:25 -04002959 renderbuffer = framebuffer->getDepthbuffer();
Nicolas Capensf160b172014-11-26 11:58:23 -05002960 break;
Alexis Hetua734c0f2015-07-03 10:42:25 -04002961 case GL_STENCIL:
2962 if(clientVersion < 3)
2963 {
2964 return error(GL_INVALID_ENUM);
2965 }
2966 // fall through
Nicolas Capensf160b172014-11-26 11:58:23 -05002967 case GL_STENCIL_ATTACHMENT:
2968 attachmentType = framebuffer->getStencilbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002969 attachmentHandle = framebuffer->getStencilbufferName();
Alexis Hetu0fecd6f2015-07-22 16:49:31 -04002970 attachmentLayer = framebuffer->getStencilbufferLayer();
Alexis Hetua734c0f2015-07-03 10:42:25 -04002971 renderbuffer = framebuffer->getStencilbuffer();
Nicolas Capensf160b172014-11-26 11:58:23 -05002972 break;
Alexis Hetu696a8182015-06-23 11:18:17 -04002973 case GL_DEPTH_STENCIL_ATTACHMENT:
2974 if(clientVersion >= 3)
2975 {
2976 attachmentType = framebuffer->getDepthbufferType();
2977 attachmentHandle = framebuffer->getDepthbufferName();
Alexis Hetu0fecd6f2015-07-22 16:49:31 -04002978 attachmentLayer = framebuffer->getDepthbufferLayer();
Alexis Hetu696a8182015-06-23 11:18:17 -04002979 if(attachmentHandle != framebuffer->getStencilbufferName())
2980 {
2981 // Different attachments to DEPTH and STENCIL, query fails
2982 return error(GL_INVALID_OPERATION);
2983 }
Alexis Hetua734c0f2015-07-03 10:42:25 -04002984 renderbuffer = framebuffer->getDepthbuffer();
Alexis Hetu696a8182015-06-23 11:18:17 -04002985 }
2986 else return error(GL_INVALID_ENUM);
Alexis Hetua734c0f2015-07-03 10:42:25 -04002987 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05002988 default:
2989 return error(GL_INVALID_ENUM);
2990 }
John Bauman66b8ab22014-05-06 15:57:45 -04002991
Nicolas Capensf160b172014-11-26 11:58:23 -05002992 GLenum attachmentObjectType; // Type category
2993 if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
2994 {
2995 attachmentObjectType = attachmentType;
2996 }
2997 else if(es2::IsTextureTarget(attachmentType))
2998 {
2999 attachmentObjectType = GL_TEXTURE;
3000 }
Nicolas Capens3713cd42015-06-22 10:41:54 -04003001 else UNREACHABLE(attachmentType);
John Bauman66b8ab22014-05-06 15:57:45 -04003002
Alexis Hetu5dcf88b2015-12-02 15:29:43 -05003003 if(attachmentObjectType != GL_NONE)
Nicolas Capensf160b172014-11-26 11:58:23 -05003004 {
Alexis Hetu5dcf88b2015-12-02 15:29:43 -05003005 switch(pname)
Nicolas Capensf160b172014-11-26 11:58:23 -05003006 {
Alexis Hetu5dcf88b2015-12-02 15:29:43 -05003007 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3008 *params = attachmentObjectType;
3009 break;
3010 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3011 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
Nicolas Capensf160b172014-11-26 11:58:23 -05003012 {
Alexis Hetu5dcf88b2015-12-02 15:29:43 -05003013 *params = attachmentHandle;
Nicolas Capensf160b172014-11-26 11:58:23 -05003014 }
3015 else
3016 {
Alexis Hetu5dcf88b2015-12-02 15:29:43 -05003017 return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003018 }
Alexis Hetu5dcf88b2015-12-02 15:29:43 -05003019 break;
3020 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3021 if(attachmentObjectType == GL_TEXTURE)
3022 {
3023 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
3024 }
3025 else
3026 {
3027 return error(GL_INVALID_ENUM);
3028 }
3029 break;
3030 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3031 if(attachmentObjectType == GL_TEXTURE)
3032 {
3033 if(es2::IsCubemapTextureTarget(attachmentType))
3034 {
3035 *params = attachmentType;
3036 }
3037 else
3038 {
3039 *params = 0;
3040 }
3041 }
3042 else
3043 {
3044 return error(GL_INVALID_ENUM);
3045 }
3046 break;
3047 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
3048 if(clientVersion >= 3)
3049 {
3050 *params = attachmentLayer;
3051 }
3052 else return error(GL_INVALID_ENUM);
3053 break;
3054 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
3055 if(clientVersion >= 3)
3056 {
3057 *params = renderbuffer->getRedSize();
3058 }
3059 else return error(GL_INVALID_ENUM);
3060 break;
3061 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
3062 if(clientVersion >= 3)
3063 {
3064 *params = renderbuffer->getGreenSize();
3065 }
3066 else return error(GL_INVALID_ENUM);
3067 break;
3068 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
3069 if(clientVersion >= 3)
3070 {
3071 *params = renderbuffer->getBlueSize();
3072 }
3073 else return error(GL_INVALID_ENUM);
3074 break;
3075 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
3076 if(clientVersion >= 3)
3077 {
3078 *params = renderbuffer->getAlphaSize();
3079 }
3080 else return error(GL_INVALID_ENUM);
3081 break;
3082 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
3083 if(clientVersion >= 3)
3084 {
3085 *params = renderbuffer->getDepthSize();
3086 }
3087 else return error(GL_INVALID_ENUM);
3088 break;
3089 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
3090 if(clientVersion >= 3)
3091 {
3092 *params = renderbuffer->getStencilSize();
3093 }
3094 else return error(GL_INVALID_ENUM);
3095 break;
3096 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
3097 if(clientVersion >= 3)
3098 {
3099 if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
3100 {
3101 return error(GL_INVALID_OPERATION);
3102 }
3103
3104 *params = sw2es::GetComponentType(renderbuffer->getInternalFormat(), attachment);
3105 }
3106 else return error(GL_INVALID_ENUM);
3107 break;
3108 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
3109 if(clientVersion >= 3)
3110 {
3111 *params = GL_LINEAR; // FIXME: GL_SRGB will also be possible, when sRGB is added
3112 }
3113 else return error(GL_INVALID_ENUM);
3114 break;
3115 default:
Nicolas Capensf160b172014-11-26 11:58:23 -05003116 return error(GL_INVALID_ENUM);
3117 }
Alexis Hetu5dcf88b2015-12-02 15:29:43 -05003118 }
3119 else
3120 {
3121 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
3122 // is NONE, then querying any other pname will generate INVALID_ENUM.
3123
3124 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
3125 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
3126 // INVALID_OPERATION for all other pnames
3127
3128 switch(pname)
Alexis Hetu074c6412015-06-22 15:57:27 -04003129 {
Alexis Hetu5dcf88b2015-12-02 15:29:43 -05003130 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3131 *params = GL_NONE;
3132 break;
3133
3134 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3135 if(clientVersion < 3)
3136 {
3137 return error(GL_INVALID_ENUM);
3138 }
3139 *params = 0;
3140 break;
3141
3142 default:
3143 if(clientVersion < 3)
3144 {
3145 return error(GL_INVALID_ENUM);
3146 }
3147 else
Alexis Hetua734c0f2015-07-03 10:42:25 -04003148 {
3149 return error(GL_INVALID_OPERATION);
3150 }
Alexis Hetua734c0f2015-07-03 10:42:25 -04003151 }
Nicolas Capensf160b172014-11-26 11:58:23 -05003152 }
3153 }
John Bauman66b8ab22014-05-06 15:57:45 -04003154}
3155
Nicolas Capenseb195b62015-04-28 17:18:42 -07003156GLenum GetGraphicsResetStatusEXT(void)
John Bauman66b8ab22014-05-06 15:57:45 -04003157{
Nicolas Capensf160b172014-11-26 11:58:23 -05003158 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04003159
Nicolas Capensf160b172014-11-26 11:58:23 -05003160 return GL_NO_ERROR;
John Bauman66b8ab22014-05-06 15:57:45 -04003161}
3162
Nicolas Capenseb195b62015-04-28 17:18:42 -07003163void GetIntegerv(GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003164{
Nicolas Capens4be33702015-04-28 15:13:30 -07003165 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003166
Nicolas Capensf160b172014-11-26 11:58:23 -05003167 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003168
Nicolas Capens7ae353d2015-03-13 17:59:58 -04003169 if(!context)
3170 {
Greg Hartman6074f122015-04-08 09:57:16 -07003171 // Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
3172 #ifdef __ANDROID__
3173 ALOGI("expected_badness glGetIntegerv() called without current context.");
3174 #else
3175 ERR("glGetIntegerv() called without current context.");
3176 #endif
Nicolas Capens7ae353d2015-03-13 17:59:58 -04003177
3178 // This is not spec compliant! When there is no current GL context, functions should
3179 // have no side effects. Google Maps queries these values before creating a context,
3180 // so we need this as a bug-compatible workaround.
3181 switch(pname)
3182 {
3183 case GL_MAX_TEXTURE_SIZE: *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE; return;
3184 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS; return;
3185 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
3186 case GL_STENCIL_BITS: *params = 8; return;
3187 case GL_ALIASED_LINE_WIDTH_RANGE:
3188 params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
3189 params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
3190 return;
3191 }
3192 }
3193
Nicolas Capensf160b172014-11-26 11:58:23 -05003194 if(context)
3195 {
3196 if(!(context->getIntegerv(pname, params)))
3197 {
3198 GLenum nativeType;
3199 unsigned int numParams = 0;
3200 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3201 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04003202
Nicolas Capensf160b172014-11-26 11:58:23 -05003203 if(numParams == 0)
3204 return; // it is known that pname is valid, but there are no parameters to return
John Bauman66b8ab22014-05-06 15:57:45 -04003205
Nicolas Capensf160b172014-11-26 11:58:23 -05003206 if(nativeType == GL_BOOL)
3207 {
3208 GLboolean *boolParams = NULL;
3209 boolParams = new GLboolean[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04003210
Nicolas Capensf160b172014-11-26 11:58:23 -05003211 context->getBooleanv(pname, boolParams);
John Bauman66b8ab22014-05-06 15:57:45 -04003212
Nicolas Capensf160b172014-11-26 11:58:23 -05003213 for(unsigned int i = 0; i < numParams; ++i)
3214 {
Alexis Hetued306182015-04-02 12:02:28 -04003215 params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
Nicolas Capensf160b172014-11-26 11:58:23 -05003216 }
John Bauman66b8ab22014-05-06 15:57:45 -04003217
Nicolas Capensf160b172014-11-26 11:58:23 -05003218 delete [] boolParams;
3219 }
3220 else if(nativeType == GL_FLOAT)
3221 {
3222 GLfloat *floatParams = NULL;
3223 floatParams = new GLfloat[numParams];
John Bauman66b8ab22014-05-06 15:57:45 -04003224
Nicolas Capensf160b172014-11-26 11:58:23 -05003225 context->getFloatv(pname, floatParams);
John Bauman66b8ab22014-05-06 15:57:45 -04003226
Nicolas Capensf160b172014-11-26 11:58:23 -05003227 for(unsigned int i = 0; i < numParams; ++i)
3228 {
3229 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
3230 {
Alexis Hetu5a01c182015-04-16 13:14:04 -04003231 params[i] = es2::floatToInt(floatParams[i]);
Nicolas Capensf160b172014-11-26 11:58:23 -05003232 }
3233 else
3234 {
3235 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
3236 }
3237 }
John Bauman66b8ab22014-05-06 15:57:45 -04003238
Nicolas Capensf160b172014-11-26 11:58:23 -05003239 delete [] floatParams;
3240 }
3241 }
3242 }
John Bauman66b8ab22014-05-06 15:57:45 -04003243}
3244
Nicolas Capenseb195b62015-04-28 17:18:42 -07003245void GetProgramiv(GLuint program, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003246{
Nicolas Capens4be33702015-04-28 15:13:30 -07003247 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003248
Nicolas Capensf160b172014-11-26 11:58:23 -05003249 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003250
Nicolas Capensf160b172014-11-26 11:58:23 -05003251 if(context)
3252 {
3253 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003254
Nicolas Capensf160b172014-11-26 11:58:23 -05003255 if(!programObject)
3256 {
3257 return error(GL_INVALID_VALUE);
3258 }
John Bauman66b8ab22014-05-06 15:57:45 -04003259
Alexis Hetud1746742015-04-30 15:48:23 -04003260 egl::GLint clientVersion = egl::getClientVersion();
3261
Nicolas Capensf160b172014-11-26 11:58:23 -05003262 switch(pname)
3263 {
3264 case GL_DELETE_STATUS:
3265 *params = programObject->isFlaggedForDeletion();
3266 return;
3267 case GL_LINK_STATUS:
3268 *params = programObject->isLinked();
3269 return;
3270 case GL_VALIDATE_STATUS:
3271 *params = programObject->isValidated();
3272 return;
3273 case GL_INFO_LOG_LENGTH:
3274 *params = programObject->getInfoLogLength();
3275 return;
3276 case GL_ATTACHED_SHADERS:
3277 *params = programObject->getAttachedShadersCount();
3278 return;
3279 case GL_ACTIVE_ATTRIBUTES:
3280 *params = programObject->getActiveAttributeCount();
3281 return;
3282 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
3283 *params = programObject->getActiveAttributeMaxLength();
3284 return;
3285 case GL_ACTIVE_UNIFORMS:
3286 *params = programObject->getActiveUniformCount();
3287 return;
3288 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
3289 *params = programObject->getActiveUniformMaxLength();
3290 return;
Alexis Hetud1746742015-04-30 15:48:23 -04003291 case GL_ACTIVE_UNIFORM_BLOCKS:
3292 if(clientVersion >= 3)
3293 {
3294 *params = programObject->getActiveUniformBlockCount();
3295 return;
3296 }
3297 else return error(GL_INVALID_ENUM);
3298 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
3299 if(clientVersion >= 3)
3300 {
3301 *params = programObject->getActiveUniformBlockMaxLength();
3302 return;
3303 }
3304 else return error(GL_INVALID_ENUM);
Alexis Hetu638e2ae2015-06-10 16:03:17 -04003305 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
3306 if(clientVersion >= 3)
3307 {
3308 *params = programObject->getTransformFeedbackBufferMode();
3309 return;
3310 }
3311 else return error(GL_INVALID_ENUM);
3312 case GL_TRANSFORM_FEEDBACK_VARYINGS:
3313 if(clientVersion >= 3)
3314 {
3315 *params = programObject->getTransformFeedbackVaryingCount();
3316 return;
3317 }
3318 else return error(GL_INVALID_ENUM);
3319 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
3320 if(clientVersion >= 3)
3321 {
3322 *params = programObject->getTransformFeedbackVaryingMaxLength();
3323 return;
3324 }
3325 else return error(GL_INVALID_ENUM);
3326 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
3327 if(clientVersion >= 3)
3328 {
Alexis Hetufef22a62015-06-30 17:03:10 -04003329 *params = programObject->getBinaryRetrievableHint();
3330 return;
3331 }
3332 else return error(GL_INVALID_ENUM);
3333 case GL_PROGRAM_BINARY_LENGTH:
3334 if(clientVersion >= 3)
3335 {
3336 *params = programObject->getBinaryLength();
3337 return;
Alexis Hetu638e2ae2015-06-10 16:03:17 -04003338 }
3339 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003340 default:
3341 return error(GL_INVALID_ENUM);
3342 }
3343 }
John Bauman66b8ab22014-05-06 15:57:45 -04003344}
3345
Nicolas Capenseb195b62015-04-28 17:18:42 -07003346void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
John Bauman66b8ab22014-05-06 15:57:45 -04003347{
Nicolas Capens4be33702015-04-28 15:13:30 -07003348 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003349 program, bufsize, length, infolog);
John Bauman66b8ab22014-05-06 15:57:45 -04003350
Nicolas Capensf160b172014-11-26 11:58:23 -05003351 if(bufsize < 0)
3352 {
3353 return error(GL_INVALID_VALUE);
3354 }
John Bauman66b8ab22014-05-06 15:57:45 -04003355
Nicolas Capensf160b172014-11-26 11:58:23 -05003356 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003357
Nicolas Capensf160b172014-11-26 11:58:23 -05003358 if(context)
3359 {
3360 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003361
Nicolas Capensf160b172014-11-26 11:58:23 -05003362 if(!programObject)
3363 {
3364 return error(GL_INVALID_VALUE);
3365 }
John Bauman66b8ab22014-05-06 15:57:45 -04003366
Nicolas Capensf160b172014-11-26 11:58:23 -05003367 programObject->getInfoLog(bufsize, length, infolog);
3368 }
John Bauman66b8ab22014-05-06 15:57:45 -04003369}
3370
Nicolas Capenseb195b62015-04-28 17:18:42 -07003371void GetQueryivEXT(GLenum target, GLenum pname, GLint *params)
John Bauman66b8ab22014-05-06 15:57:45 -04003372{
Nicolas Capens4be33702015-04-28 15:13:30 -07003373 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003374
Nicolas Capensf160b172014-11-26 11:58:23 -05003375 switch(pname)
3376 {
3377 case GL_CURRENT_QUERY_EXT:
3378 break;
3379 default:
3380 return error(GL_INVALID_ENUM);
3381 }
John Bauman66b8ab22014-05-06 15:57:45 -04003382
Nicolas Capensf160b172014-11-26 11:58:23 -05003383 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003384
Nicolas Capensf160b172014-11-26 11:58:23 -05003385 if(context)
3386 {
3387 params[0] = context->getActiveQuery(target);
3388 }
John Bauman66b8ab22014-05-06 15:57:45 -04003389}
3390
Nicolas Capenseb195b62015-04-28 17:18:42 -07003391void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
John Bauman66b8ab22014-05-06 15:57:45 -04003392{
Nicolas Capens4be33702015-04-28 15:13:30 -07003393 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003394
Nicolas Capensf160b172014-11-26 11:58:23 -05003395 switch(pname)
3396 {
3397 case GL_QUERY_RESULT_EXT:
3398 case GL_QUERY_RESULT_AVAILABLE_EXT:
3399 break;
3400 default:
3401 return error(GL_INVALID_ENUM);
3402 }
John Bauman66b8ab22014-05-06 15:57:45 -04003403
Nicolas Capensf160b172014-11-26 11:58:23 -05003404 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003405
Nicolas Capensf160b172014-11-26 11:58:23 -05003406 if(context)
3407 {
Alexis Hetu8e32f7b2015-04-28 09:59:09 -04003408 es2::Query *queryObject = context->getQuery(name);
John Bauman66b8ab22014-05-06 15:57:45 -04003409
Nicolas Capensf160b172014-11-26 11:58:23 -05003410 if(!queryObject)
3411 {
3412 return error(GL_INVALID_OPERATION);
3413 }
John Bauman66b8ab22014-05-06 15:57:45 -04003414
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003415 if(context->getActiveQuery(queryObject->getType()) == name)
Nicolas Capensf160b172014-11-26 11:58:23 -05003416 {
3417 return error(GL_INVALID_OPERATION);
3418 }
John Bauman66b8ab22014-05-06 15:57:45 -04003419
Nicolas Capensf160b172014-11-26 11:58:23 -05003420 switch(pname)
3421 {
3422 case GL_QUERY_RESULT_EXT:
3423 params[0] = queryObject->getResult();
3424 break;
3425 case GL_QUERY_RESULT_AVAILABLE_EXT:
3426 params[0] = queryObject->isResultAvailable();
3427 break;
3428 default:
3429 ASSERT(false);
3430 }
3431 }
John Bauman66b8ab22014-05-06 15:57:45 -04003432}
3433
Nicolas Capenseb195b62015-04-28 17:18:42 -07003434void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003435{
Nicolas Capens4be33702015-04-28 15:13:30 -07003436 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003437
Nicolas Capensf160b172014-11-26 11:58:23 -05003438 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003439
Nicolas Capensf160b172014-11-26 11:58:23 -05003440 if(context)
3441 {
3442 if(target != GL_RENDERBUFFER)
3443 {
3444 return error(GL_INVALID_ENUM);
3445 }
John Bauman66b8ab22014-05-06 15:57:45 -04003446
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003447 if(context->getRenderbufferName() == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05003448 {
3449 return error(GL_INVALID_OPERATION);
3450 }
John Bauman66b8ab22014-05-06 15:57:45 -04003451
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003452 es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
John Bauman66b8ab22014-05-06 15:57:45 -04003453
Nicolas Capensf160b172014-11-26 11:58:23 -05003454 switch(pname)
3455 {
3456 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3457 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3458 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
3459 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3460 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3461 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3462 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3463 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3464 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
3465 case GL_RENDERBUFFER_SAMPLES_ANGLE: *params = renderbuffer->getSamples(); break;
3466 default:
3467 return error(GL_INVALID_ENUM);
3468 }
3469 }
John Bauman66b8ab22014-05-06 15:57:45 -04003470}
3471
Nicolas Capenseb195b62015-04-28 17:18:42 -07003472void GetShaderiv(GLuint shader, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003473{
Nicolas Capens4be33702015-04-28 15:13:30 -07003474 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003475
Nicolas Capensf160b172014-11-26 11:58:23 -05003476 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003477
Nicolas Capensf160b172014-11-26 11:58:23 -05003478 if(context)
3479 {
3480 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003481
Nicolas Capensf160b172014-11-26 11:58:23 -05003482 if(!shaderObject)
3483 {
3484 return error(GL_INVALID_VALUE);
3485 }
John Bauman66b8ab22014-05-06 15:57:45 -04003486
Nicolas Capensf160b172014-11-26 11:58:23 -05003487 switch(pname)
3488 {
3489 case GL_SHADER_TYPE:
3490 *params = shaderObject->getType();
3491 return;
3492 case GL_DELETE_STATUS:
3493 *params = shaderObject->isFlaggedForDeletion();
3494 return;
3495 case GL_COMPILE_STATUS:
3496 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3497 return;
3498 case GL_INFO_LOG_LENGTH:
3499 *params = shaderObject->getInfoLogLength();
3500 return;
3501 case GL_SHADER_SOURCE_LENGTH:
3502 *params = shaderObject->getSourceLength();
3503 return;
3504 default:
3505 return error(GL_INVALID_ENUM);
3506 }
3507 }
John Bauman66b8ab22014-05-06 15:57:45 -04003508}
3509
Nicolas Capenseb195b62015-04-28 17:18:42 -07003510void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
John Bauman66b8ab22014-05-06 15:57:45 -04003511{
Nicolas Capens4be33702015-04-28 15:13:30 -07003512 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003513 shader, bufsize, length, infolog);
John Bauman66b8ab22014-05-06 15:57:45 -04003514
Nicolas Capensf160b172014-11-26 11:58:23 -05003515 if(bufsize < 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::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003521
Nicolas Capensf160b172014-11-26 11:58:23 -05003522 if(context)
3523 {
3524 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003525
Nicolas Capensf160b172014-11-26 11:58:23 -05003526 if(!shaderObject)
3527 {
3528 return error(GL_INVALID_VALUE);
3529 }
John Bauman66b8ab22014-05-06 15:57:45 -04003530
Nicolas Capensf160b172014-11-26 11:58:23 -05003531 shaderObject->getInfoLog(bufsize, length, infolog);
3532 }
John Bauman66b8ab22014-05-06 15:57:45 -04003533}
3534
Nicolas Capenseb195b62015-04-28 17:18:42 -07003535void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
John Bauman66b8ab22014-05-06 15:57:45 -04003536{
Nicolas Capens4be33702015-04-28 15:13:30 -07003537 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003538 shadertype, precisiontype, range, precision);
John Bauman66b8ab22014-05-06 15:57:45 -04003539
Nicolas Capensf160b172014-11-26 11:58:23 -05003540 switch(shadertype)
3541 {
3542 case GL_VERTEX_SHADER:
3543 case GL_FRAGMENT_SHADER:
3544 break;
3545 default:
3546 return error(GL_INVALID_ENUM);
3547 }
John Bauman66b8ab22014-05-06 15:57:45 -04003548
Nicolas Capensf160b172014-11-26 11:58:23 -05003549 switch(precisiontype)
3550 {
3551 case GL_LOW_FLOAT:
3552 case GL_MEDIUM_FLOAT:
3553 case GL_HIGH_FLOAT:
3554 // IEEE 754 single-precision
3555 range[0] = 127;
3556 range[1] = 127;
3557 *precision = 23;
3558 break;
3559 case GL_LOW_INT:
3560 case GL_MEDIUM_INT:
3561 case GL_HIGH_INT:
Alexis Hetu02a2bb82015-08-20 14:10:33 -04003562 // Full integer precision is supported
3563 range[0] = 31;
3564 range[1] = 30;
Nicolas Capensf160b172014-11-26 11:58:23 -05003565 *precision = 0;
3566 break;
3567 default:
3568 return error(GL_INVALID_ENUM);
3569 }
John Bauman66b8ab22014-05-06 15:57:45 -04003570}
3571
Nicolas Capenseb195b62015-04-28 17:18:42 -07003572void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
John Bauman66b8ab22014-05-06 15:57:45 -04003573{
Nicolas Capens4be33702015-04-28 15:13:30 -07003574 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003575 shader, bufsize, length, source);
John Bauman66b8ab22014-05-06 15:57:45 -04003576
Nicolas Capensf160b172014-11-26 11:58:23 -05003577 if(bufsize < 0)
3578 {
3579 return error(GL_INVALID_VALUE);
3580 }
John Bauman66b8ab22014-05-06 15:57:45 -04003581
Nicolas Capensf160b172014-11-26 11:58:23 -05003582 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003583
Nicolas Capensf160b172014-11-26 11:58:23 -05003584 if(context)
3585 {
3586 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04003587
Nicolas Capensf160b172014-11-26 11:58:23 -05003588 if(!shaderObject)
3589 {
3590 return error(GL_INVALID_OPERATION);
3591 }
John Bauman66b8ab22014-05-06 15:57:45 -04003592
Nicolas Capensf160b172014-11-26 11:58:23 -05003593 shaderObject->getSource(bufsize, length, source);
3594 }
John Bauman66b8ab22014-05-06 15:57:45 -04003595}
3596
Nicolas Capenseb195b62015-04-28 17:18:42 -07003597const GLubyte* GetString(GLenum name)
John Bauman66b8ab22014-05-06 15:57:45 -04003598{
Nicolas Capensf160b172014-11-26 11:58:23 -05003599 TRACE("(GLenum name = 0x%X)", name);
John Bauman66b8ab22014-05-06 15:57:45 -04003600
Nicolas Capensf160b172014-11-26 11:58:23 -05003601 switch(name)
3602 {
3603 case GL_VENDOR:
Alexis Hetu8141d7c2015-04-02 16:45:59 -04003604 return (GLubyte*)"Google Inc.";
Nicolas Capensf160b172014-11-26 11:58:23 -05003605 case GL_RENDERER:
Nicolas Capense3ae4282015-11-12 22:47:30 -05003606 return (GLubyte*)"Google SwiftShader";
Nicolas Capensf160b172014-11-26 11:58:23 -05003607 case GL_VERSION:
Alexis Hetu18bcfcc2015-07-03 10:57:21 -04003608 {
3609 es2::Context *context = es2::getContext();
3610 return (context && (context->getClientVersion() >= 3)) ?
3611 (GLubyte*)"OpenGL ES 3.0 SwiftShader " VERSION_STRING :
3612 (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
3613 }
Nicolas Capensf160b172014-11-26 11:58:23 -05003614 case GL_SHADING_LANGUAGE_VERSION:
Alexis Hetu18bcfcc2015-07-03 10:57:21 -04003615 {
3616 es2::Context *context = es2::getContext();
3617 return (context && (context->getClientVersion() >= 3)) ?
3618 (GLubyte*)"OpenGL ES GLSL ES 3.00 SwiftShader " VERSION_STRING :
3619 (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
3620 }
Nicolas Capensf160b172014-11-26 11:58:23 -05003621 case GL_EXTENSIONS:
Alexis Hetu8141d7c2015-04-02 16:45:59 -04003622 {
3623 es2::Context *context = es2::getContext();
3624 return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)NULL;
3625 }
Nicolas Capensf160b172014-11-26 11:58:23 -05003626 default:
3627 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3628 }
John Bauman66b8ab22014-05-06 15:57:45 -04003629}
3630
Nicolas Capenseb195b62015-04-28 17:18:42 -07003631void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003632{
Nicolas Capens4be33702015-04-28 15:13:30 -07003633 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003634
Nicolas Capensf160b172014-11-26 11:58:23 -05003635 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003636
Nicolas Capensf160b172014-11-26 11:58:23 -05003637 if(context)
3638 {
3639 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04003640
Alexis Hetued306182015-04-02 12:02:28 -04003641 egl::GLint clientVersion = context->getClientVersion();
3642
Nicolas Capensf160b172014-11-26 11:58:23 -05003643 switch(target)
3644 {
3645 case GL_TEXTURE_2D:
3646 texture = context->getTexture2D();
3647 break;
3648 case GL_TEXTURE_CUBE_MAP:
3649 texture = context->getTextureCubeMap();
3650 break;
3651 case GL_TEXTURE_EXTERNAL_OES:
3652 texture = context->getTextureExternal();
3653 break;
Alexis Hetued306182015-04-02 12:02:28 -04003654 case GL_TEXTURE_2D_ARRAY:
3655 if(clientVersion < 3)
3656 {
3657 return error(GL_INVALID_ENUM);
3658 }
3659 else
3660 {
Alexis Hetuf15e8942015-12-01 15:13:23 -05003661 texture = context->getTexture2DArray();
Alexis Hetued306182015-04-02 12:02:28 -04003662 }
Alexis Hetuf15e8942015-12-01 15:13:23 -05003663 break;
Alexis Hetued306182015-04-02 12:02:28 -04003664 case GL_TEXTURE_3D_OES:
3665 texture = context->getTexture3D();
3666 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003667 default:
3668 return error(GL_INVALID_ENUM);
3669 }
John Bauman66b8ab22014-05-06 15:57:45 -04003670
Nicolas Capensf160b172014-11-26 11:58:23 -05003671 switch(pname)
3672 {
3673 case GL_TEXTURE_MAG_FILTER:
3674 *params = (GLfloat)texture->getMagFilter();
3675 break;
3676 case GL_TEXTURE_MIN_FILTER:
3677 *params = (GLfloat)texture->getMinFilter();
3678 break;
3679 case GL_TEXTURE_WRAP_S:
3680 *params = (GLfloat)texture->getWrapS();
3681 break;
3682 case GL_TEXTURE_WRAP_T:
3683 *params = (GLfloat)texture->getWrapT();
3684 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05003685 case GL_TEXTURE_WRAP_R_OES:
3686 *params = (GLfloat)texture->getWrapR();
3687 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003688 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3689 *params = texture->getMaxAnisotropy();
3690 break;
3691 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3692 *params = (GLfloat)1;
3693 break;
Alexis Hetued306182015-04-02 12:02:28 -04003694 case GL_TEXTURE_BASE_LEVEL:
3695 if(clientVersion >= 3)
3696 {
3697 *params = (GLfloat)texture->getBaseLevel();
3698 break;
3699 }
3700 else return error(GL_INVALID_ENUM);
3701 case GL_TEXTURE_COMPARE_FUNC:
3702 if(clientVersion >= 3)
3703 {
3704 *params = (GLfloat)texture->getCompareFunc();
3705 break;
3706 }
3707 else return error(GL_INVALID_ENUM);
3708 case GL_TEXTURE_COMPARE_MODE:
3709 if(clientVersion >= 3)
3710 {
3711 *params = (GLfloat)texture->getCompareMode();
3712 break;
3713 }
3714 else return error(GL_INVALID_ENUM);
3715 case GL_TEXTURE_IMMUTABLE_FORMAT:
3716 if(clientVersion >= 3)
3717 {
3718 *params = (GLfloat)texture->getImmutableFormat();
3719 break;
3720 }
3721 else return error(GL_INVALID_ENUM);
3722 case GL_TEXTURE_MAX_LEVEL:
3723 if(clientVersion >= 3)
3724 {
3725 *params = (GLfloat)texture->getMaxLevel();
3726 break;
3727 }
3728 else return error(GL_INVALID_ENUM);
3729 case GL_TEXTURE_MAX_LOD:
3730 if(clientVersion >= 3)
3731 {
3732 *params = texture->getMaxLOD();
3733 break;
3734 }
3735 else return error(GL_INVALID_ENUM);
3736 case GL_TEXTURE_MIN_LOD:
3737 if(clientVersion >= 3)
3738 {
3739 *params = texture->getMinLOD();
3740 break;
3741 }
3742 else return error(GL_INVALID_ENUM);
3743 case GL_TEXTURE_SWIZZLE_R:
3744 if(clientVersion >= 3)
3745 {
3746 *params = (GLfloat)texture->getSwizzleR();
3747 break;
3748 }
3749 else return error(GL_INVALID_ENUM);
3750 case GL_TEXTURE_SWIZZLE_G:
3751 if(clientVersion >= 3)
3752 {
3753 *params = (GLfloat)texture->getSwizzleG();
3754 break;
3755 }
3756 else return error(GL_INVALID_ENUM);
3757 case GL_TEXTURE_SWIZZLE_B:
3758 if(clientVersion >= 3)
3759 {
3760 *params = (GLfloat)texture->getSwizzleB();
3761 break;
3762 }
3763 else return error(GL_INVALID_ENUM);
3764 case GL_TEXTURE_SWIZZLE_A:
3765 if(clientVersion >= 3)
3766 {
3767 *params = (GLfloat)texture->getSwizzleA();
3768 break;
3769 }
3770 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003771 default:
3772 return error(GL_INVALID_ENUM);
3773 }
3774 }
John Bauman66b8ab22014-05-06 15:57:45 -04003775}
3776
Nicolas Capenseb195b62015-04-28 17:18:42 -07003777void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003778{
Nicolas Capens4be33702015-04-28 15:13:30 -07003779 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003780
Nicolas Capensf160b172014-11-26 11:58:23 -05003781 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003782
Nicolas Capensf160b172014-11-26 11:58:23 -05003783 if(context)
3784 {
3785 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04003786
Alexis Hetued306182015-04-02 12:02:28 -04003787 egl::GLint clientVersion = context->getClientVersion();
3788
Nicolas Capensf160b172014-11-26 11:58:23 -05003789 switch(target)
3790 {
3791 case GL_TEXTURE_2D:
3792 texture = context->getTexture2D();
3793 break;
3794 case GL_TEXTURE_CUBE_MAP:
3795 texture = context->getTextureCubeMap();
3796 break;
3797 case GL_TEXTURE_EXTERNAL_OES:
3798 texture = context->getTextureExternal();
3799 break;
Alexis Hetued306182015-04-02 12:02:28 -04003800 case GL_TEXTURE_2D_ARRAY:
3801 if(clientVersion < 3)
3802 {
3803 return error(GL_INVALID_ENUM);
3804 }
3805 else
3806 {
Alexis Hetuf15e8942015-12-01 15:13:23 -05003807 texture = context->getTexture2DArray();
Alexis Hetued306182015-04-02 12:02:28 -04003808 }
Alexis Hetuf15e8942015-12-01 15:13:23 -05003809 break;
Alexis Hetued306182015-04-02 12:02:28 -04003810 case GL_TEXTURE_3D_OES:
3811 texture = context->getTexture3D();
3812 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003813 default:
3814 return error(GL_INVALID_ENUM);
3815 }
John Bauman66b8ab22014-05-06 15:57:45 -04003816
Nicolas Capensf160b172014-11-26 11:58:23 -05003817 switch(pname)
3818 {
3819 case GL_TEXTURE_MAG_FILTER:
3820 *params = texture->getMagFilter();
3821 break;
3822 case GL_TEXTURE_MIN_FILTER:
3823 *params = texture->getMinFilter();
3824 break;
3825 case GL_TEXTURE_WRAP_S:
3826 *params = texture->getWrapS();
3827 break;
3828 case GL_TEXTURE_WRAP_T:
3829 *params = texture->getWrapT();
3830 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05003831 case GL_TEXTURE_WRAP_R_OES:
3832 *params = texture->getWrapR();
3833 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05003834 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3835 *params = (GLint)texture->getMaxAnisotropy();
3836 break;
3837 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3838 *params = 1;
3839 break;
Alexis Hetued306182015-04-02 12:02:28 -04003840 case GL_TEXTURE_BASE_LEVEL:
3841 if(clientVersion >= 3)
3842 {
3843 *params = texture->getBaseLevel();
3844 break;
3845 }
3846 else return error(GL_INVALID_ENUM);
3847 case GL_TEXTURE_COMPARE_FUNC:
3848 if(clientVersion >= 3)
3849 {
3850 *params = (GLint)texture->getCompareFunc();
3851 break;
3852 }
3853 else return error(GL_INVALID_ENUM);
3854 case GL_TEXTURE_COMPARE_MODE:
3855 if(clientVersion >= 3)
3856 {
3857 *params = (GLint)texture->getCompareMode();
3858 break;
3859 }
3860 else return error(GL_INVALID_ENUM);
3861 case GL_TEXTURE_IMMUTABLE_FORMAT:
3862 if(clientVersion >= 3)
3863 {
3864 *params = (GLint)texture->getImmutableFormat();
3865 break;
3866 }
3867 else return error(GL_INVALID_ENUM);
3868 case GL_TEXTURE_MAX_LEVEL:
3869 if(clientVersion >= 3)
3870 {
3871 *params = texture->getMaxLevel();
3872 break;
3873 }
3874 else return error(GL_INVALID_ENUM);
3875 case GL_TEXTURE_MAX_LOD:
3876 if(clientVersion >= 3)
3877 {
Alexis Hetub1a071f2015-07-03 15:46:32 -04003878 *params = (GLint)roundf(texture->getMaxLOD());
Alexis Hetued306182015-04-02 12:02:28 -04003879 break;
3880 }
3881 else return error(GL_INVALID_ENUM);
3882 case GL_TEXTURE_MIN_LOD:
3883 if(clientVersion >= 3)
3884 {
Alexis Hetub1a071f2015-07-03 15:46:32 -04003885 *params = (GLint)roundf(texture->getMinLOD());
Alexis Hetued306182015-04-02 12:02:28 -04003886 break;
3887 }
3888 else return error(GL_INVALID_ENUM);
3889 case GL_TEXTURE_SWIZZLE_R:
3890 if(clientVersion >= 3)
3891 {
3892 *params = (GLint)texture->getSwizzleR();
3893 break;
3894 }
3895 else return error(GL_INVALID_ENUM);
3896 case GL_TEXTURE_SWIZZLE_G:
3897 if(clientVersion >= 3)
3898 {
3899 *params = (GLint)texture->getSwizzleG();
3900 break;
3901 }
3902 else return error(GL_INVALID_ENUM);
3903 case GL_TEXTURE_SWIZZLE_B:
3904 if(clientVersion >= 3)
3905 {
3906 *params = (GLint)texture->getSwizzleB();
3907 break;
3908 }
3909 else return error(GL_INVALID_ENUM);
3910 case GL_TEXTURE_SWIZZLE_A:
3911 if(clientVersion >= 3)
3912 {
3913 *params = (GLint)texture->getSwizzleA();
3914 break;
3915 }
3916 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05003917 default:
3918 return error(GL_INVALID_ENUM);
3919 }
3920 }
John Bauman66b8ab22014-05-06 15:57:45 -04003921}
3922
Nicolas Capenseb195b62015-04-28 17:18:42 -07003923void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003924{
Nicolas Capens4be33702015-04-28 15:13:30 -07003925 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003926 program, location, bufSize, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003927
Nicolas Capensf160b172014-11-26 11:58:23 -05003928 if(bufSize < 0)
3929 {
3930 return error(GL_INVALID_VALUE);
3931 }
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)
3936 {
3937 if(program == 0)
3938 {
3939 return error(GL_INVALID_VALUE);
3940 }
John Bauman66b8ab22014-05-06 15:57:45 -04003941
Nicolas Capensf160b172014-11-26 11:58:23 -05003942 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003943
Nicolas Capensf160b172014-11-26 11:58:23 -05003944 if(!programObject || !programObject->isLinked())
3945 {
3946 return error(GL_INVALID_OPERATION);
3947 }
John Bauman66b8ab22014-05-06 15:57:45 -04003948
Nicolas Capensf160b172014-11-26 11:58:23 -05003949 if(!programObject->getUniformfv(location, &bufSize, params))
3950 {
3951 return error(GL_INVALID_OPERATION);
3952 }
3953 }
John Bauman66b8ab22014-05-06 15:57:45 -04003954}
3955
Nicolas Capenseb195b62015-04-28 17:18:42 -07003956void GetUniformfv(GLuint program, GLint location, GLfloat* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003957{
Nicolas Capens4be33702015-04-28 15:13:30 -07003958 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003959
Nicolas Capensf160b172014-11-26 11:58:23 -05003960 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003961
Nicolas Capensf160b172014-11-26 11:58:23 -05003962 if(context)
3963 {
3964 if(program == 0)
3965 {
3966 return error(GL_INVALID_VALUE);
3967 }
John Bauman66b8ab22014-05-06 15:57:45 -04003968
Nicolas Capensf160b172014-11-26 11:58:23 -05003969 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04003970
Nicolas Capensf160b172014-11-26 11:58:23 -05003971 if(!programObject || !programObject->isLinked())
3972 {
3973 return error(GL_INVALID_OPERATION);
3974 }
John Bauman66b8ab22014-05-06 15:57:45 -04003975
Nicolas Capensf160b172014-11-26 11:58:23 -05003976 if(!programObject->getUniformfv(location, NULL, params))
3977 {
3978 return error(GL_INVALID_OPERATION);
3979 }
3980 }
John Bauman66b8ab22014-05-06 15:57:45 -04003981}
3982
Nicolas Capenseb195b62015-04-28 17:18:42 -07003983void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04003984{
Nicolas Capens4be33702015-04-28 15:13:30 -07003985 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05003986 program, location, bufSize, params);
John Bauman66b8ab22014-05-06 15:57:45 -04003987
Nicolas Capensf160b172014-11-26 11:58:23 -05003988 if(bufSize < 0)
3989 {
3990 return error(GL_INVALID_VALUE);
3991 }
John Bauman66b8ab22014-05-06 15:57:45 -04003992
Nicolas Capensf160b172014-11-26 11:58:23 -05003993 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04003994
Nicolas Capensf160b172014-11-26 11:58:23 -05003995 if(context)
3996 {
3997 if(program == 0)
3998 {
3999 return error(GL_INVALID_VALUE);
4000 }
John Bauman66b8ab22014-05-06 15:57:45 -04004001
Nicolas Capensf160b172014-11-26 11:58:23 -05004002 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004003
Nicolas Capensf160b172014-11-26 11:58:23 -05004004 if(!programObject || !programObject->isLinked())
4005 {
4006 return error(GL_INVALID_OPERATION);
4007 }
John Bauman66b8ab22014-05-06 15:57:45 -04004008
Nicolas Capensf160b172014-11-26 11:58:23 -05004009 if(!programObject)
4010 {
4011 return error(GL_INVALID_OPERATION);
4012 }
John Bauman66b8ab22014-05-06 15:57:45 -04004013
Nicolas Capensf160b172014-11-26 11:58:23 -05004014 if(!programObject->getUniformiv(location, &bufSize, params))
4015 {
4016 return error(GL_INVALID_OPERATION);
4017 }
4018 }
John Bauman66b8ab22014-05-06 15:57:45 -04004019}
4020
Nicolas Capenseb195b62015-04-28 17:18:42 -07004021void GetUniformiv(GLuint program, GLint location, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04004022{
Nicolas Capens4be33702015-04-28 15:13:30 -07004023 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
John Bauman66b8ab22014-05-06 15:57:45 -04004024
Nicolas Capensf160b172014-11-26 11:58:23 -05004025 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004026
Nicolas Capensf160b172014-11-26 11:58:23 -05004027 if(context)
4028 {
4029 if(program == 0)
4030 {
4031 return error(GL_INVALID_VALUE);
4032 }
John Bauman66b8ab22014-05-06 15:57:45 -04004033
Nicolas Capensf160b172014-11-26 11:58:23 -05004034 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004035
Nicolas Capensf160b172014-11-26 11:58:23 -05004036 if(!programObject || !programObject->isLinked())
4037 {
4038 return error(GL_INVALID_OPERATION);
4039 }
John Bauman66b8ab22014-05-06 15:57:45 -04004040
Nicolas Capensf160b172014-11-26 11:58:23 -05004041 if(!programObject)
4042 {
4043 return error(GL_INVALID_OPERATION);
4044 }
John Bauman66b8ab22014-05-06 15:57:45 -04004045
Nicolas Capensf160b172014-11-26 11:58:23 -05004046 if(!programObject->getUniformiv(location, NULL, params))
4047 {
4048 return error(GL_INVALID_OPERATION);
4049 }
4050 }
John Bauman66b8ab22014-05-06 15:57:45 -04004051}
4052
Nicolas Capenseb195b62015-04-28 17:18:42 -07004053int GetUniformLocation(GLuint program, const GLchar* name)
John Bauman66b8ab22014-05-06 15:57:45 -04004054{
Nicolas Capensf160b172014-11-26 11:58:23 -05004055 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
John Bauman66b8ab22014-05-06 15:57:45 -04004056
Nicolas Capensf160b172014-11-26 11:58:23 -05004057 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004058
Nicolas Capensf160b172014-11-26 11:58:23 -05004059 if(strstr(name, "gl_") == name)
4060 {
4061 return -1;
4062 }
John Bauman66b8ab22014-05-06 15:57:45 -04004063
Nicolas Capensf160b172014-11-26 11:58:23 -05004064 if(context)
4065 {
4066 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004067
Nicolas Capensf160b172014-11-26 11:58:23 -05004068 if(!programObject)
4069 {
4070 if(context->getShader(program))
4071 {
4072 return error(GL_INVALID_OPERATION, -1);
4073 }
4074 else
4075 {
4076 return error(GL_INVALID_VALUE, -1);
4077 }
4078 }
John Bauman66b8ab22014-05-06 15:57:45 -04004079
Nicolas Capensf160b172014-11-26 11:58:23 -05004080 if(!programObject->isLinked())
4081 {
4082 return error(GL_INVALID_OPERATION, -1);
4083 }
John Bauman66b8ab22014-05-06 15:57:45 -04004084
Nicolas Capensf160b172014-11-26 11:58:23 -05004085 return programObject->getUniformLocation(name);
4086 }
John Bauman66b8ab22014-05-06 15:57:45 -04004087
Nicolas Capensf160b172014-11-26 11:58:23 -05004088 return -1;
John Bauman66b8ab22014-05-06 15:57:45 -04004089}
4090
Nicolas Capenseb195b62015-04-28 17:18:42 -07004091void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
John Bauman66b8ab22014-05-06 15:57:45 -04004092{
Nicolas Capens4be33702015-04-28 15:13:30 -07004093 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04004094
Nicolas Capensf160b172014-11-26 11:58:23 -05004095 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004096
Nicolas Capensf160b172014-11-26 11:58:23 -05004097 if(context)
4098 {
4099 if(index >= es2::MAX_VERTEX_ATTRIBS)
4100 {
4101 return error(GL_INVALID_VALUE);
4102 }
John Bauman66b8ab22014-05-06 15:57:45 -04004103
Nicolas Capensf160b172014-11-26 11:58:23 -05004104 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
Nicolas Capensccee6a82015-04-28 16:49:59 -07004105
Alexis Hetued306182015-04-02 12:02:28 -04004106 egl::GLint clientVersion = context->getClientVersion();
John Bauman66b8ab22014-05-06 15:57:45 -04004107
Nicolas Capensf160b172014-11-26 11:58:23 -05004108 switch(pname)
4109 {
4110 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
4111 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
4112 break;
4113 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
4114 *params = (GLfloat)attribState.mSize;
4115 break;
4116 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
4117 *params = (GLfloat)attribState.mStride;
4118 break;
4119 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
4120 *params = (GLfloat)attribState.mType;
4121 break;
4122 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
4123 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
4124 break;
4125 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004126 *params = (GLfloat)attribState.mBoundBuffer.name();
Nicolas Capensf160b172014-11-26 11:58:23 -05004127 break;
4128 case GL_CURRENT_VERTEX_ATTRIB:
Nicolas Capensf160b172014-11-26 11:58:23 -05004129 {
Alexis Hetub4d557d2015-04-24 17:25:10 -04004130 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
4131 for(int i = 0; i < 4; ++i)
4132 {
Alexis Hetu02a2bb82015-08-20 14:10:33 -04004133 params[i] = attrib.getCurrentValueF(i);
Alexis Hetub4d557d2015-04-24 17:25:10 -04004134 }
Nicolas Capensf160b172014-11-26 11:58:23 -05004135 }
4136 break;
Alexis Hetued306182015-04-02 12:02:28 -04004137 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
4138 if(clientVersion >= 3)
4139 {
4140 switch(attribState.mType)
4141 {
4142 case GL_BYTE:
4143 case GL_UNSIGNED_BYTE:
4144 case GL_SHORT:
4145 case GL_UNSIGNED_SHORT:
4146 case GL_INT:
4147 case GL_INT_2_10_10_10_REV:
4148 case GL_UNSIGNED_INT:
4149 case GL_FIXED:
4150 *params = (GLfloat)GL_TRUE;
4151 break;
4152 default:
4153 *params = (GLfloat)GL_FALSE;
4154 break;
4155 }
4156 break;
4157 }
4158 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05004159 default: return error(GL_INVALID_ENUM);
4160 }
4161 }
John Bauman66b8ab22014-05-06 15:57:45 -04004162}
4163
Nicolas Capenseb195b62015-04-28 17:18:42 -07004164void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04004165{
Nicolas Capens4be33702015-04-28 15:13:30 -07004166 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
John Bauman66b8ab22014-05-06 15:57:45 -04004167
Nicolas Capensf160b172014-11-26 11:58:23 -05004168 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004169
Nicolas Capensf160b172014-11-26 11:58:23 -05004170 if(context)
4171 {
4172 if(index >= es2::MAX_VERTEX_ATTRIBS)
4173 {
4174 return error(GL_INVALID_VALUE);
4175 }
John Bauman66b8ab22014-05-06 15:57:45 -04004176
Nicolas Capensf160b172014-11-26 11:58:23 -05004177 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
John Bauman66b8ab22014-05-06 15:57:45 -04004178
Alexis Hetued306182015-04-02 12:02:28 -04004179 egl::GLint clientVersion = context->getClientVersion();
4180
Nicolas Capensf160b172014-11-26 11:58:23 -05004181 switch(pname)
4182 {
4183 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
4184 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
4185 break;
4186 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
4187 *params = attribState.mSize;
4188 break;
4189 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
4190 *params = attribState.mStride;
4191 break;
4192 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
4193 *params = attribState.mType;
4194 break;
4195 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
4196 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
4197 break;
4198 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004199 *params = attribState.mBoundBuffer.name();
Nicolas Capensf160b172014-11-26 11:58:23 -05004200 break;
4201 case GL_CURRENT_VERTEX_ATTRIB:
Nicolas Capensf160b172014-11-26 11:58:23 -05004202 {
Alexis Hetub4d557d2015-04-24 17:25:10 -04004203 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
4204 for(int i = 0; i < 4; ++i)
4205 {
Alexis Hetu02a2bb82015-08-20 14:10:33 -04004206 float currentValue = attrib.getCurrentValueF(i);
Alexis Hetub4d557d2015-04-24 17:25:10 -04004207 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4208 }
Nicolas Capensf160b172014-11-26 11:58:23 -05004209 }
4210 break;
Alexis Hetued306182015-04-02 12:02:28 -04004211 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
4212 if(clientVersion >= 3)
4213 {
4214 switch(attribState.mType)
4215 {
4216 case GL_BYTE:
4217 case GL_UNSIGNED_BYTE:
4218 case GL_SHORT:
4219 case GL_UNSIGNED_SHORT:
4220 case GL_INT:
4221 case GL_INT_2_10_10_10_REV:
4222 case GL_UNSIGNED_INT:
4223 case GL_FIXED:
4224 *params = GL_TRUE;
4225 break;
4226 default:
4227 *params = GL_FALSE;
4228 break;
4229 }
4230 break;
4231 }
4232 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05004233 default: return error(GL_INVALID_ENUM);
4234 }
4235 }
John Bauman66b8ab22014-05-06 15:57:45 -04004236}
4237
Nicolas Capenseb195b62015-04-28 17:18:42 -07004238void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
John Bauman66b8ab22014-05-06 15:57:45 -04004239{
Nicolas Capens4be33702015-04-28 15:13:30 -07004240 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
John Bauman66b8ab22014-05-06 15:57:45 -04004241
Nicolas Capensf160b172014-11-26 11:58:23 -05004242 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004243
Nicolas Capensf160b172014-11-26 11:58:23 -05004244 if(context)
4245 {
4246 if(index >= es2::MAX_VERTEX_ATTRIBS)
4247 {
4248 return error(GL_INVALID_VALUE);
4249 }
John Bauman66b8ab22014-05-06 15:57:45 -04004250
Nicolas Capensf160b172014-11-26 11:58:23 -05004251 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4252 {
4253 return error(GL_INVALID_ENUM);
4254 }
John Bauman66b8ab22014-05-06 15:57:45 -04004255
Nicolas Capensf160b172014-11-26 11:58:23 -05004256 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
4257 }
John Bauman66b8ab22014-05-06 15:57:45 -04004258}
4259
Nicolas Capenseb195b62015-04-28 17:18:42 -07004260void Hint(GLenum target, GLenum mode)
John Bauman66b8ab22014-05-06 15:57:45 -04004261{
Nicolas Capensf160b172014-11-26 11:58:23 -05004262 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
John Bauman66b8ab22014-05-06 15:57:45 -04004263
Nicolas Capensf160b172014-11-26 11:58:23 -05004264 switch(mode)
4265 {
4266 case GL_FASTEST:
4267 case GL_NICEST:
4268 case GL_DONT_CARE:
4269 break;
4270 default:
4271 return error(GL_INVALID_ENUM);
4272 }
John Bauman66b8ab22014-05-06 15:57:45 -04004273
Nicolas Capensf160b172014-11-26 11:58:23 -05004274 es2::Context *context = es2::getContext();
4275 switch(target)
4276 {
4277 case GL_GENERATE_MIPMAP_HINT:
4278 if(context) context->setGenerateMipmapHint(mode);
4279 break;
4280 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4281 if(context) context->setFragmentShaderDerivativeHint(mode);
4282 break;
4283 default:
4284 return error(GL_INVALID_ENUM);
4285 }
John Bauman66b8ab22014-05-06 15:57:45 -04004286}
4287
Nicolas Capenseb195b62015-04-28 17:18:42 -07004288GLboolean IsBuffer(GLuint buffer)
John Bauman66b8ab22014-05-06 15:57:45 -04004289{
Nicolas Capensf160b172014-11-26 11:58:23 -05004290 TRACE("(GLuint buffer = %d)", buffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004291
Nicolas Capensf160b172014-11-26 11:58:23 -05004292 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004293
Nicolas Capensf160b172014-11-26 11:58:23 -05004294 if(context && buffer)
4295 {
4296 es2::Buffer *bufferObject = context->getBuffer(buffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004297
Nicolas Capensf160b172014-11-26 11:58:23 -05004298 if(bufferObject)
4299 {
4300 return GL_TRUE;
4301 }
4302 }
John Bauman66b8ab22014-05-06 15:57:45 -04004303
Nicolas Capensf160b172014-11-26 11:58:23 -05004304 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004305}
4306
Nicolas Capenseb195b62015-04-28 17:18:42 -07004307GLboolean IsEnabled(GLenum cap)
John Bauman66b8ab22014-05-06 15:57:45 -04004308{
Nicolas Capensf160b172014-11-26 11:58:23 -05004309 TRACE("(GLenum cap = 0x%X)", cap);
John Bauman66b8ab22014-05-06 15:57:45 -04004310
Nicolas Capensf160b172014-11-26 11:58:23 -05004311 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004312
Nicolas Capensf160b172014-11-26 11:58:23 -05004313 if(context)
4314 {
Alexis Hetu5bf8c172015-06-23 11:24:48 -04004315 egl::GLint clientVersion = context->getClientVersion();
4316
Nicolas Capensf160b172014-11-26 11:58:23 -05004317 switch(cap)
4318 {
4319 case GL_CULL_FACE: return context->isCullFaceEnabled();
4320 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4321 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4322 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4323 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4324 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4325 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4326 case GL_BLEND: return context->isBlendEnabled();
4327 case GL_DITHER: return context->isDitherEnabled();
Alexis Hetu5bf8c172015-06-23 11:24:48 -04004328 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4329 if(clientVersion >= 3)
4330 {
4331 return context->isPrimitiveRestartFixedIndexEnabled();
4332 }
4333 else return error(GL_INVALID_ENUM, false);
4334 case GL_RASTERIZER_DISCARD:
4335 if(clientVersion >= 3)
4336 {
4337 return context->isRasterizerDiscardEnabled();
4338 }
4339 else return error(GL_INVALID_ENUM, false);
Nicolas Capensf160b172014-11-26 11:58:23 -05004340 default:
4341 return error(GL_INVALID_ENUM, false);
4342 }
4343 }
John Bauman66b8ab22014-05-06 15:57:45 -04004344
Nicolas Capensf160b172014-11-26 11:58:23 -05004345 return false;
John Bauman66b8ab22014-05-06 15:57:45 -04004346}
4347
Nicolas Capenseb195b62015-04-28 17:18:42 -07004348GLboolean IsFenceNV(GLuint fence)
John Bauman66b8ab22014-05-06 15:57:45 -04004349{
Nicolas Capensf160b172014-11-26 11:58:23 -05004350 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004351
Nicolas Capensf160b172014-11-26 11:58:23 -05004352 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004353
Nicolas Capensf160b172014-11-26 11:58:23 -05004354 if(context)
4355 {
4356 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004357
Nicolas Capensf160b172014-11-26 11:58:23 -05004358 if(fenceObject == NULL)
4359 {
4360 return GL_FALSE;
4361 }
John Bauman66b8ab22014-05-06 15:57:45 -04004362
Nicolas Capensf160b172014-11-26 11:58:23 -05004363 return fenceObject->isFence();
4364 }
John Bauman66b8ab22014-05-06 15:57:45 -04004365
Nicolas Capensf160b172014-11-26 11:58:23 -05004366 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004367}
4368
Nicolas Capenseb195b62015-04-28 17:18:42 -07004369GLboolean IsFramebuffer(GLuint framebuffer)
John Bauman66b8ab22014-05-06 15:57:45 -04004370{
Nicolas Capensf160b172014-11-26 11:58:23 -05004371 TRACE("(GLuint framebuffer = %d)", framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004372
Nicolas Capensf160b172014-11-26 11:58:23 -05004373 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004374
Nicolas Capensf160b172014-11-26 11:58:23 -05004375 if(context && framebuffer)
4376 {
4377 es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004378
Nicolas Capensf160b172014-11-26 11:58:23 -05004379 if(framebufferObject)
4380 {
4381 return GL_TRUE;
4382 }
4383 }
John Bauman66b8ab22014-05-06 15:57:45 -04004384
Nicolas Capensf160b172014-11-26 11:58:23 -05004385 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004386}
4387
Nicolas Capenseb195b62015-04-28 17:18:42 -07004388GLboolean IsProgram(GLuint program)
John Bauman66b8ab22014-05-06 15:57:45 -04004389{
Nicolas Capensf160b172014-11-26 11:58:23 -05004390 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04004391
Nicolas Capensf160b172014-11-26 11:58:23 -05004392 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004393
Nicolas Capensf160b172014-11-26 11:58:23 -05004394 if(context && program)
4395 {
4396 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004397
Nicolas Capensf160b172014-11-26 11:58:23 -05004398 if(programObject)
4399 {
4400 return GL_TRUE;
4401 }
4402 }
John Bauman66b8ab22014-05-06 15:57:45 -04004403
Nicolas Capensf160b172014-11-26 11:58:23 -05004404 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004405}
4406
Nicolas Capenseb195b62015-04-28 17:18:42 -07004407GLboolean IsQueryEXT(GLuint name)
John Bauman66b8ab22014-05-06 15:57:45 -04004408{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004409 TRACE("(GLuint name = %d)", name);
John Bauman66b8ab22014-05-06 15:57:45 -04004410
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004411 if(name == 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05004412 {
4413 return GL_FALSE;
4414 }
John Bauman66b8ab22014-05-06 15:57:45 -04004415
Nicolas Capensf160b172014-11-26 11:58:23 -05004416 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004417
Nicolas Capensf160b172014-11-26 11:58:23 -05004418 if(context)
4419 {
Alexis Hetu8e32f7b2015-04-28 09:59:09 -04004420 es2::Query *queryObject = context->getQuery(name);
John Bauman66b8ab22014-05-06 15:57:45 -04004421
Nicolas Capensf160b172014-11-26 11:58:23 -05004422 if(queryObject)
4423 {
4424 return GL_TRUE;
4425 }
4426 }
John Bauman66b8ab22014-05-06 15:57:45 -04004427
Nicolas Capensf160b172014-11-26 11:58:23 -05004428 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004429}
4430
Nicolas Capenseb195b62015-04-28 17:18:42 -07004431GLboolean IsRenderbuffer(GLuint renderbuffer)
John Bauman66b8ab22014-05-06 15:57:45 -04004432{
Nicolas Capensf160b172014-11-26 11:58:23 -05004433 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004434
Nicolas Capensf160b172014-11-26 11:58:23 -05004435 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004436
Nicolas Capensf160b172014-11-26 11:58:23 -05004437 if(context && renderbuffer)
4438 {
4439 es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
John Bauman66b8ab22014-05-06 15:57:45 -04004440
Nicolas Capensf160b172014-11-26 11:58:23 -05004441 if(renderbufferObject)
4442 {
4443 return GL_TRUE;
4444 }
4445 }
John Bauman66b8ab22014-05-06 15:57:45 -04004446
Nicolas Capensf160b172014-11-26 11:58:23 -05004447 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004448}
4449
Nicolas Capenseb195b62015-04-28 17:18:42 -07004450GLboolean IsShader(GLuint shader)
John Bauman66b8ab22014-05-06 15:57:45 -04004451{
Nicolas Capensf160b172014-11-26 11:58:23 -05004452 TRACE("(GLuint shader = %d)", shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004453
Nicolas Capensf160b172014-11-26 11:58:23 -05004454 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004455
Nicolas Capensf160b172014-11-26 11:58:23 -05004456 if(context && shader)
4457 {
4458 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004459
Nicolas Capensf160b172014-11-26 11:58:23 -05004460 if(shaderObject)
4461 {
4462 return GL_TRUE;
4463 }
4464 }
John Bauman66b8ab22014-05-06 15:57:45 -04004465
Nicolas Capensf160b172014-11-26 11:58:23 -05004466 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004467}
4468
Nicolas Capenseb195b62015-04-28 17:18:42 -07004469GLboolean IsTexture(GLuint texture)
John Bauman66b8ab22014-05-06 15:57:45 -04004470{
Nicolas Capensf160b172014-11-26 11:58:23 -05004471 TRACE("(GLuint texture = %d)", texture);
John Bauman66b8ab22014-05-06 15:57:45 -04004472
Nicolas Capensf160b172014-11-26 11:58:23 -05004473 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004474
Nicolas Capensf160b172014-11-26 11:58:23 -05004475 if(context && texture)
4476 {
4477 es2::Texture *textureObject = context->getTexture(texture);
John Bauman66b8ab22014-05-06 15:57:45 -04004478
Nicolas Capensf160b172014-11-26 11:58:23 -05004479 if(textureObject)
4480 {
4481 return GL_TRUE;
4482 }
4483 }
John Bauman66b8ab22014-05-06 15:57:45 -04004484
Nicolas Capensf160b172014-11-26 11:58:23 -05004485 return GL_FALSE;
John Bauman66b8ab22014-05-06 15:57:45 -04004486}
4487
Nicolas Capenseb195b62015-04-28 17:18:42 -07004488void LineWidth(GLfloat width)
John Bauman66b8ab22014-05-06 15:57:45 -04004489{
Nicolas Capensf160b172014-11-26 11:58:23 -05004490 TRACE("(GLfloat width = %f)", width);
John Bauman66b8ab22014-05-06 15:57:45 -04004491
Nicolas Capensf160b172014-11-26 11:58:23 -05004492 if(width <= 0.0f)
4493 {
4494 return error(GL_INVALID_VALUE);
4495 }
John Bauman66b8ab22014-05-06 15:57:45 -04004496
Nicolas Capensf160b172014-11-26 11:58:23 -05004497 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004498
Nicolas Capensf160b172014-11-26 11:58:23 -05004499 if(context)
4500 {
4501 context->setLineWidth(width);
4502 }
John Bauman66b8ab22014-05-06 15:57:45 -04004503}
4504
Nicolas Capenseb195b62015-04-28 17:18:42 -07004505void LinkProgram(GLuint program)
John Bauman66b8ab22014-05-06 15:57:45 -04004506{
Nicolas Capensf160b172014-11-26 11:58:23 -05004507 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04004508
Nicolas Capensf160b172014-11-26 11:58:23 -05004509 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004510
Nicolas Capensf160b172014-11-26 11:58:23 -05004511 if(context)
4512 {
4513 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04004514
Nicolas Capensf160b172014-11-26 11:58:23 -05004515 if(!programObject)
4516 {
4517 if(context->getShader(program))
4518 {
4519 return error(GL_INVALID_OPERATION);
4520 }
4521 else
4522 {
4523 return error(GL_INVALID_VALUE);
4524 }
4525 }
John Bauman66b8ab22014-05-06 15:57:45 -04004526
Nicolas Capensf160b172014-11-26 11:58:23 -05004527 programObject->link();
4528 }
John Bauman66b8ab22014-05-06 15:57:45 -04004529}
4530
Nicolas Capenseb195b62015-04-28 17:18:42 -07004531void PixelStorei(GLenum pname, GLint param)
John Bauman66b8ab22014-05-06 15:57:45 -04004532{
Nicolas Capensf160b172014-11-26 11:58:23 -05004533 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04004534
Nicolas Capensf160b172014-11-26 11:58:23 -05004535 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004536
Nicolas Capensf160b172014-11-26 11:58:23 -05004537 if(context)
4538 {
Alexis Hetued306182015-04-02 12:02:28 -04004539 egl::GLint clientVersion = context->getClientVersion();
4540
Nicolas Capensf160b172014-11-26 11:58:23 -05004541 switch(pname)
4542 {
4543 case GL_UNPACK_ALIGNMENT:
4544 if(param != 1 && param != 2 && param != 4 && param != 8)
4545 {
4546 return error(GL_INVALID_VALUE);
4547 }
4548 context->setUnpackAlignment(param);
4549 break;
4550 case GL_PACK_ALIGNMENT:
4551 if(param != 1 && param != 2 && param != 4 && param != 8)
4552 {
4553 return error(GL_INVALID_VALUE);
4554 }
4555 context->setPackAlignment(param);
4556 break;
Alexis Hetued306182015-04-02 12:02:28 -04004557 case GL_PACK_ROW_LENGTH:
Alexis Hetued306182015-04-02 12:02:28 -04004558 if(clientVersion >= 3)
4559 {
Alexis Hetuc7b05102015-04-23 16:19:53 -04004560 if(param < 0)
4561 {
4562 return error(GL_INVALID_VALUE);
4563 }
4564 context->setPackRowLength(param);
4565 break;
4566 }
4567 else return error(GL_INVALID_ENUM);
4568 case GL_PACK_SKIP_PIXELS:
4569 if(clientVersion >= 3)
4570 {
4571 if(param < 0)
4572 {
4573 return error(GL_INVALID_VALUE);
4574 }
4575 context->setPackSkipPixels(param);
4576 break;
4577 }
4578 else return error(GL_INVALID_ENUM);
4579 case GL_PACK_SKIP_ROWS:
4580 if(clientVersion >= 3)
4581 {
4582 if(param < 0)
4583 {
4584 return error(GL_INVALID_VALUE);
4585 }
4586 context->setPackSkipRows(param);
4587 break;
4588 }
4589 else return error(GL_INVALID_ENUM);
4590 case GL_UNPACK_ROW_LENGTH:
4591 if(clientVersion >= 3)
4592 {
4593 if(param < 0)
4594 {
4595 return error(GL_INVALID_VALUE);
4596 }
4597 context->setUnpackRowLength(param);
4598 break;
4599 }
4600 else return error(GL_INVALID_ENUM);
4601 case GL_UNPACK_IMAGE_HEIGHT:
4602 if(clientVersion >= 3)
4603 {
4604 if(param < 0)
4605 {
4606 return error(GL_INVALID_VALUE);
4607 }
4608 context->setUnpackImageHeight(param);
4609 break;
4610 }
4611 else return error(GL_INVALID_ENUM);
4612 case GL_UNPACK_SKIP_PIXELS:
4613 if(clientVersion >= 3)
4614 {
4615 if(param < 0)
4616 {
4617 return error(GL_INVALID_VALUE);
4618 }
4619 context->setUnpackSkipPixels(param);
4620 break;
4621 }
4622 else return error(GL_INVALID_ENUM);
4623 case GL_UNPACK_SKIP_ROWS:
4624 if(clientVersion >= 3)
4625 {
4626 if(param < 0)
4627 {
4628 return error(GL_INVALID_VALUE);
4629 }
4630 context->setUnpackSkipRows(param);
4631 break;
4632 }
4633 else return error(GL_INVALID_ENUM);
4634 case GL_UNPACK_SKIP_IMAGES:
4635 if(clientVersion >= 3) {
4636 if(param < 0)
4637 {
4638 return error(GL_INVALID_VALUE);
4639 }
4640 context->setUnpackSkipImages(param);
Alexis Hetued306182015-04-02 12:02:28 -04004641 break;
4642 }
4643 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05004644 default:
4645 return error(GL_INVALID_ENUM);
4646 }
4647 }
John Bauman66b8ab22014-05-06 15:57:45 -04004648}
4649
Nicolas Capenseb195b62015-04-28 17:18:42 -07004650void PolygonOffset(GLfloat factor, GLfloat units)
John Bauman66b8ab22014-05-06 15:57:45 -04004651{
Nicolas Capensf160b172014-11-26 11:58:23 -05004652 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
John Bauman66b8ab22014-05-06 15:57:45 -04004653
Nicolas Capensf160b172014-11-26 11:58:23 -05004654 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004655
Nicolas Capensf160b172014-11-26 11:58:23 -05004656 if(context)
4657 {
4658 context->setPolygonOffsetParams(factor, units);
4659 }
John Bauman66b8ab22014-05-06 15:57:45 -04004660}
4661
Nicolas Capenseb195b62015-04-28 17:18:42 -07004662void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4663 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
John Bauman66b8ab22014-05-06 15:57:45 -04004664{
Nicolas Capensf160b172014-11-26 11:58:23 -05004665 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004666 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004667 x, y, width, height, format, type, bufSize, data);
John Bauman66b8ab22014-05-06 15:57:45 -04004668
Nicolas Capensf160b172014-11-26 11:58:23 -05004669 if(width < 0 || height < 0 || bufSize < 0)
4670 {
4671 return error(GL_INVALID_VALUE);
4672 }
John Bauman66b8ab22014-05-06 15:57:45 -04004673
Nicolas Capensf160b172014-11-26 11:58:23 -05004674 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004675
Nicolas Capensf160b172014-11-26 11:58:23 -05004676 if(context)
4677 {
4678 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4679 }
John Bauman66b8ab22014-05-06 15:57:45 -04004680}
4681
Nicolas Capenseb195b62015-04-28 17:18:42 -07004682void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04004683{
Nicolas Capensf160b172014-11-26 11:58:23 -05004684 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004685 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004686 x, y, width, height, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04004687
Nicolas Capensf160b172014-11-26 11:58:23 -05004688 if(width < 0 || height < 0)
4689 {
4690 return error(GL_INVALID_VALUE);
4691 }
John Bauman66b8ab22014-05-06 15:57:45 -04004692
Nicolas Capensf160b172014-11-26 11:58:23 -05004693 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004694
Nicolas Capensf160b172014-11-26 11:58:23 -05004695 if(context)
4696 {
4697 context->readPixels(x, y, width, height, format, type, NULL, pixels);
4698 }
John Bauman66b8ab22014-05-06 15:57:45 -04004699}
4700
Nicolas Capenseb195b62015-04-28 17:18:42 -07004701void ReleaseShaderCompiler(void)
John Bauman66b8ab22014-05-06 15:57:45 -04004702{
Nicolas Capensf160b172014-11-26 11:58:23 -05004703 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -04004704
Nicolas Capensf160b172014-11-26 11:58:23 -05004705 es2::Shader::releaseCompiler();
John Bauman66b8ab22014-05-06 15:57:45 -04004706}
4707
Nicolas Capenseb195b62015-04-28 17:18:42 -07004708void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
John Bauman66b8ab22014-05-06 15:57:45 -04004709{
Nicolas Capensf160b172014-11-26 11:58:23 -05004710 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4711 target, samples, internalformat, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004712
Nicolas Capensf160b172014-11-26 11:58:23 -05004713 switch(target)
4714 {
4715 case GL_RENDERBUFFER:
4716 break;
4717 default:
4718 return error(GL_INVALID_ENUM);
4719 }
John Bauman66b8ab22014-05-06 15:57:45 -04004720
Nicolas Capensf160b172014-11-26 11:58:23 -05004721 if(width < 0 || height < 0 || samples < 0)
4722 {
4723 return error(GL_INVALID_VALUE);
4724 }
John Bauman66b8ab22014-05-06 15:57:45 -04004725
Nicolas Capensf160b172014-11-26 11:58:23 -05004726 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004727
Nicolas Capensf160b172014-11-26 11:58:23 -05004728 if(context)
4729 {
4730 if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4731 height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4732 samples > es2::IMPLEMENTATION_MAX_SAMPLES)
4733 {
4734 return error(GL_INVALID_VALUE);
4735 }
John Bauman66b8ab22014-05-06 15:57:45 -04004736
Nicolas Capens7cc75e12015-01-29 14:44:24 -05004737 GLuint handle = context->getRenderbufferName();
Nicolas Capensf160b172014-11-26 11:58:23 -05004738 if(handle == 0)
4739 {
4740 return error(GL_INVALID_OPERATION);
4741 }
John Bauman66b8ab22014-05-06 15:57:45 -04004742
Alexis Hetu8f604582015-05-27 16:58:29 -04004743 egl::GLint clientVersion = context->getClientVersion();
Nicolas Capensf160b172014-11-26 11:58:23 -05004744 switch(internalformat)
4745 {
Alexis Hetu8f604582015-05-27 16:58:29 -04004746 case GL_DEPTH_COMPONENT32F:
4747 if(clientVersion < 3)
4748 {
4749 return error(GL_INVALID_ENUM);
4750 }
4751 // fall through
Nicolas Capensf160b172014-11-26 11:58:23 -05004752 case GL_DEPTH_COMPONENT16:
Alexis Hetue7277752015-12-04 11:16:35 -05004753 case GL_DEPTH_COMPONENT24:
4754 case GL_DEPTH_COMPONENT32_OES:
Nicolas Capensf160b172014-11-26 11:58:23 -05004755 context->setRenderbufferStorage(new es2::Depthbuffer(width, height, samples));
4756 break;
Alexis Hetu8f604582015-05-27 16:58:29 -04004757 case GL_R8:
4758 case GL_R8UI:
4759 case GL_R8I:
4760 case GL_R16UI:
4761 case GL_R16I:
4762 case GL_R32UI:
4763 case GL_R32I:
4764 case GL_RG8:
4765 case GL_RG8UI:
4766 case GL_RG8I:
4767 case GL_RG16UI:
4768 case GL_RG16I:
4769 case GL_RG32UI:
4770 case GL_RG32I:
4771 case GL_SRGB8_ALPHA8:
4772 case GL_RGB10_A2:
4773 case GL_RGBA8UI:
4774 case GL_RGBA8I:
4775 case GL_RGB10_A2UI:
4776 case GL_RGBA16UI:
4777 case GL_RGBA16I:
4778 case GL_RGBA32I:
4779 case GL_RGBA32UI:
Alexis Hetuc8f95e82015-11-12 16:36:34 -05004780 case GL_R16F:
4781 case GL_RG16F:
4782 case GL_R11F_G11F_B10F:
4783 case GL_RGBA16F:
4784 case GL_R32F:
4785 case GL_RG32F:
4786 case GL_RGB32F:
4787 case GL_RGBA32F:
Alexis Hetu8f604582015-05-27 16:58:29 -04004788 if(clientVersion < 3)
4789 {
4790 return error(GL_INVALID_ENUM);
4791 }
4792 // fall through
Nicolas Capensf160b172014-11-26 11:58:23 -05004793 case GL_RGBA4:
4794 case GL_RGB5_A1:
4795 case GL_RGB565:
4796 case GL_RGB8_OES:
4797 case GL_RGBA8_OES:
4798 context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
4799 break;
4800 case GL_STENCIL_INDEX8:
4801 context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
4802 break;
Alexis Hetu8f604582015-05-27 16:58:29 -04004803 case GL_DEPTH32F_STENCIL8:
4804 if(clientVersion < 3)
4805 {
4806 return error(GL_INVALID_ENUM);
4807 }
4808 // fall through
Nicolas Capensf160b172014-11-26 11:58:23 -05004809 case GL_DEPTH24_STENCIL8_OES:
4810 context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, samples));
4811 break;
4812 default:
4813 return error(GL_INVALID_ENUM);
4814 }
4815 }
John Bauman66b8ab22014-05-06 15:57:45 -04004816}
4817
Nicolas Capenseb195b62015-04-28 17:18:42 -07004818void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
John Bauman66b8ab22014-05-06 15:57:45 -04004819{
Nicolas Capensf160b172014-11-26 11:58:23 -05004820 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004821}
4822
Nicolas Capenseb195b62015-04-28 17:18:42 -07004823void SampleCoverage(GLclampf value, GLboolean invert)
John Bauman66b8ab22014-05-06 15:57:45 -04004824{
Nicolas Capensf160b172014-11-26 11:58:23 -05004825 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
John Bauman66b8ab22014-05-06 15:57:45 -04004826
Nicolas Capensf160b172014-11-26 11:58:23 -05004827 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004828
Nicolas Capensf160b172014-11-26 11:58:23 -05004829 if(context)
4830 {
4831 context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
4832 }
John Bauman66b8ab22014-05-06 15:57:45 -04004833}
4834
Nicolas Capenseb195b62015-04-28 17:18:42 -07004835void SetFenceNV(GLuint fence, GLenum condition)
John Bauman66b8ab22014-05-06 15:57:45 -04004836{
Nicolas Capensf160b172014-11-26 11:58:23 -05004837 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
John Bauman66b8ab22014-05-06 15:57:45 -04004838
Nicolas Capensf160b172014-11-26 11:58:23 -05004839 if(condition != GL_ALL_COMPLETED_NV)
4840 {
4841 return error(GL_INVALID_ENUM);
4842 }
John Bauman66b8ab22014-05-06 15:57:45 -04004843
Nicolas Capensf160b172014-11-26 11:58:23 -05004844 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004845
Nicolas Capensf160b172014-11-26 11:58:23 -05004846 if(context)
4847 {
4848 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04004849
Nicolas Capensf160b172014-11-26 11:58:23 -05004850 if(fenceObject == NULL)
4851 {
4852 return error(GL_INVALID_OPERATION);
4853 }
John Bauman66b8ab22014-05-06 15:57:45 -04004854
Nicolas Capensf160b172014-11-26 11:58:23 -05004855 fenceObject->setFence(condition);
4856 }
John Bauman66b8ab22014-05-06 15:57:45 -04004857}
4858
Nicolas Capenseb195b62015-04-28 17:18:42 -07004859void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
John Bauman66b8ab22014-05-06 15:57:45 -04004860{
Nicolas Capensf160b172014-11-26 11:58:23 -05004861 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04004862
Nicolas Capensf160b172014-11-26 11:58:23 -05004863 if(width < 0 || height < 0)
4864 {
4865 return error(GL_INVALID_VALUE);
4866 }
John Bauman66b8ab22014-05-06 15:57:45 -04004867
Nicolas Capensf160b172014-11-26 11:58:23 -05004868 es2::Context* context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004869
Nicolas Capensf160b172014-11-26 11:58:23 -05004870 if(context)
4871 {
4872 context->setScissorParams(x, y, width, height);
4873 }
John Bauman66b8ab22014-05-06 15:57:45 -04004874}
4875
Nicolas Capenseb195b62015-04-28 17:18:42 -07004876void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
John Bauman66b8ab22014-05-06 15:57:45 -04004877{
Nicolas Capens4be33702015-04-28 15:13:30 -07004878 TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
4879 "const GLvoid* binary = %p, GLsizei length = %d)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004880 n, shaders, binaryformat, binary, length);
John Bauman66b8ab22014-05-06 15:57:45 -04004881
Nicolas Capensf160b172014-11-26 11:58:23 -05004882 // No binary shader formats are supported.
4883 return error(GL_INVALID_ENUM);
John Bauman66b8ab22014-05-06 15:57:45 -04004884}
4885
Nicolas Capenseb195b62015-04-28 17:18:42 -07004886void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
John Bauman66b8ab22014-05-06 15:57:45 -04004887{
Nicolas Capens4be33702015-04-28 15:13:30 -07004888 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05004889 shader, count, string, length);
John Bauman66b8ab22014-05-06 15:57:45 -04004890
Nicolas Capensf160b172014-11-26 11:58:23 -05004891 if(count < 0)
4892 {
4893 return error(GL_INVALID_VALUE);
4894 }
John Bauman66b8ab22014-05-06 15:57:45 -04004895
Nicolas Capensf160b172014-11-26 11:58:23 -05004896 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004897
Nicolas Capensf160b172014-11-26 11:58:23 -05004898 if(context)
4899 {
4900 es2::Shader *shaderObject = context->getShader(shader);
John Bauman66b8ab22014-05-06 15:57:45 -04004901
Nicolas Capensf160b172014-11-26 11:58:23 -05004902 if(!shaderObject)
4903 {
4904 if(context->getProgram(shader))
4905 {
4906 return error(GL_INVALID_OPERATION);
4907 }
4908 else
4909 {
4910 return error(GL_INVALID_VALUE);
4911 }
4912 }
John Bauman66b8ab22014-05-06 15:57:45 -04004913
Nicolas Capensf160b172014-11-26 11:58:23 -05004914 shaderObject->setSource(count, string, length);
4915 }
John Bauman66b8ab22014-05-06 15:57:45 -04004916}
4917
Nicolas Capenseb195b62015-04-28 17:18:42 -07004918void StencilFunc(GLenum func, GLint ref, GLuint mask)
John Bauman66b8ab22014-05-06 15:57:45 -04004919{
Nicolas Capensf160b172014-11-26 11:58:23 -05004920 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004921}
4922
Nicolas Capenseb195b62015-04-28 17:18:42 -07004923void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
John Bauman66b8ab22014-05-06 15:57:45 -04004924{
Nicolas Capensf160b172014-11-26 11:58:23 -05004925 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 -04004926
Nicolas Capensf160b172014-11-26 11:58:23 -05004927 switch(face)
4928 {
4929 case GL_FRONT:
4930 case GL_BACK:
4931 case GL_FRONT_AND_BACK:
4932 break;
4933 default:
4934 return error(GL_INVALID_ENUM);
4935 }
John Bauman66b8ab22014-05-06 15:57:45 -04004936
Nicolas Capensf160b172014-11-26 11:58:23 -05004937 switch(func)
4938 {
4939 case GL_NEVER:
4940 case GL_ALWAYS:
4941 case GL_LESS:
4942 case GL_LEQUAL:
4943 case GL_EQUAL:
4944 case GL_GEQUAL:
4945 case GL_GREATER:
4946 case GL_NOTEQUAL:
4947 break;
4948 default:
4949 return error(GL_INVALID_ENUM);
4950 }
John Bauman66b8ab22014-05-06 15:57:45 -04004951
Nicolas Capensf160b172014-11-26 11:58:23 -05004952 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004953
Nicolas Capensf160b172014-11-26 11:58:23 -05004954 if(context)
4955 {
4956 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4957 {
4958 context->setStencilParams(func, ref, mask);
4959 }
John Bauman66b8ab22014-05-06 15:57:45 -04004960
Nicolas Capensf160b172014-11-26 11:58:23 -05004961 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4962 {
4963 context->setStencilBackParams(func, ref, mask);
4964 }
4965 }
John Bauman66b8ab22014-05-06 15:57:45 -04004966}
4967
Nicolas Capenseb195b62015-04-28 17:18:42 -07004968void StencilMask(GLuint mask)
John Bauman66b8ab22014-05-06 15:57:45 -04004969{
Nicolas Capensf160b172014-11-26 11:58:23 -05004970 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004971}
4972
Nicolas Capenseb195b62015-04-28 17:18:42 -07004973void StencilMaskSeparate(GLenum face, GLuint mask)
John Bauman66b8ab22014-05-06 15:57:45 -04004974{
Nicolas Capensf160b172014-11-26 11:58:23 -05004975 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
John Bauman66b8ab22014-05-06 15:57:45 -04004976
Nicolas Capensf160b172014-11-26 11:58:23 -05004977 switch(face)
4978 {
4979 case GL_FRONT:
4980 case GL_BACK:
4981 case GL_FRONT_AND_BACK:
4982 break;
4983 default:
4984 return error(GL_INVALID_ENUM);
4985 }
John Bauman66b8ab22014-05-06 15:57:45 -04004986
Nicolas Capensf160b172014-11-26 11:58:23 -05004987 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04004988
Nicolas Capensf160b172014-11-26 11:58:23 -05004989 if(context)
4990 {
4991 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4992 {
4993 context->setStencilWritemask(mask);
4994 }
John Bauman66b8ab22014-05-06 15:57:45 -04004995
Nicolas Capensf160b172014-11-26 11:58:23 -05004996 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4997 {
4998 context->setStencilBackWritemask(mask);
4999 }
5000 }
John Bauman66b8ab22014-05-06 15:57:45 -04005001}
5002
Nicolas Capenseb195b62015-04-28 17:18:42 -07005003void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
John Bauman66b8ab22014-05-06 15:57:45 -04005004{
Nicolas Capensf160b172014-11-26 11:58:23 -05005005 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
John Bauman66b8ab22014-05-06 15:57:45 -04005006}
5007
Nicolas Capenseb195b62015-04-28 17:18:42 -07005008void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
John Bauman66b8ab22014-05-06 15:57:45 -04005009{
Nicolas Capensf160b172014-11-26 11:58:23 -05005010 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
5011 face, fail, zfail, zpass);
John Bauman66b8ab22014-05-06 15:57:45 -04005012
Nicolas Capensf160b172014-11-26 11:58:23 -05005013 switch(face)
5014 {
5015 case GL_FRONT:
5016 case GL_BACK:
5017 case GL_FRONT_AND_BACK:
5018 break;
5019 default:
5020 return error(GL_INVALID_ENUM);
5021 }
John Bauman66b8ab22014-05-06 15:57:45 -04005022
Nicolas Capensf160b172014-11-26 11:58:23 -05005023 switch(fail)
5024 {
5025 case GL_ZERO:
5026 case GL_KEEP:
5027 case GL_REPLACE:
5028 case GL_INCR:
5029 case GL_DECR:
5030 case GL_INVERT:
5031 case GL_INCR_WRAP:
5032 case GL_DECR_WRAP:
5033 break;
5034 default:
5035 return error(GL_INVALID_ENUM);
5036 }
John Bauman66b8ab22014-05-06 15:57:45 -04005037
Nicolas Capensf160b172014-11-26 11:58:23 -05005038 switch(zfail)
5039 {
5040 case GL_ZERO:
5041 case GL_KEEP:
5042 case GL_REPLACE:
5043 case GL_INCR:
5044 case GL_DECR:
5045 case GL_INVERT:
5046 case GL_INCR_WRAP:
5047 case GL_DECR_WRAP:
5048 break;
5049 default:
5050 return error(GL_INVALID_ENUM);
5051 }
John Bauman66b8ab22014-05-06 15:57:45 -04005052
Nicolas Capensf160b172014-11-26 11:58:23 -05005053 switch(zpass)
5054 {
5055 case GL_ZERO:
5056 case GL_KEEP:
5057 case GL_REPLACE:
5058 case GL_INCR:
5059 case GL_DECR:
5060 case GL_INVERT:
5061 case GL_INCR_WRAP:
5062 case GL_DECR_WRAP:
5063 break;
5064 default:
5065 return error(GL_INVALID_ENUM);
5066 }
John Bauman66b8ab22014-05-06 15:57:45 -04005067
Nicolas Capensf160b172014-11-26 11:58:23 -05005068 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005069
Nicolas Capensf160b172014-11-26 11:58:23 -05005070 if(context)
5071 {
5072 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
5073 {
5074 context->setStencilOperations(fail, zfail, zpass);
5075 }
John Bauman66b8ab22014-05-06 15:57:45 -04005076
Nicolas Capensf160b172014-11-26 11:58:23 -05005077 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
5078 {
5079 context->setStencilBackOperations(fail, zfail, zpass);
5080 }
5081 }
John Bauman66b8ab22014-05-06 15:57:45 -04005082}
5083
Nicolas Capenseb195b62015-04-28 17:18:42 -07005084GLboolean TestFenceNV(GLuint fence)
John Bauman66b8ab22014-05-06 15:57:45 -04005085{
Nicolas Capensf160b172014-11-26 11:58:23 -05005086 TRACE("(GLuint fence = %d)", fence);
John Bauman66b8ab22014-05-06 15:57:45 -04005087
Nicolas Capensf160b172014-11-26 11:58:23 -05005088 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005089
Nicolas Capensf160b172014-11-26 11:58:23 -05005090 if(context)
5091 {
5092 es2::Fence *fenceObject = context->getFence(fence);
John Bauman66b8ab22014-05-06 15:57:45 -04005093
Nicolas Capensf160b172014-11-26 11:58:23 -05005094 if(fenceObject == NULL)
5095 {
5096 return error(GL_INVALID_OPERATION, GL_TRUE);
5097 }
John Bauman66b8ab22014-05-06 15:57:45 -04005098
Nicolas Capensf160b172014-11-26 11:58:23 -05005099 return fenceObject->testFence();
5100 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05005101
Nicolas Capensf160b172014-11-26 11:58:23 -05005102 return GL_TRUE;
John Bauman66b8ab22014-05-06 15:57:45 -04005103}
5104
Nicolas Capenseb195b62015-04-28 17:18:42 -07005105void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
5106 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04005107{
Nicolas Capensf160b172014-11-26 11:58:23 -05005108 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07005109 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05005110 target, level, internalformat, width, height, border, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04005111
Nicolas Capensf160b172014-11-26 11:58:23 -05005112 if(!validImageSize(level, width, height))
5113 {
5114 return error(GL_INVALID_VALUE);
5115 }
John Bauman66b8ab22014-05-06 15:57:45 -04005116
Nicolas Capensf160b172014-11-26 11:58:23 -05005117 es2::Context *context = es2::getContext();
5118
5119 if(context)
5120 {
Alexis Hetu61161502015-05-21 11:45:03 -04005121 egl::GLint clientVersion = context->getClientVersion();
5122 if(clientVersion < 3)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005123 {
5124 if(internalformat != format)
5125 {
5126 return error(GL_INVALID_OPERATION);
5127 }
5128 }
5129
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04005130 GLenum validationError = ValidateCompressedFormat(format, clientVersion, false);
5131 if(validationError != GL_NONE)
Alexis Hetu460e41f2015-09-01 10:58:37 -04005132 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04005133 return error(validationError);
Alexis Hetu460e41f2015-09-01 10:58:37 -04005134 }
5135
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005136 switch(format)
5137 {
5138 case GL_ALPHA:
5139 case GL_LUMINANCE:
5140 case GL_LUMINANCE_ALPHA:
5141 switch(type)
5142 {
Alexis Hetu61161502015-05-21 11:45:03 -04005143 case GL_HALF_FLOAT:
5144 if(clientVersion < 3)
5145 {
5146 return error(GL_INVALID_ENUM);
5147 }
5148 break;
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005149 case GL_UNSIGNED_BYTE:
5150 case GL_FLOAT:
5151 case GL_HALF_FLOAT_OES:
5152 break;
5153 default:
5154 return error(GL_INVALID_ENUM);
5155 }
5156 break;
Alexis Hetued306182015-04-02 12:02:28 -04005157 case GL_RED:
5158 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005159 {
Alexis Hetued306182015-04-02 12:02:28 -04005160 case GL_R8:
5161 switch(type)
5162 {
5163 case GL_UNSIGNED_BYTE:
5164 break;
5165 default:
5166 return error(GL_INVALID_ENUM);
5167 }
5168 break;
5169 case GL_R8_SNORM:
5170 switch(type)
5171 {
5172 case GL_BYTE:
5173 break;
5174 default:
5175 return error(GL_INVALID_ENUM);
5176 }
5177 break;
5178 case GL_R16F:
5179 switch(type)
5180 {
Alexis Hetued306182015-04-02 12:02:28 -04005181 case GL_HALF_FLOAT:
Alexis Hetu61161502015-05-21 11:45:03 -04005182 if(clientVersion < 3)
5183 {
5184 return error(GL_INVALID_ENUM);
5185 }
5186 break;
5187 case GL_FLOAT:
5188 case GL_HALF_FLOAT_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005189 break;
5190 default:
5191 return error(GL_INVALID_ENUM);
5192 }
5193 break;
5194 case GL_R32F:
5195 switch(type)
5196 {
5197 case GL_FLOAT:
5198 break;
5199 default:
5200 return error(GL_INVALID_ENUM);
5201 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005202 break;
5203 default:
Alexis Hetued306182015-04-02 12:02:28 -04005204 return error(GL_INVALID_VALUE);
5205 }
5206 break;
5207 case GL_RED_INTEGER:
5208 switch(internalformat)
5209 {
5210 case GL_R8UI:
5211 switch(type)
5212 {
5213 case GL_UNSIGNED_BYTE:
5214 break;
5215 default:
5216 return error(GL_INVALID_ENUM);
5217 }
5218 break;
5219 case GL_R8I:
5220 switch(type)
5221 {
5222 case GL_BYTE:
5223 break;
5224 default:
5225 return error(GL_INVALID_ENUM);
5226 }
5227 break;
5228 case GL_R16UI:
5229 switch(type)
5230 {
5231 case GL_UNSIGNED_SHORT:
5232 break;
5233 default:
5234 return error(GL_INVALID_ENUM);
5235 }
5236 break;
5237 case GL_R16I:
5238 switch(type)
5239 {
5240 case GL_SHORT:
5241 break;
5242 default:
5243 return error(GL_INVALID_ENUM);
5244 }
5245 break;
5246 case GL_R32UI:
5247 switch(type)
5248 {
5249 case GL_UNSIGNED_INT:
5250 break;
5251 default:
5252 return error(GL_INVALID_ENUM);
5253 }
5254 break;
5255 case GL_R32I:
5256 switch(type)
5257 {
5258 case GL_INT:
5259 break;
5260 default:
5261 return error(GL_INVALID_ENUM);
5262 }
5263 break;
5264 default:
5265 return error(GL_INVALID_VALUE);
5266 }
5267 break;
5268 case GL_RG_INTEGER:
5269 switch(internalformat)
5270 {
5271 case GL_RG8UI:
5272 switch(type)
5273 {
5274 case GL_UNSIGNED_BYTE:
5275 break;
5276 default:
5277 return error(GL_INVALID_ENUM);
5278 }
5279 break;
5280 case GL_RG8I:
5281 switch(type)
5282 {
5283 case GL_BYTE:
5284 break;
5285 default:
5286 return error(GL_INVALID_ENUM);
5287 }
5288 break;
5289 case GL_RG16UI:
5290 switch(type)
5291 {
5292 case GL_UNSIGNED_SHORT:
5293 break;
5294 default:
5295 return error(GL_INVALID_ENUM);
5296 }
5297 break;
5298 case GL_RG16I:
5299 switch(type)
5300 {
5301 case GL_SHORT:
5302 break;
5303 default:
5304 return error(GL_INVALID_ENUM);
5305 }
5306 break;
5307 case GL_RG32UI:
5308 switch(type)
5309 {
5310 case GL_UNSIGNED_INT:
5311 break;
5312 default:
5313 return error(GL_INVALID_ENUM);
5314 }
5315 break;
5316 case GL_RG32I:
5317 switch(type)
5318 {
5319 case GL_INT:
5320 break;
5321 default:
5322 return error(GL_INVALID_ENUM);
5323 }
5324 break;
5325 default:
5326 return error(GL_INVALID_VALUE);
5327 }
5328 break;
5329 case GL_RGB_INTEGER:
5330 switch(internalformat)
5331 {
5332 case GL_RGB8UI:
5333 switch(type)
5334 {
5335 case GL_UNSIGNED_BYTE:
5336 break;
5337 default:
5338 return error(GL_INVALID_ENUM);
5339 }
5340 break;
5341 case GL_RGB8I:
5342 switch(type)
5343 {
5344 case GL_BYTE:
5345 break;
5346 default:
5347 return error(GL_INVALID_ENUM);
5348 }
5349 break;
5350 case GL_RGB16UI:
5351 switch(type)
5352 {
5353 case GL_UNSIGNED_SHORT:
5354 break;
5355 default:
5356 return error(GL_INVALID_ENUM);
5357 }
5358 break;
5359 case GL_RGB16I:
5360 switch(type)
5361 {
5362 case GL_SHORT:
5363 break;
5364 default:
5365 return error(GL_INVALID_ENUM);
5366 }
5367 break;
5368 case GL_RGB32UI:
5369 switch(type)
5370 {
5371 case GL_UNSIGNED_INT:
5372 break;
5373 default:
5374 return error(GL_INVALID_ENUM);
5375 }
5376 break;
5377 case GL_RGB32I:
5378 switch(type)
5379 {
5380 case GL_INT:
5381 break;
5382 default:
5383 return error(GL_INVALID_ENUM);
5384 }
5385 break;
5386 default:
5387 return error(GL_INVALID_VALUE);
5388 }
5389 break;
5390 case GL_RGBA_INTEGER:
5391 switch(internalformat)
5392 {
5393 case GL_RGBA8UI:
5394 switch(type)
5395 {
5396 case GL_UNSIGNED_BYTE:
5397 break;
5398 default:
5399 return error(GL_INVALID_ENUM);
5400 }
5401 break;
5402 case GL_RGBA8I:
5403 switch(type)
5404 {
5405 case GL_BYTE:
5406 break;
5407 default:
5408 return error(GL_INVALID_ENUM);
5409 }
5410 break;
5411 case GL_RGB10_A2UI:
5412 switch(type)
5413 {
5414 case GL_UNSIGNED_INT_2_10_10_10_REV:
5415 break;
5416 default:
5417 return error(GL_INVALID_ENUM);
5418 }
5419 break;
5420 case GL_RGBA16UI:
5421 switch(type)
5422 {
5423 case GL_UNSIGNED_SHORT:
5424 break;
5425 default:
5426 return error(GL_INVALID_ENUM);
5427 }
5428 break;
5429 case GL_RGBA16I:
5430 switch(type)
5431 {
5432 case GL_SHORT:
5433 break;
5434 default:
5435 return error(GL_INVALID_ENUM);
5436 }
5437 break;
5438 case GL_RGBA32UI:
5439 switch(type)
5440 {
Alexis Hetu8be7e3f2015-05-01 15:15:24 -04005441 case GL_UNSIGNED_INT:
Alexis Hetued306182015-04-02 12:02:28 -04005442 break;
5443 default:
5444 return error(GL_INVALID_ENUM);
5445 }
5446 break;
5447 case GL_RGBA32I:
5448 switch(type)
5449 {
Alexis Hetu8be7e3f2015-05-01 15:15:24 -04005450 case GL_INT:
Alexis Hetued306182015-04-02 12:02:28 -04005451 break;
5452 default:
5453 return error(GL_INVALID_ENUM);
5454 }
5455 break;
5456 default:
5457 return error(GL_INVALID_VALUE);
5458 }
5459 break;
5460 case GL_RG:
5461 switch(internalformat)
5462 {
5463 case GL_RG8:
5464 switch(type)
5465 {
5466 case GL_UNSIGNED_BYTE:
5467 break;
5468 default:
5469 return error(GL_INVALID_ENUM);
5470 }
5471 break;
5472 case GL_RG8_SNORM:
5473 switch(type)
5474 {
5475 case GL_BYTE:
5476 break;
5477 default:
5478 return error(GL_INVALID_ENUM);
5479 }
5480 break;
5481 case GL_RG16F:
5482 switch(type)
5483 {
Alexis Hetued306182015-04-02 12:02:28 -04005484 case GL_HALF_FLOAT:
Alexis Hetu61161502015-05-21 11:45:03 -04005485 if(clientVersion < 3)
5486 {
5487 return error(GL_INVALID_ENUM);
5488 }
5489 break;
5490 case GL_FLOAT:
5491 case GL_HALF_FLOAT_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005492 break;
5493 default:
5494 return error(GL_INVALID_ENUM);
5495 }
5496 break;
5497 case GL_RG32F:
5498 switch(type)
5499 {
5500 case GL_FLOAT:
5501 break;
5502 default:
5503 return error(GL_INVALID_ENUM);
5504 }
5505 break;
5506 default:
5507 return error(GL_INVALID_VALUE);
5508 }
5509 break;
5510 case GL_RGB:
5511 switch(internalformat)
5512 {
5513 case GL_RGB:
5514 switch(type)
5515 {
Alexis Hetu61161502015-05-21 11:45:03 -04005516 case GL_HALF_FLOAT:
5517 if(clientVersion < 3)
5518 {
5519 return error(GL_INVALID_ENUM);
5520 }
5521 break;
Alexis Hetued306182015-04-02 12:02:28 -04005522 case GL_UNSIGNED_BYTE:
5523 case GL_UNSIGNED_SHORT_5_6_5:
5524 case GL_FLOAT:
5525 case GL_HALF_FLOAT_OES:
5526 break;
5527 default:
5528 return error(GL_INVALID_ENUM);
5529 }
5530 break;
5531 case GL_RGB8:
5532 switch(type)
5533 {
5534 case GL_UNSIGNED_BYTE:
5535 break;
5536 default:
5537 return error(GL_INVALID_ENUM);
5538 }
5539 break;
5540 case GL_SRGB8:
5541 switch(type)
5542 {
5543 case GL_UNSIGNED_BYTE:
5544 break;
5545 default:
5546 return error(GL_INVALID_ENUM);
5547 }
5548 break;
5549 case GL_RGB565:
5550 switch(type)
5551 {
5552 case GL_UNSIGNED_BYTE:
5553 case GL_UNSIGNED_SHORT_5_6_5:
5554 break;
5555 default:
5556 return error(GL_INVALID_ENUM);
5557 }
5558 break;
5559 case GL_RGB8_SNORM:
5560 switch(type)
5561 {
5562 case GL_BYTE:
5563 break;
5564 default:
5565 return error(GL_INVALID_ENUM);
5566 }
5567 break;
5568 case GL_R11F_G11F_B10F:
5569 switch(type)
5570 {
Alexis Hetu61161502015-05-21 11:45:03 -04005571 case GL_HALF_FLOAT:
5572 if(clientVersion < 3)
5573 {
5574 return error(GL_INVALID_ENUM);
5575 }
5576 break;
Alexis Hetued306182015-04-02 12:02:28 -04005577 case GL_UNSIGNED_INT_10F_11F_11F_REV:
5578 case GL_FLOAT:
Alexis Hetu61161502015-05-21 11:45:03 -04005579 case GL_HALF_FLOAT_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005580 break;
5581 default:
5582 return error(GL_INVALID_ENUM);
5583 }
5584 break;
5585 case GL_RGB9_E5:
5586 switch(type)
5587 {
Alexis Hetu61161502015-05-21 11:45:03 -04005588 case GL_HALF_FLOAT:
5589 if(clientVersion < 3)
5590 {
5591 return error(GL_INVALID_ENUM);
5592 }
5593 break;
Alexis Hetued306182015-04-02 12:02:28 -04005594 case GL_UNSIGNED_INT_5_9_9_9_REV:
5595 case GL_FLOAT:
Alexis Hetu61161502015-05-21 11:45:03 -04005596 case GL_HALF_FLOAT_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005597 break;
5598 default:
5599 return error(GL_INVALID_ENUM);
5600 }
5601 break;
5602 case GL_RGB16F:
5603 switch(type)
5604 {
Alexis Hetued306182015-04-02 12:02:28 -04005605 case GL_HALF_FLOAT:
Alexis Hetu61161502015-05-21 11:45:03 -04005606 if(clientVersion < 3)
5607 {
5608 return error(GL_INVALID_ENUM);
5609 }
5610 break;
5611 case GL_FLOAT:
5612 case GL_HALF_FLOAT_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005613 break;
5614 default:
5615 return error(GL_INVALID_ENUM);
5616 }
5617 break;
5618 case GL_RGB32F:
5619 switch(type)
5620 {
5621 case GL_FLOAT:
5622 break;
5623 default:
5624 return error(GL_INVALID_ENUM);
5625 }
5626 break;
5627 default:
5628 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005629 }
5630 break;
5631 case GL_RGBA:
Alexis Hetued306182015-04-02 12:02:28 -04005632 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005633 {
Alexis Hetued306182015-04-02 12:02:28 -04005634 case GL_RGBA:
5635 switch(type)
5636 {
Alexis Hetu61161502015-05-21 11:45:03 -04005637 case GL_HALF_FLOAT:
5638 if(clientVersion < 3)
5639 {
5640 return error(GL_INVALID_ENUM);
5641 }
5642 break;
Alexis Hetued306182015-04-02 12:02:28 -04005643 case GL_UNSIGNED_BYTE:
5644 case GL_UNSIGNED_SHORT_4_4_4_4:
5645 case GL_UNSIGNED_SHORT_5_5_5_1:
5646 case GL_FLOAT:
5647 case GL_HALF_FLOAT_OES:
5648 break;
5649 default:
5650 return error(GL_INVALID_ENUM);
5651 }
5652 break;
5653 case GL_RGBA8:
5654 switch(type)
5655 {
5656 case GL_UNSIGNED_BYTE:
5657 break;
5658 default:
5659 return error(GL_INVALID_ENUM);
5660 }
5661 break;
5662 case GL_SRGB8_ALPHA8:
5663 switch(type)
5664 {
5665 case GL_UNSIGNED_BYTE:
5666 break;
5667 default:
5668 return error(GL_INVALID_ENUM);
5669 }
5670 break;
5671 case GL_RGB5_A1:
5672 switch(type)
5673 {
5674 case GL_UNSIGNED_BYTE:
5675 case GL_UNSIGNED_SHORT_5_5_5_1:
5676 case GL_UNSIGNED_INT_2_10_10_10_REV:
5677 break;
5678 default:
5679 return error(GL_INVALID_ENUM);
5680 }
5681 break;
5682 case GL_RGBA8_SNORM:
5683 switch(type)
5684 {
5685 case GL_BYTE:
5686 break;
5687 default:
5688 return error(GL_INVALID_ENUM);
5689 }
5690 break;
5691 case GL_RGBA4:
5692 switch(type)
5693 {
5694 case GL_UNSIGNED_BYTE:
5695 case GL_UNSIGNED_SHORT_4_4_4_4:
5696 break;
5697 default:
5698 return error(GL_INVALID_ENUM);
5699 }
5700 break;
5701 case GL_RGB10_A2:
5702 switch(type)
5703 {
5704 case GL_UNSIGNED_INT_2_10_10_10_REV:
5705 break;
5706 default:
5707 return error(GL_INVALID_ENUM);
5708 }
5709 break;
5710 case GL_RGBA16F:
5711 switch(type)
5712 {
Alexis Hetued306182015-04-02 12:02:28 -04005713 case GL_HALF_FLOAT:
Alexis Hetu61161502015-05-21 11:45:03 -04005714 if(clientVersion < 3)
5715 {
5716 return error(GL_INVALID_ENUM);
5717 }
5718 break;
5719 case GL_FLOAT:
5720 case GL_HALF_FLOAT_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005721 break;
5722 default:
5723 return error(GL_INVALID_ENUM);
5724 }
5725 break;
5726 case GL_RGBA32F:
5727 switch(type)
5728 {
5729 case GL_FLOAT:
5730 break;
5731 default:
5732 return error(GL_INVALID_ENUM);
5733 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005734 break;
5735 default:
Alexis Hetued306182015-04-02 12:02:28 -04005736 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005737 }
5738 break;
5739 case GL_BGRA_EXT:
5740 switch(type)
5741 {
5742 case GL_UNSIGNED_BYTE:
5743 break;
5744 default:
5745 return error(GL_INVALID_ENUM);
5746 }
5747 break;
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005748 case GL_DEPTH_COMPONENT:
Alexis Hetued306182015-04-02 12:02:28 -04005749 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005750 {
Alexis Hetued306182015-04-02 12:02:28 -04005751 case GL_DEPTH_COMPONENT:
5752 case GL_DEPTH_COMPONENT16:
5753 switch(type)
5754 {
5755 case GL_UNSIGNED_SHORT:
5756 case GL_UNSIGNED_INT:
5757 break;
5758 default:
5759 return error(GL_INVALID_ENUM);
5760 }
5761 break;
5762 case GL_DEPTH_COMPONENT24:
Alexis Hetue7277752015-12-04 11:16:35 -05005763 case GL_DEPTH_COMPONENT32_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005764 switch(type)
5765 {
5766 case GL_UNSIGNED_INT:
5767 break;
5768 default:
5769 return error(GL_INVALID_ENUM);
5770 }
5771 break;
5772 case GL_DEPTH_COMPONENT32F:
5773 switch(type)
5774 {
Alexis Hetue4795222015-09-18 11:44:23 -04005775 case GL_FLOAT:
Alexis Hetued306182015-04-02 12:02:28 -04005776 break;
5777 default:
5778 return error(GL_INVALID_ENUM);
5779 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005780 break;
5781 default:
Alexis Hetued306182015-04-02 12:02:28 -04005782 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005783 }
5784 break;
5785 case GL_DEPTH_STENCIL_OES:
Alexis Hetued306182015-04-02 12:02:28 -04005786 switch(internalformat)
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005787 {
Alexis Hetued306182015-04-02 12:02:28 -04005788 case GL_DEPTH_STENCIL_OES:
5789 case GL_DEPTH24_STENCIL8:
5790 switch(type)
5791 {
5792 case GL_UNSIGNED_INT_24_8_OES:
5793 break;
5794 default:
5795 return error(GL_INVALID_ENUM);
5796 }
5797 break;
5798 case GL_DEPTH32F_STENCIL8:
5799 switch(type)
5800 {
5801 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
5802 break;
5803 default:
5804 return error(GL_INVALID_ENUM);
5805 }
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005806 break;
5807 default:
Alexis Hetued306182015-04-02 12:02:28 -04005808 return error(GL_INVALID_VALUE);
Nicolas Capensb97ad2e2015-02-11 17:40:30 -05005809 }
5810 break;
5811 default:
5812 return error(GL_INVALID_VALUE);
5813 }
5814
5815 if(border != 0)
5816 {
5817 return error(GL_INVALID_VALUE);
5818 }
5819
Nicolas Capensf160b172014-11-26 11:58:23 -05005820 switch(target)
5821 {
Nicolas Capens22658242014-11-29 00:31:41 -05005822 case GL_TEXTURE_2D:
Nicolas Capensf160b172014-11-26 11:58:23 -05005823 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
5824 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
John Bauman66b8ab22014-05-06 15:57:45 -04005825 {
Nicolas Capensf160b172014-11-26 11:58:23 -05005826 return error(GL_INVALID_VALUE);
John Bauman66b8ab22014-05-06 15:57:45 -04005827 }
5828 break;
Nicolas Capens22658242014-11-29 00:31:41 -05005829 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5830 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5831 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5832 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5833 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5834 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
Nicolas Capensf160b172014-11-26 11:58:23 -05005835 if(width != height)
John Bauman66b8ab22014-05-06 15:57:45 -04005836 {
Nicolas Capensf160b172014-11-26 11:58:23 -05005837 return error(GL_INVALID_VALUE);
5838 }
5839
5840 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
5841 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
5842 {
5843 return error(GL_INVALID_VALUE);
John Bauman66b8ab22014-05-06 15:57:45 -04005844 }
5845 break;
Nicolas Capens22658242014-11-29 00:31:41 -05005846 default:
Nicolas Capensf160b172014-11-26 11:58:23 -05005847 return error(GL_INVALID_ENUM);
5848 }
John Bauman66b8ab22014-05-06 15:57:45 -04005849
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04005850 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
5851
Nicolas Capensf160b172014-11-26 11:58:23 -05005852 if(target == GL_TEXTURE_2D)
5853 {
5854 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04005855
Nicolas Capensf160b172014-11-26 11:58:23 -05005856 if(!texture)
5857 {
5858 return error(GL_INVALID_OPERATION);
5859 }
John Bauman66b8ab22014-05-06 15:57:45 -04005860
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04005861 texture->setImage(level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
Nicolas Capensf160b172014-11-26 11:58:23 -05005862 }
5863 else
5864 {
5865 es2::TextureCubeMap *texture = context->getTextureCubeMap();
John Bauman66b8ab22014-05-06 15:57:45 -04005866
Nicolas Capensf160b172014-11-26 11:58:23 -05005867 if(!texture)
5868 {
5869 return error(GL_INVALID_OPERATION);
5870 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05005871
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04005872 texture->setImage(target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
Nicolas Capensf160b172014-11-26 11:58:23 -05005873 }
5874 }
John Bauman66b8ab22014-05-06 15:57:45 -04005875}
5876
Nicolas Capenseb195b62015-04-28 17:18:42 -07005877void TexParameterf(GLenum target, GLenum pname, GLfloat param)
John Bauman66b8ab22014-05-06 15:57:45 -04005878{
Nicolas Capensf160b172014-11-26 11:58:23 -05005879 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04005880
Nicolas Capensf160b172014-11-26 11:58:23 -05005881 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04005882
Nicolas Capensf160b172014-11-26 11:58:23 -05005883 if(context)
5884 {
5885 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04005886
Alexis Hetued306182015-04-02 12:02:28 -04005887 egl::GLint clientVersion = context->getClientVersion();
5888
Nicolas Capensf160b172014-11-26 11:58:23 -05005889 switch(target)
5890 {
5891 case GL_TEXTURE_2D:
5892 texture = context->getTexture2D();
5893 break;
Alexis Hetued306182015-04-02 12:02:28 -04005894 case GL_TEXTURE_2D_ARRAY:
5895 if(clientVersion < 3)
5896 {
5897 return error(GL_INVALID_ENUM);
5898 }
5899 else
5900 {
Alexis Hetuf15e8942015-12-01 15:13:23 -05005901 texture = context->getTexture2DArray();
Alexis Hetued306182015-04-02 12:02:28 -04005902 }
Alexis Hetuf15e8942015-12-01 15:13:23 -05005903 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05005904 case GL_TEXTURE_3D_OES:
5905 texture = context->getTexture3D();
5906 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005907 case GL_TEXTURE_CUBE_MAP:
5908 texture = context->getTextureCubeMap();
5909 break;
5910 case GL_TEXTURE_EXTERNAL_OES:
5911 texture = context->getTextureExternal();
5912 break;
5913 default:
5914 return error(GL_INVALID_ENUM);
5915 }
John Bauman66b8ab22014-05-06 15:57:45 -04005916
Nicolas Capensf160b172014-11-26 11:58:23 -05005917 switch(pname)
5918 {
5919 case GL_TEXTURE_WRAP_S:
5920 if(!texture->setWrapS((GLenum)param))
5921 {
5922 return error(GL_INVALID_ENUM);
5923 }
5924 break;
5925 case GL_TEXTURE_WRAP_T:
5926 if(!texture->setWrapT((GLenum)param))
5927 {
5928 return error(GL_INVALID_ENUM);
5929 }
5930 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05005931 case GL_TEXTURE_WRAP_R_OES:
5932 if(!texture->setWrapR((GLenum)param))
5933 {
5934 return error(GL_INVALID_ENUM);
5935 }
5936 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05005937 case GL_TEXTURE_MIN_FILTER:
5938 if(!texture->setMinFilter((GLenum)param))
5939 {
5940 return error(GL_INVALID_ENUM);
5941 }
5942 break;
5943 case GL_TEXTURE_MAG_FILTER:
5944 if(!texture->setMagFilter((GLenum)param))
5945 {
5946 return error(GL_INVALID_ENUM);
5947 }
5948 break;
5949 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5950 if(!texture->setMaxAnisotropy(param))
5951 {
5952 return error(GL_INVALID_VALUE);
5953 }
5954 break;
Alexis Hetued306182015-04-02 12:02:28 -04005955 case GL_TEXTURE_BASE_LEVEL:
Alexis Hetu3ed16302015-09-10 16:57:44 -04005956 if(clientVersion < 3 || !texture->setBaseLevel((GLint)(roundf(param))))
Alexis Hetued306182015-04-02 12:02:28 -04005957 {
5958 return error(GL_INVALID_VALUE);
5959 }
5960 break;
5961 case GL_TEXTURE_COMPARE_FUNC:
5962 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5963 {
5964 return error(GL_INVALID_VALUE);
5965 }
5966 break;
5967 case GL_TEXTURE_COMPARE_MODE:
5968 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5969 {
5970 return error(GL_INVALID_VALUE);
5971 }
5972 break;
5973 case GL_TEXTURE_IMMUTABLE_FORMAT:
Alexis Hetu8e098372015-09-28 10:59:11 -04005974 if(clientVersion < 3 || !texture->setImmutableFormat((GLboolean)param))
Alexis Hetued306182015-04-02 12:02:28 -04005975 {
5976 return error(GL_INVALID_VALUE);
5977 }
5978 break;
5979 case GL_TEXTURE_MAX_LEVEL:
Alexis Hetu3ed16302015-09-10 16:57:44 -04005980 if(clientVersion < 3 || !texture->setMaxLevel((GLint)(roundf(param))))
Alexis Hetued306182015-04-02 12:02:28 -04005981 {
5982 return error(GL_INVALID_VALUE);
5983 }
5984 break;
5985 case GL_TEXTURE_MAX_LOD:
5986 if(clientVersion < 3 || !texture->setMaxLOD(param))
5987 {
5988 return error(GL_INVALID_VALUE);
5989 }
5990 break;
5991 case GL_TEXTURE_MIN_LOD:
5992 if(clientVersion < 3 || !texture->setMinLOD(param))
5993 {
5994 return error(GL_INVALID_VALUE);
5995 }
5996 break;
5997 case GL_TEXTURE_SWIZZLE_R:
5998 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5999 {
6000 return error(GL_INVALID_VALUE);
6001 }
6002 break;
6003 case GL_TEXTURE_SWIZZLE_G:
6004 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
6005 {
6006 return error(GL_INVALID_VALUE);
6007 }
6008 break;
6009 case GL_TEXTURE_SWIZZLE_B:
6010 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
6011 {
6012 return error(GL_INVALID_VALUE);
6013 }
6014 break;
6015 case GL_TEXTURE_SWIZZLE_A:
6016 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
6017 {
6018 return error(GL_INVALID_VALUE);
6019 }
6020 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05006021 default:
6022 return error(GL_INVALID_ENUM);
6023 }
6024 }
John Bauman66b8ab22014-05-06 15:57:45 -04006025}
6026
Nicolas Capenseb195b62015-04-28 17:18:42 -07006027void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
John Bauman66b8ab22014-05-06 15:57:45 -04006028{
Nicolas Capensf160b172014-11-26 11:58:23 -05006029 glTexParameterf(target, pname, *params);
John Bauman66b8ab22014-05-06 15:57:45 -04006030}
6031
Nicolas Capenseb195b62015-04-28 17:18:42 -07006032void TexParameteri(GLenum target, GLenum pname, GLint param)
John Bauman66b8ab22014-05-06 15:57:45 -04006033{
Nicolas Capensf160b172014-11-26 11:58:23 -05006034 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
John Bauman66b8ab22014-05-06 15:57:45 -04006035
Nicolas Capensf160b172014-11-26 11:58:23 -05006036 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006037
Nicolas Capensf160b172014-11-26 11:58:23 -05006038 if(context)
6039 {
6040 es2::Texture *texture;
John Bauman66b8ab22014-05-06 15:57:45 -04006041
Alexis Hetued306182015-04-02 12:02:28 -04006042 egl::GLint clientVersion = context->getClientVersion();
6043
Nicolas Capensf160b172014-11-26 11:58:23 -05006044 switch(target)
6045 {
6046 case GL_TEXTURE_2D:
6047 texture = context->getTexture2D();
6048 break;
Alexis Hetued306182015-04-02 12:02:28 -04006049 case GL_TEXTURE_2D_ARRAY:
6050 if(clientVersion < 3)
6051 {
6052 return error(GL_INVALID_ENUM);
6053 }
6054 else
6055 {
Alexis Hetuf15e8942015-12-01 15:13:23 -05006056 texture = context->getTexture2DArray();
Alexis Hetued306182015-04-02 12:02:28 -04006057 }
Alexis Hetuf15e8942015-12-01 15:13:23 -05006058 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05006059 case GL_TEXTURE_3D_OES:
6060 texture = context->getTexture3D();
6061 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05006062 case GL_TEXTURE_CUBE_MAP:
6063 texture = context->getTextureCubeMap();
6064 break;
6065 case GL_TEXTURE_EXTERNAL_OES:
Alexis Hetuf7be67f2015-02-11 16:11:07 -05006066 texture = context->getTextureExternal();
6067 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05006068 default:
6069 return error(GL_INVALID_ENUM);
6070 }
John Bauman66b8ab22014-05-06 15:57:45 -04006071
Nicolas Capensf160b172014-11-26 11:58:23 -05006072 switch(pname)
6073 {
6074 case GL_TEXTURE_WRAP_S:
6075 if(!texture->setWrapS((GLenum)param))
6076 {
6077 return error(GL_INVALID_ENUM);
6078 }
6079 break;
6080 case GL_TEXTURE_WRAP_T:
6081 if(!texture->setWrapT((GLenum)param))
6082 {
6083 return error(GL_INVALID_ENUM);
6084 }
6085 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05006086 case GL_TEXTURE_WRAP_R_OES:
6087 if(!texture->setWrapR((GLenum)param))
6088 {
6089 return error(GL_INVALID_ENUM);
6090 }
6091 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05006092 case GL_TEXTURE_MIN_FILTER:
6093 if(!texture->setMinFilter((GLenum)param))
6094 {
6095 return error(GL_INVALID_ENUM);
6096 }
6097 break;
6098 case GL_TEXTURE_MAG_FILTER:
6099 if(!texture->setMagFilter((GLenum)param))
6100 {
6101 return error(GL_INVALID_ENUM);
6102 }
6103 break;
6104 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6105 if(!texture->setMaxAnisotropy((GLfloat)param))
6106 {
6107 return error(GL_INVALID_VALUE);
6108 }
6109 break;
Alexis Hetued306182015-04-02 12:02:28 -04006110 case GL_TEXTURE_BASE_LEVEL:
6111 if(clientVersion < 3 || !texture->setBaseLevel(param))
6112 {
6113 return error(GL_INVALID_VALUE);
6114 }
6115 break;
6116 case GL_TEXTURE_COMPARE_FUNC:
6117 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
6118 {
6119 return error(GL_INVALID_VALUE);
6120 }
6121 break;
6122 case GL_TEXTURE_COMPARE_MODE:
6123 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
6124 {
6125 return error(GL_INVALID_VALUE);
6126 }
Alexis Hetu8e098372015-09-28 10:59:11 -04006127 break;
Alexis Hetued306182015-04-02 12:02:28 -04006128 case GL_TEXTURE_IMMUTABLE_FORMAT:
Alexis Hetu8e098372015-09-28 10:59:11 -04006129 if(clientVersion < 3 || !texture->setImmutableFormat((GLboolean)param))
Alexis Hetued306182015-04-02 12:02:28 -04006130 {
6131 return error(GL_INVALID_VALUE);
6132 }
6133 break;
6134 case GL_TEXTURE_MAX_LEVEL:
6135 if(clientVersion < 3 || !texture->setMaxLevel(param))
6136 {
6137 return error(GL_INVALID_VALUE);
6138 }
6139 break;
6140 case GL_TEXTURE_MAX_LOD:
6141 if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
6142 {
6143 return error(GL_INVALID_VALUE);
6144 }
6145 break;
6146 case GL_TEXTURE_MIN_LOD:
6147 if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
6148 {
6149 return error(GL_INVALID_VALUE);
6150 }
6151 break;
6152 case GL_TEXTURE_SWIZZLE_R:
6153 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
6154 {
6155 return error(GL_INVALID_VALUE);
6156 }
6157 break;
6158 case GL_TEXTURE_SWIZZLE_G:
6159 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
6160 {
6161 return error(GL_INVALID_VALUE);
6162 }
6163 break;
6164 case GL_TEXTURE_SWIZZLE_B:
6165 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
6166 {
6167 return error(GL_INVALID_VALUE);
6168 }
6169 break;
6170 case GL_TEXTURE_SWIZZLE_A:
6171 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
6172 {
6173 return error(GL_INVALID_VALUE);
6174 }
6175 break;
Nicolas Capensf160b172014-11-26 11:58:23 -05006176 default:
6177 return error(GL_INVALID_ENUM);
6178 }
6179 }
John Bauman66b8ab22014-05-06 15:57:45 -04006180}
6181
Nicolas Capenseb195b62015-04-28 17:18:42 -07006182void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
John Bauman66b8ab22014-05-06 15:57:45 -04006183{
Nicolas Capensf160b172014-11-26 11:58:23 -05006184 glTexParameteri(target, pname, *params);
John Bauman66b8ab22014-05-06 15:57:45 -04006185}
6186
Nicolas Capenseb195b62015-04-28 17:18:42 -07006187void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
6188 GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04006189{
Nicolas Capensf160b172014-11-26 11:58:23 -05006190 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6191 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07006192 "const GLvoid* pixels = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006193 target, level, xoffset, yoffset, width, height, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04006194
Nicolas Capensf160b172014-11-26 11:58:23 -05006195 if(!es2::IsTextureTarget(target))
6196 {
6197 return error(GL_INVALID_ENUM);
6198 }
John Bauman66b8ab22014-05-06 15:57:45 -04006199
Nicolas Capensf160b172014-11-26 11:58:23 -05006200 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
6201 {
6202 return error(GL_INVALID_VALUE);
6203 }
John Bauman66b8ab22014-05-06 15:57:45 -04006204
Nicolas Capensf160b172014-11-26 11:58:23 -05006205 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
6206 {
6207 return error(GL_INVALID_VALUE);
6208 }
John Bauman66b8ab22014-05-06 15:57:45 -04006209
Alexis Hetu61161502015-05-21 11:45:03 -04006210 if(!es2::CheckTextureFormatType(format, type, egl::getClientVersion()))
Nicolas Capensf160b172014-11-26 11:58:23 -05006211 {
6212 return error(GL_INVALID_ENUM);
6213 }
John Bauman66b8ab22014-05-06 15:57:45 -04006214
Nicolas Capensf160b172014-11-26 11:58:23 -05006215 if(width == 0 || height == 0 || pixels == NULL)
6216 {
6217 return;
6218 }
John Bauman66b8ab22014-05-06 15:57:45 -04006219
Nicolas Capensf160b172014-11-26 11:58:23 -05006220 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006221
Nicolas Capensf160b172014-11-26 11:58:23 -05006222 if(context)
6223 {
Alexis Hetub027aa92015-01-19 15:56:12 -05006224 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capensf160b172014-11-26 11:58:23 -05006225 {
6226 return error(GL_INVALID_VALUE);
6227 }
John Bauman66b8ab22014-05-06 15:57:45 -04006228
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04006229 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
6230
Nicolas Capensf160b172014-11-26 11:58:23 -05006231 if(target == GL_TEXTURE_2D)
6232 {
6233 es2::Texture2D *texture = context->getTexture2D();
John Bauman66b8ab22014-05-06 15:57:45 -04006234
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04006235 GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
6236
6237 if(validationError == GL_NONE)
Nicolas Capensf160b172014-11-26 11:58:23 -05006238 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04006239 texture->subImage(level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
6240 }
6241 else
6242 {
6243 return error(validationError);
Nicolas Capensf160b172014-11-26 11:58:23 -05006244 }
6245 }
6246 else if(es2::IsCubemapTextureTarget(target))
6247 {
6248 es2::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens08e90f02014-11-21 12:49:12 -05006249
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04006250 GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
6251
6252 if(validationError == GL_NONE)
Nicolas Capensf160b172014-11-26 11:58:23 -05006253 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04006254 texture->subImage(target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
6255 }
6256 else
6257 {
6258 return error(validationError);
Nicolas Capensf160b172014-11-26 11:58:23 -05006259 }
6260 }
Nicolas Capens3713cd42015-06-22 10:41:54 -04006261 else UNREACHABLE(target);
Nicolas Capensf160b172014-11-26 11:58:23 -05006262 }
John Bauman66b8ab22014-05-06 15:57:45 -04006263}
6264
Nicolas Capenseb195b62015-04-28 17:18:42 -07006265void Uniform1f(GLint location, GLfloat x)
John Bauman66b8ab22014-05-06 15:57:45 -04006266{
Nicolas Capensf160b172014-11-26 11:58:23 -05006267 glUniform1fv(location, 1, &x);
John Bauman66b8ab22014-05-06 15:57:45 -04006268}
6269
Nicolas Capenseb195b62015-04-28 17:18:42 -07006270void Uniform1fv(GLint location, GLsizei count, const GLfloat* v)
John Bauman66b8ab22014-05-06 15:57:45 -04006271{
Nicolas Capens4be33702015-04-28 15:13:30 -07006272 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006273
Nicolas Capensf160b172014-11-26 11:58:23 -05006274 if(count < 0)
6275 {
6276 return error(GL_INVALID_VALUE);
6277 }
John Bauman66b8ab22014-05-06 15:57:45 -04006278
Nicolas Capensf160b172014-11-26 11:58:23 -05006279 if(location == -1)
6280 {
6281 return;
6282 }
John Bauman66b8ab22014-05-06 15:57:45 -04006283
Nicolas Capensf160b172014-11-26 11:58:23 -05006284 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006285
Nicolas Capensf160b172014-11-26 11:58:23 -05006286 if(context)
6287 {
6288 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006289
Nicolas Capensf160b172014-11-26 11:58:23 -05006290 if(!program)
6291 {
6292 return error(GL_INVALID_OPERATION);
6293 }
John Bauman66b8ab22014-05-06 15:57:45 -04006294
Nicolas Capensf160b172014-11-26 11:58:23 -05006295 if(!program->setUniform1fv(location, count, v))
6296 {
6297 return error(GL_INVALID_OPERATION);
6298 }
6299 }
John Bauman66b8ab22014-05-06 15:57:45 -04006300}
6301
Nicolas Capenseb195b62015-04-28 17:18:42 -07006302void Uniform1i(GLint location, GLint x)
John Bauman66b8ab22014-05-06 15:57:45 -04006303{
Nicolas Capensf160b172014-11-26 11:58:23 -05006304 glUniform1iv(location, 1, &x);
John Bauman66b8ab22014-05-06 15:57:45 -04006305}
6306
Nicolas Capenseb195b62015-04-28 17:18:42 -07006307void Uniform1iv(GLint location, GLsizei count, const GLint* v)
John Bauman66b8ab22014-05-06 15:57:45 -04006308{
Nicolas Capens4be33702015-04-28 15:13:30 -07006309 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006310
Nicolas Capensf160b172014-11-26 11:58:23 -05006311 if(count < 0)
6312 {
6313 return error(GL_INVALID_VALUE);
6314 }
John Bauman66b8ab22014-05-06 15:57:45 -04006315
Nicolas Capensf160b172014-11-26 11:58:23 -05006316 if(location == -1)
6317 {
6318 return;
6319 }
John Bauman66b8ab22014-05-06 15:57:45 -04006320
Nicolas Capensf160b172014-11-26 11:58:23 -05006321 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006322
Nicolas Capensf160b172014-11-26 11:58:23 -05006323 if(context)
6324 {
6325 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006326
Nicolas Capensf160b172014-11-26 11:58:23 -05006327 if(!program)
6328 {
6329 return error(GL_INVALID_OPERATION);
6330 }
John Bauman66b8ab22014-05-06 15:57:45 -04006331
Nicolas Capensf160b172014-11-26 11:58:23 -05006332 if(!program->setUniform1iv(location, count, v))
6333 {
6334 return error(GL_INVALID_OPERATION);
6335 }
6336 }
John Bauman66b8ab22014-05-06 15:57:45 -04006337}
6338
Nicolas Capenseb195b62015-04-28 17:18:42 -07006339void Uniform2f(GLint location, GLfloat x, GLfloat y)
John Bauman66b8ab22014-05-06 15:57:45 -04006340{
Nicolas Capensf160b172014-11-26 11:58:23 -05006341 GLfloat xy[2] = {x, y};
John Bauman66b8ab22014-05-06 15:57:45 -04006342
Nicolas Capensf160b172014-11-26 11:58:23 -05006343 glUniform2fv(location, 1, (GLfloat*)&xy);
John Bauman66b8ab22014-05-06 15:57:45 -04006344}
6345
Nicolas Capenseb195b62015-04-28 17:18:42 -07006346void Uniform2fv(GLint location, GLsizei count, const GLfloat* v)
John Bauman66b8ab22014-05-06 15:57:45 -04006347{
Nicolas Capens4be33702015-04-28 15:13:30 -07006348 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006349
Nicolas Capensf160b172014-11-26 11:58:23 -05006350 if(count < 0)
6351 {
6352 return error(GL_INVALID_VALUE);
6353 }
Nicolas Capens08e90f02014-11-21 12:49:12 -05006354
Nicolas Capensf160b172014-11-26 11:58:23 -05006355 if(location == -1)
6356 {
6357 return;
6358 }
John Bauman66b8ab22014-05-06 15:57:45 -04006359
Nicolas Capensf160b172014-11-26 11:58:23 -05006360 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006361
Nicolas Capensf160b172014-11-26 11:58:23 -05006362 if(context)
6363 {
6364 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006365
Nicolas Capensf160b172014-11-26 11:58:23 -05006366 if(!program)
6367 {
6368 return error(GL_INVALID_OPERATION);
6369 }
John Bauman66b8ab22014-05-06 15:57:45 -04006370
Nicolas Capensf160b172014-11-26 11:58:23 -05006371 if(!program->setUniform2fv(location, count, v))
6372 {
6373 return error(GL_INVALID_OPERATION);
6374 }
6375 }
John Bauman66b8ab22014-05-06 15:57:45 -04006376}
6377
Nicolas Capenseb195b62015-04-28 17:18:42 -07006378void Uniform2i(GLint location, GLint x, GLint y)
John Bauman66b8ab22014-05-06 15:57:45 -04006379{
Nicolas Capensf160b172014-11-26 11:58:23 -05006380 GLint xy[4] = {x, y};
John Bauman66b8ab22014-05-06 15:57:45 -04006381
Nicolas Capensf160b172014-11-26 11:58:23 -05006382 glUniform2iv(location, 1, (GLint*)&xy);
John Bauman66b8ab22014-05-06 15:57:45 -04006383}
6384
Nicolas Capenseb195b62015-04-28 17:18:42 -07006385void Uniform2iv(GLint location, GLsizei count, const GLint* v)
John Bauman66b8ab22014-05-06 15:57:45 -04006386{
Nicolas Capens4be33702015-04-28 15:13:30 -07006387 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006388
Nicolas Capensf160b172014-11-26 11:58:23 -05006389 if(count < 0)
6390 {
6391 return error(GL_INVALID_VALUE);
6392 }
John Bauman66b8ab22014-05-06 15:57:45 -04006393
Nicolas Capensf160b172014-11-26 11:58:23 -05006394 if(location == -1)
6395 {
6396 return;
6397 }
John Bauman66b8ab22014-05-06 15:57:45 -04006398
Nicolas Capensf160b172014-11-26 11:58:23 -05006399 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006400
Nicolas Capensf160b172014-11-26 11:58:23 -05006401 if(context)
6402 {
6403 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006404
Nicolas Capensf160b172014-11-26 11:58:23 -05006405 if(!program)
6406 {
6407 return error(GL_INVALID_OPERATION);
6408 }
John Bauman66b8ab22014-05-06 15:57:45 -04006409
Nicolas Capensf160b172014-11-26 11:58:23 -05006410 if(!program->setUniform2iv(location, count, v))
6411 {
6412 return error(GL_INVALID_OPERATION);
6413 }
6414 }
John Bauman66b8ab22014-05-06 15:57:45 -04006415}
6416
Nicolas Capenseb195b62015-04-28 17:18:42 -07006417void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
John Bauman66b8ab22014-05-06 15:57:45 -04006418{
Nicolas Capensf160b172014-11-26 11:58:23 -05006419 GLfloat xyz[3] = {x, y, z};
John Bauman66b8ab22014-05-06 15:57:45 -04006420
Nicolas Capensf160b172014-11-26 11:58:23 -05006421 glUniform3fv(location, 1, (GLfloat*)&xyz);
John Bauman66b8ab22014-05-06 15:57:45 -04006422}
6423
Nicolas Capenseb195b62015-04-28 17:18:42 -07006424void Uniform3fv(GLint location, GLsizei count, const GLfloat* v)
John Bauman66b8ab22014-05-06 15:57:45 -04006425{
Nicolas Capens4be33702015-04-28 15:13:30 -07006426 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006427
Nicolas Capensf160b172014-11-26 11:58:23 -05006428 if(count < 0)
6429 {
6430 return error(GL_INVALID_VALUE);
6431 }
John Bauman66b8ab22014-05-06 15:57:45 -04006432
Nicolas Capensf160b172014-11-26 11:58:23 -05006433 if(location == -1)
6434 {
6435 return;
6436 }
John Bauman66b8ab22014-05-06 15:57:45 -04006437
Nicolas Capensf160b172014-11-26 11:58:23 -05006438 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006439
Nicolas Capensf160b172014-11-26 11:58:23 -05006440 if(context)
6441 {
6442 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006443
Nicolas Capensf160b172014-11-26 11:58:23 -05006444 if(!program)
6445 {
6446 return error(GL_INVALID_OPERATION);
6447 }
John Bauman66b8ab22014-05-06 15:57:45 -04006448
Nicolas Capensf160b172014-11-26 11:58:23 -05006449 if(!program->setUniform3fv(location, count, v))
6450 {
6451 return error(GL_INVALID_OPERATION);
6452 }
6453 }
John Bauman66b8ab22014-05-06 15:57:45 -04006454}
6455
Nicolas Capenseb195b62015-04-28 17:18:42 -07006456void Uniform3i(GLint location, GLint x, GLint y, GLint z)
John Bauman66b8ab22014-05-06 15:57:45 -04006457{
Nicolas Capensf160b172014-11-26 11:58:23 -05006458 GLint xyz[3] = {x, y, z};
John Bauman66b8ab22014-05-06 15:57:45 -04006459
Nicolas Capensf160b172014-11-26 11:58:23 -05006460 glUniform3iv(location, 1, (GLint*)&xyz);
John Bauman66b8ab22014-05-06 15:57:45 -04006461}
6462
Nicolas Capenseb195b62015-04-28 17:18:42 -07006463void Uniform3iv(GLint location, GLsizei count, const GLint* v)
John Bauman66b8ab22014-05-06 15:57:45 -04006464{
Nicolas Capens4be33702015-04-28 15:13:30 -07006465 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006466
Nicolas Capensf160b172014-11-26 11:58:23 -05006467 if(count < 0)
6468 {
6469 return error(GL_INVALID_VALUE);
6470 }
John Bauman66b8ab22014-05-06 15:57:45 -04006471
Nicolas Capensf160b172014-11-26 11:58:23 -05006472 if(location == -1)
6473 {
6474 return;
6475 }
John Bauman66b8ab22014-05-06 15:57:45 -04006476
Nicolas Capensf160b172014-11-26 11:58:23 -05006477 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006478
Nicolas Capensf160b172014-11-26 11:58:23 -05006479 if(context)
6480 {
6481 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006482
Nicolas Capensf160b172014-11-26 11:58:23 -05006483 if(!program)
6484 {
6485 return error(GL_INVALID_OPERATION);
6486 }
John Bauman66b8ab22014-05-06 15:57:45 -04006487
Nicolas Capensf160b172014-11-26 11:58:23 -05006488 if(!program->setUniform3iv(location, count, v))
6489 {
6490 return error(GL_INVALID_OPERATION);
6491 }
6492 }
John Bauman66b8ab22014-05-06 15:57:45 -04006493}
6494
Nicolas Capenseb195b62015-04-28 17:18:42 -07006495void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
John Bauman66b8ab22014-05-06 15:57:45 -04006496{
Nicolas Capensf160b172014-11-26 11:58:23 -05006497 GLfloat xyzw[4] = {x, y, z, w};
John Bauman66b8ab22014-05-06 15:57:45 -04006498
Nicolas Capensf160b172014-11-26 11:58:23 -05006499 glUniform4fv(location, 1, (GLfloat*)&xyzw);
John Bauman66b8ab22014-05-06 15:57:45 -04006500}
6501
Nicolas Capenseb195b62015-04-28 17:18:42 -07006502void Uniform4fv(GLint location, GLsizei count, const GLfloat* v)
John Bauman66b8ab22014-05-06 15:57:45 -04006503{
Nicolas Capens4be33702015-04-28 15:13:30 -07006504 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006505
Nicolas Capensf160b172014-11-26 11:58:23 -05006506 if(count < 0)
6507 {
6508 return error(GL_INVALID_VALUE);
6509 }
John Bauman66b8ab22014-05-06 15:57:45 -04006510
Nicolas Capensf160b172014-11-26 11:58:23 -05006511 if(location == -1)
6512 {
6513 return;
6514 }
John Bauman66b8ab22014-05-06 15:57:45 -04006515
Nicolas Capensf160b172014-11-26 11:58:23 -05006516 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006517
Nicolas Capensf160b172014-11-26 11:58:23 -05006518 if(context)
6519 {
6520 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006521
Nicolas Capensf160b172014-11-26 11:58:23 -05006522 if(!program)
6523 {
6524 return error(GL_INVALID_OPERATION);
6525 }
John Bauman66b8ab22014-05-06 15:57:45 -04006526
Nicolas Capensf160b172014-11-26 11:58:23 -05006527 if(!program->setUniform4fv(location, count, v))
6528 {
6529 return error(GL_INVALID_OPERATION);
6530 }
6531 }
John Bauman66b8ab22014-05-06 15:57:45 -04006532}
6533
Nicolas Capenseb195b62015-04-28 17:18:42 -07006534void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
John Bauman66b8ab22014-05-06 15:57:45 -04006535{
Nicolas Capensf160b172014-11-26 11:58:23 -05006536 GLint xyzw[4] = {x, y, z, w};
John Bauman66b8ab22014-05-06 15:57:45 -04006537
Nicolas Capensf160b172014-11-26 11:58:23 -05006538 glUniform4iv(location, 1, (GLint*)&xyzw);
John Bauman66b8ab22014-05-06 15:57:45 -04006539}
6540
Nicolas Capenseb195b62015-04-28 17:18:42 -07006541void Uniform4iv(GLint location, GLsizei count, const GLint* v)
John Bauman66b8ab22014-05-06 15:57:45 -04006542{
Nicolas Capens4be33702015-04-28 15:13:30 -07006543 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
John Bauman66b8ab22014-05-06 15:57:45 -04006544
Nicolas Capensf160b172014-11-26 11:58:23 -05006545 if(count < 0)
6546 {
6547 return error(GL_INVALID_VALUE);
6548 }
John Bauman66b8ab22014-05-06 15:57:45 -04006549
Nicolas Capensf160b172014-11-26 11:58:23 -05006550 if(location == -1)
6551 {
6552 return;
6553 }
John Bauman66b8ab22014-05-06 15:57:45 -04006554
Nicolas Capensf160b172014-11-26 11:58:23 -05006555 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006556
Nicolas Capensf160b172014-11-26 11:58:23 -05006557 if(context)
6558 {
6559 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006560
Nicolas Capensf160b172014-11-26 11:58:23 -05006561 if(!program)
6562 {
6563 return error(GL_INVALID_OPERATION);
6564 }
John Bauman66b8ab22014-05-06 15:57:45 -04006565
Nicolas Capensf160b172014-11-26 11:58:23 -05006566 if(!program->setUniform4iv(location, count, v))
6567 {
6568 return error(GL_INVALID_OPERATION);
6569 }
6570 }
John Bauman66b8ab22014-05-06 15:57:45 -04006571}
6572
Nicolas Capenseb195b62015-04-28 17:18:42 -07006573void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
John Bauman66b8ab22014-05-06 15:57:45 -04006574{
Nicolas Capens4be33702015-04-28 15:13:30 -07006575 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006576 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006577
Alexis Hetu4de7e2e2015-05-21 10:47:04 -04006578 if(count < 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05006579 {
6580 return error(GL_INVALID_VALUE);
6581 }
John Bauman66b8ab22014-05-06 15:57:45 -04006582
Nicolas Capensf160b172014-11-26 11:58:23 -05006583 if(location == -1)
6584 {
6585 return;
6586 }
John Bauman66b8ab22014-05-06 15:57:45 -04006587
Nicolas Capensf160b172014-11-26 11:58:23 -05006588 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006589
Nicolas Capensf160b172014-11-26 11:58:23 -05006590 if(context)
6591 {
Alexis Hetu4de7e2e2015-05-21 10:47:04 -04006592 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
6593 {
6594 return error(GL_INVALID_VALUE);
6595 }
6596
Nicolas Capensf160b172014-11-26 11:58:23 -05006597 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006598
Nicolas Capensf160b172014-11-26 11:58:23 -05006599 if(!program)
6600 {
6601 return error(GL_INVALID_OPERATION);
6602 }
John Bauman66b8ab22014-05-06 15:57:45 -04006603
Alexis Hetu4de7e2e2015-05-21 10:47:04 -04006604 if(!program->setUniformMatrix2fv(location, count, transpose, value))
Nicolas Capensf160b172014-11-26 11:58:23 -05006605 {
6606 return error(GL_INVALID_OPERATION);
6607 }
6608 }
John Bauman66b8ab22014-05-06 15:57:45 -04006609}
6610
Nicolas Capenseb195b62015-04-28 17:18:42 -07006611void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
John Bauman66b8ab22014-05-06 15:57:45 -04006612{
Nicolas Capens4be33702015-04-28 15:13:30 -07006613 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006614 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006615
Alexis Hetu4de7e2e2015-05-21 10:47:04 -04006616 if(count < 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05006617 {
6618 return error(GL_INVALID_VALUE);
6619 }
John Bauman66b8ab22014-05-06 15:57:45 -04006620
Nicolas Capensf160b172014-11-26 11:58:23 -05006621 if(location == -1)
6622 {
6623 return;
6624 }
John Bauman66b8ab22014-05-06 15:57:45 -04006625
Nicolas Capensf160b172014-11-26 11:58:23 -05006626 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006627
Nicolas Capensf160b172014-11-26 11:58:23 -05006628 if(context)
6629 {
Alexis Hetu4de7e2e2015-05-21 10:47:04 -04006630 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
6631 {
6632 return error(GL_INVALID_VALUE);
6633 }
6634
Nicolas Capensf160b172014-11-26 11:58:23 -05006635 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006636
Nicolas Capensf160b172014-11-26 11:58:23 -05006637 if(!program)
6638 {
6639 return error(GL_INVALID_OPERATION);
6640 }
John Bauman66b8ab22014-05-06 15:57:45 -04006641
Alexis Hetu4de7e2e2015-05-21 10:47:04 -04006642 if(!program->setUniformMatrix3fv(location, count, transpose, value))
Nicolas Capensf160b172014-11-26 11:58:23 -05006643 {
6644 return error(GL_INVALID_OPERATION);
6645 }
6646 }
John Bauman66b8ab22014-05-06 15:57:45 -04006647}
6648
Nicolas Capenseb195b62015-04-28 17:18:42 -07006649void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
John Bauman66b8ab22014-05-06 15:57:45 -04006650{
Nicolas Capens4be33702015-04-28 15:13:30 -07006651 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006652 location, count, transpose, value);
John Bauman66b8ab22014-05-06 15:57:45 -04006653
Alexis Hetu4de7e2e2015-05-21 10:47:04 -04006654 if(count < 0)
Nicolas Capensf160b172014-11-26 11:58:23 -05006655 {
6656 return error(GL_INVALID_VALUE);
6657 }
John Bauman66b8ab22014-05-06 15:57:45 -04006658
Nicolas Capensf160b172014-11-26 11:58:23 -05006659 if(location == -1)
6660 {
6661 return;
6662 }
John Bauman66b8ab22014-05-06 15:57:45 -04006663
Nicolas Capensf160b172014-11-26 11:58:23 -05006664 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006665
Nicolas Capensf160b172014-11-26 11:58:23 -05006666 if(context)
6667 {
Alexis Hetu4de7e2e2015-05-21 10:47:04 -04006668 if(context->getClientVersion() < 3 && transpose != GL_FALSE)
6669 {
6670 return error(GL_INVALID_VALUE);
6671 }
6672
Nicolas Capensf160b172014-11-26 11:58:23 -05006673 es2::Program *program = context->getCurrentProgram();
John Bauman66b8ab22014-05-06 15:57:45 -04006674
Nicolas Capensf160b172014-11-26 11:58:23 -05006675 if(!program)
6676 {
6677 return error(GL_INVALID_OPERATION);
6678 }
John Bauman66b8ab22014-05-06 15:57:45 -04006679
Alexis Hetu4de7e2e2015-05-21 10:47:04 -04006680 if(!program->setUniformMatrix4fv(location, count, transpose, value))
Nicolas Capensf160b172014-11-26 11:58:23 -05006681 {
6682 return error(GL_INVALID_OPERATION);
6683 }
6684 }
John Bauman66b8ab22014-05-06 15:57:45 -04006685}
6686
Nicolas Capenseb195b62015-04-28 17:18:42 -07006687void UseProgram(GLuint program)
John Bauman66b8ab22014-05-06 15:57:45 -04006688{
Nicolas Capensf160b172014-11-26 11:58:23 -05006689 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04006690
Nicolas Capensf160b172014-11-26 11:58:23 -05006691 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006692
Nicolas Capensf160b172014-11-26 11:58:23 -05006693 if(context)
6694 {
6695 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04006696
Nicolas Capensf160b172014-11-26 11:58:23 -05006697 if(!programObject && program != 0)
6698 {
6699 if(context->getShader(program))
6700 {
6701 return error(GL_INVALID_OPERATION);
6702 }
6703 else
6704 {
6705 return error(GL_INVALID_VALUE);
6706 }
6707 }
John Bauman66b8ab22014-05-06 15:57:45 -04006708
Nicolas Capensf160b172014-11-26 11:58:23 -05006709 if(program != 0 && !programObject->isLinked())
6710 {
6711 return error(GL_INVALID_OPERATION);
6712 }
John Bauman66b8ab22014-05-06 15:57:45 -04006713
Nicolas Capensf160b172014-11-26 11:58:23 -05006714 context->useProgram(program);
6715 }
John Bauman66b8ab22014-05-06 15:57:45 -04006716}
6717
Nicolas Capenseb195b62015-04-28 17:18:42 -07006718void ValidateProgram(GLuint program)
John Bauman66b8ab22014-05-06 15:57:45 -04006719{
Nicolas Capensf160b172014-11-26 11:58:23 -05006720 TRACE("(GLuint program = %d)", program);
John Bauman66b8ab22014-05-06 15:57:45 -04006721
Nicolas Capensf160b172014-11-26 11:58:23 -05006722 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006723
Nicolas Capensf160b172014-11-26 11:58:23 -05006724 if(context)
6725 {
6726 es2::Program *programObject = context->getProgram(program);
John Bauman66b8ab22014-05-06 15:57:45 -04006727
Nicolas Capensf160b172014-11-26 11:58:23 -05006728 if(!programObject)
6729 {
6730 if(context->getShader(program))
6731 {
6732 return error(GL_INVALID_OPERATION);
6733 }
6734 else
6735 {
6736 return error(GL_INVALID_VALUE);
6737 }
6738 }
John Bauman66b8ab22014-05-06 15:57:45 -04006739
Nicolas Capensf160b172014-11-26 11:58:23 -05006740 programObject->validate();
6741 }
John Bauman66b8ab22014-05-06 15:57:45 -04006742}
6743
Nicolas Capenseb195b62015-04-28 17:18:42 -07006744void VertexAttrib1f(GLuint index, GLfloat x)
John Bauman66b8ab22014-05-06 15:57:45 -04006745{
Nicolas Capensf160b172014-11-26 11:58:23 -05006746 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
John Bauman66b8ab22014-05-06 15:57:45 -04006747
Nicolas Capensf160b172014-11-26 11:58:23 -05006748 if(index >= es2::MAX_VERTEX_ATTRIBS)
6749 {
6750 return error(GL_INVALID_VALUE);
6751 }
John Bauman66b8ab22014-05-06 15:57:45 -04006752
Nicolas Capensf160b172014-11-26 11:58:23 -05006753 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006754
Nicolas Capensf160b172014-11-26 11:58:23 -05006755 if(context)
6756 {
6757 GLfloat vals[4] = { x, 0, 0, 1 };
6758 context->setVertexAttrib(index, vals);
6759 }
John Bauman66b8ab22014-05-06 15:57:45 -04006760}
6761
Nicolas Capenseb195b62015-04-28 17:18:42 -07006762void VertexAttrib1fv(GLuint index, const GLfloat* values)
John Bauman66b8ab22014-05-06 15:57:45 -04006763{
Nicolas Capens4be33702015-04-28 15:13:30 -07006764 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006765
Nicolas Capensf160b172014-11-26 11:58:23 -05006766 if(index >= es2::MAX_VERTEX_ATTRIBS)
6767 {
6768 return error(GL_INVALID_VALUE);
6769 }
John Bauman66b8ab22014-05-06 15:57:45 -04006770
Nicolas Capensf160b172014-11-26 11:58:23 -05006771 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006772
Nicolas Capensf160b172014-11-26 11:58:23 -05006773 if(context)
6774 {
6775 GLfloat vals[4] = { values[0], 0, 0, 1 };
6776 context->setVertexAttrib(index, vals);
6777 }
John Bauman66b8ab22014-05-06 15:57:45 -04006778}
6779
Nicolas Capenseb195b62015-04-28 17:18:42 -07006780void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
John Bauman66b8ab22014-05-06 15:57:45 -04006781{
Nicolas Capensf160b172014-11-26 11:58:23 -05006782 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
John Bauman66b8ab22014-05-06 15:57:45 -04006783
Nicolas Capensf160b172014-11-26 11:58:23 -05006784 if(index >= es2::MAX_VERTEX_ATTRIBS)
6785 {
6786 return error(GL_INVALID_VALUE);
6787 }
John Bauman66b8ab22014-05-06 15:57:45 -04006788
Nicolas Capensf160b172014-11-26 11:58:23 -05006789 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006790
Nicolas Capensf160b172014-11-26 11:58:23 -05006791 if(context)
6792 {
6793 GLfloat vals[4] = { x, y, 0, 1 };
6794 context->setVertexAttrib(index, vals);
6795 }
John Bauman66b8ab22014-05-06 15:57:45 -04006796}
6797
Nicolas Capenseb195b62015-04-28 17:18:42 -07006798void VertexAttrib2fv(GLuint index, const GLfloat* values)
John Bauman66b8ab22014-05-06 15:57:45 -04006799{
Nicolas Capens4be33702015-04-28 15:13:30 -07006800 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006801
Nicolas Capensf160b172014-11-26 11:58:23 -05006802 if(index >= es2::MAX_VERTEX_ATTRIBS)
6803 {
6804 return error(GL_INVALID_VALUE);
6805 }
John Bauman66b8ab22014-05-06 15:57:45 -04006806
Nicolas Capensf160b172014-11-26 11:58:23 -05006807 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006808
Nicolas Capensf160b172014-11-26 11:58:23 -05006809 if(context)
6810 {
6811 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6812 context->setVertexAttrib(index, vals);
6813 }
John Bauman66b8ab22014-05-06 15:57:45 -04006814}
6815
Nicolas Capenseb195b62015-04-28 17:18:42 -07006816void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
John Bauman66b8ab22014-05-06 15:57:45 -04006817{
Nicolas Capensf160b172014-11-26 11:58:23 -05006818 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
John Bauman66b8ab22014-05-06 15:57:45 -04006819
Nicolas Capensf160b172014-11-26 11:58:23 -05006820 if(index >= es2::MAX_VERTEX_ATTRIBS)
6821 {
6822 return error(GL_INVALID_VALUE);
6823 }
John Bauman66b8ab22014-05-06 15:57:45 -04006824
Nicolas Capensf160b172014-11-26 11:58:23 -05006825 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006826
Nicolas Capensf160b172014-11-26 11:58:23 -05006827 if(context)
6828 {
6829 GLfloat vals[4] = { x, y, z, 1 };
6830 context->setVertexAttrib(index, vals);
6831 }
John Bauman66b8ab22014-05-06 15:57:45 -04006832}
6833
Nicolas Capenseb195b62015-04-28 17:18:42 -07006834void VertexAttrib3fv(GLuint index, const GLfloat* values)
John Bauman66b8ab22014-05-06 15:57:45 -04006835{
Nicolas Capens4be33702015-04-28 15:13:30 -07006836 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006837
Nicolas Capensf160b172014-11-26 11:58:23 -05006838 if(index >= es2::MAX_VERTEX_ATTRIBS)
6839 {
6840 return error(GL_INVALID_VALUE);
6841 }
John Bauman66b8ab22014-05-06 15:57:45 -04006842
Nicolas Capensf160b172014-11-26 11:58:23 -05006843 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006844
Nicolas Capensf160b172014-11-26 11:58:23 -05006845 if(context)
6846 {
6847 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6848 context->setVertexAttrib(index, vals);
6849 }
John Bauman66b8ab22014-05-06 15:57:45 -04006850}
6851
Nicolas Capenseb195b62015-04-28 17:18:42 -07006852void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
John Bauman66b8ab22014-05-06 15:57:45 -04006853{
Nicolas Capensf160b172014-11-26 11:58:23 -05006854 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 -04006855
Nicolas Capensf160b172014-11-26 11:58:23 -05006856 if(index >= es2::MAX_VERTEX_ATTRIBS)
6857 {
6858 return error(GL_INVALID_VALUE);
6859 }
John Bauman66b8ab22014-05-06 15:57:45 -04006860
Nicolas Capensf160b172014-11-26 11:58:23 -05006861 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006862
Nicolas Capensf160b172014-11-26 11:58:23 -05006863 if(context)
6864 {
6865 GLfloat vals[4] = { x, y, z, w };
6866 context->setVertexAttrib(index, vals);
6867 }
John Bauman66b8ab22014-05-06 15:57:45 -04006868}
6869
Nicolas Capenseb195b62015-04-28 17:18:42 -07006870void VertexAttrib4fv(GLuint index, const GLfloat* values)
John Bauman66b8ab22014-05-06 15:57:45 -04006871{
Nicolas Capens4be33702015-04-28 15:13:30 -07006872 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
John Bauman66b8ab22014-05-06 15:57:45 -04006873
Nicolas Capensf160b172014-11-26 11:58:23 -05006874 if(index >= es2::MAX_VERTEX_ATTRIBS)
6875 {
6876 return error(GL_INVALID_VALUE);
6877 }
John Bauman66b8ab22014-05-06 15:57:45 -04006878
Nicolas Capensf160b172014-11-26 11:58:23 -05006879 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006880
Nicolas Capensf160b172014-11-26 11:58:23 -05006881 if(context)
6882 {
6883 context->setVertexAttrib(index, values);
6884 }
John Bauman66b8ab22014-05-06 15:57:45 -04006885}
6886
Nicolas Capenseb195b62015-04-28 17:18:42 -07006887void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
John Bauman66b8ab22014-05-06 15:57:45 -04006888{
Nicolas Capensf160b172014-11-26 11:58:23 -05006889 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07006890 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05006891 index, size, type, normalized, stride, ptr);
John Bauman66b8ab22014-05-06 15:57:45 -04006892
Nicolas Capensf160b172014-11-26 11:58:23 -05006893 if(index >= es2::MAX_VERTEX_ATTRIBS)
6894 {
6895 return error(GL_INVALID_VALUE);
6896 }
John Bauman66b8ab22014-05-06 15:57:45 -04006897
Nicolas Capensf160b172014-11-26 11:58:23 -05006898 if(size < 1 || size > 4)
6899 {
6900 return error(GL_INVALID_VALUE);
6901 }
John Bauman66b8ab22014-05-06 15:57:45 -04006902
Alexis Hetued306182015-04-02 12:02:28 -04006903 egl::GLint clientVersion = egl::getClientVersion();
6904
Nicolas Capensf160b172014-11-26 11:58:23 -05006905 switch(type)
6906 {
6907 case GL_BYTE:
6908 case GL_UNSIGNED_BYTE:
6909 case GL_SHORT:
6910 case GL_UNSIGNED_SHORT:
6911 case GL_FIXED:
6912 case GL_FLOAT:
6913 break;
Alexis Hetued306182015-04-02 12:02:28 -04006914 case GL_INT_2_10_10_10_REV:
6915 case GL_UNSIGNED_INT_2_10_10_10_REV:
6916 if(clientVersion >= 3)
6917 {
6918 if(size != 4)
6919 {
6920 return error(GL_INVALID_OPERATION);
6921 }
6922 break;
6923 }
6924 else return error(GL_INVALID_ENUM);
6925 case GL_INT:
6926 case GL_UNSIGNED_INT:
6927 case GL_HALF_FLOAT:
6928 if(clientVersion >= 3)
6929 {
6930 break;
6931 }
6932 else return error(GL_INVALID_ENUM);
Nicolas Capensf160b172014-11-26 11:58:23 -05006933 default:
6934 return error(GL_INVALID_ENUM);
6935 }
John Bauman66b8ab22014-05-06 15:57:45 -04006936
Nicolas Capensf160b172014-11-26 11:58:23 -05006937 if(stride < 0)
6938 {
6939 return error(GL_INVALID_VALUE);
6940 }
John Bauman66b8ab22014-05-06 15:57:45 -04006941
Nicolas Capensf160b172014-11-26 11:58:23 -05006942 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006943
Nicolas Capensf160b172014-11-26 11:58:23 -05006944 if(context)
6945 {
6946 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
6947 }
John Bauman66b8ab22014-05-06 15:57:45 -04006948}
6949
Nicolas Capenseb195b62015-04-28 17:18:42 -07006950void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
John Bauman66b8ab22014-05-06 15:57:45 -04006951{
Nicolas Capensf160b172014-11-26 11:58:23 -05006952 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
John Bauman66b8ab22014-05-06 15:57:45 -04006953
Nicolas Capensf160b172014-11-26 11:58:23 -05006954 if(width < 0 || height < 0)
6955 {
6956 return error(GL_INVALID_VALUE);
6957 }
John Bauman66b8ab22014-05-06 15:57:45 -04006958
Nicolas Capensf160b172014-11-26 11:58:23 -05006959 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006960
Nicolas Capensf160b172014-11-26 11:58:23 -05006961 if(context)
6962 {
6963 context->setViewportParams(x, y, width, height);
6964 }
John Bauman66b8ab22014-05-06 15:57:45 -04006965}
6966
Nicolas Capenseb195b62015-04-28 17:18:42 -07006967void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
John Bauman66b8ab22014-05-06 15:57:45 -04006968{
Nicolas Capensf160b172014-11-26 11:58:23 -05006969 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
6970 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6971 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6972 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
John Bauman66b8ab22014-05-06 15:57:45 -04006973
Nicolas Capensf160b172014-11-26 11:58:23 -05006974 switch(filter)
6975 {
6976 case GL_NEAREST:
6977 break;
6978 default:
6979 return error(GL_INVALID_ENUM);
6980 }
John Bauman66b8ab22014-05-06 15:57:45 -04006981
Nicolas Capensf160b172014-11-26 11:58:23 -05006982 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6983 {
6984 return error(GL_INVALID_VALUE);
6985 }
John Bauman66b8ab22014-05-06 15:57:45 -04006986
Nicolas Capensf160b172014-11-26 11:58:23 -05006987 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -04006988
Nicolas Capensf160b172014-11-26 11:58:23 -05006989 if(context)
6990 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05006991 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
Nicolas Capensf160b172014-11-26 11:58:23 -05006992 {
6993 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6994 return error(GL_INVALID_OPERATION);
6995 }
John Bauman66b8ab22014-05-06 15:57:45 -04006996
Nicolas Capensf160b172014-11-26 11:58:23 -05006997 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6998 }
John Bauman66b8ab22014-05-06 15:57:45 -04006999}
7000
Nicolas Capenseb195b62015-04-28 17:18:42 -07007001void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
7002 GLbitfield mask, GLenum filter)
Alexis Hetue9233fb2015-02-11 10:31:58 -05007003{
7004 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
7005 {
7006 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
7007 return error(GL_INVALID_OPERATION);
7008 }
7009
7010 glBlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
7011}
7012
Nicolas Capenseb195b62015-04-28 17:18:42 -07007013void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
7014 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
John Bauman66b8ab22014-05-06 15:57:45 -04007015{
Nicolas Capensf160b172014-11-26 11:58:23 -05007016 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
7017 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07007018 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
Nicolas Capensf160b172014-11-26 11:58:23 -05007019 target, level, internalformat, width, height, depth, border, format, type, pixels);
John Bauman66b8ab22014-05-06 15:57:45 -04007020
Alexis Hetub027aa92015-01-19 15:56:12 -05007021 switch(target)
7022 {
7023 case GL_TEXTURE_3D_OES:
7024 switch(format)
7025 {
7026 case GL_DEPTH_COMPONENT:
7027 case GL_DEPTH_STENCIL_OES:
7028 return error(GL_INVALID_OPERATION);
7029 default:
7030 break;
7031 }
7032 break;
7033 default:
7034 return error(GL_INVALID_ENUM);
7035 }
7036
7037 if(!ValidateType3D(type) || !ValidateFormat3D(format))
7038 {
7039 return error(GL_INVALID_ENUM);
7040 }
7041
7042 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
7043 {
7044 return error(GL_INVALID_VALUE);
7045 }
7046
7047 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
7048 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
7049 {
7050 return error(GL_INVALID_VALUE);
7051 }
7052
7053 if(border != 0)
7054 {
7055 return error(GL_INVALID_VALUE);
7056 }
7057
7058 if(!ValidateInternalFormat3D(internalformat, format, type))
7059 {
7060 return error(GL_INVALID_OPERATION);
7061 }
7062
7063 es2::Context *context = es2::getContext();
7064
7065 if(context)
7066 {
7067 es2::Texture3D *texture = context->getTexture3D();
7068
7069 if(!texture)
7070 {
7071 return error(GL_INVALID_OPERATION);
7072 }
7073
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04007074 texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);
Alexis Hetub027aa92015-01-19 15:56:12 -05007075 }
John Bauman66b8ab22014-05-06 15:57:45 -04007076}
7077
Nicolas Capenseb195b62015-04-28 17:18:42 -07007078void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007079{
Alexis Hetub027aa92015-01-19 15:56:12 -05007080 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
Nicolas Capens57670992015-09-02 16:52:38 -04007081 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
7082 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
7083 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007084
Alexis Hetub027aa92015-01-19 15:56:12 -05007085 switch(target)
7086 {
7087 case GL_TEXTURE_3D_OES:
7088 break;
7089 default:
7090 return error(GL_INVALID_ENUM);
7091 }
7092
7093 if(!ValidateType3D(type) || !ValidateFormat3D(format))
7094 {
7095 return error(GL_INVALID_ENUM);
7096 }
7097
7098 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
7099 {
7100 return error(GL_INVALID_VALUE);
7101 }
7102
7103 if((width < 0) || (height < 0) || (depth < 0))
7104 {
7105 return error(GL_INVALID_VALUE);
7106 }
7107
7108 es2::Context *context = es2::getContext();
7109
7110 if(context)
7111 {
7112 es2::Texture3D *texture = context->getTexture3D();
7113
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04007114 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
7115
7116 GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);
7117 if(validationError == GL_NONE)
Alexis Hetub027aa92015-01-19 15:56:12 -05007118 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04007119 texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
7120 }
7121 else
7122 {
7123 return error(validationError);
Alexis Hetub027aa92015-01-19 15:56:12 -05007124 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007125 }
7126}
7127
Nicolas Capenseb195b62015-04-28 17:18:42 -07007128void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007129{
Alexis Hetub027aa92015-01-19 15:56:12 -05007130 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
Nicolas Capens57670992015-09-02 16:52:38 -04007131 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
7132 target, level, xoffset, yoffset, zoffset, x, y, width, height);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007133
Alexis Hetub027aa92015-01-19 15:56:12 -05007134 switch(target)
7135 {
7136 case GL_TEXTURE_3D_OES:
7137 break;
7138 default:
7139 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007140 }
7141
Alexis Hetub027aa92015-01-19 15:56:12 -05007142 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
7143 {
7144 return error(GL_INVALID_VALUE);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007145 }
7146
Alexis Hetub027aa92015-01-19 15:56:12 -05007147 es2::Context *context = es2::getContext();
7148
7149 if(context)
7150 {
7151 es2::Framebuffer *framebuffer = context->getReadFramebuffer();
7152
7153 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
7154 {
7155 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
7156 }
7157
Alexis Hetu1b2f6282015-04-16 16:27:42 -04007158 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
7159
7160 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
Alexis Hetub027aa92015-01-19 15:56:12 -05007161 {
7162 return error(GL_INVALID_OPERATION);
7163 }
7164
Alexis Hetub027aa92015-01-19 15:56:12 -05007165 es2::Texture3D *texture = context->getTexture3D();
7166
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04007167 GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);
7168
7169 if(validationError != GL_NONE)
Alexis Hetub027aa92015-01-19 15:56:12 -05007170 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04007171 return error(validationError);
Alexis Hetub027aa92015-01-19 15:56:12 -05007172 }
7173
Alexis Hetub027aa92015-01-19 15:56:12 -05007174 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007175 }
7176}
7177
Nicolas Capenseb195b62015-04-28 17:18:42 -07007178void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007179{
Alexis Hetub027aa92015-01-19 15:56:12 -05007180 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
Nicolas Capens57670992015-09-02 16:52:38 -04007181 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
7182 target, level, internalformat, width, height, depth, border, imageSize, data);
Alexis Hetub027aa92015-01-19 15:56:12 -05007183
7184 switch(target)
7185 {
7186 case GL_TEXTURE_3D_OES:
7187 break;
7188 default:
7189 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007190 }
Alexis Hetub027aa92015-01-19 15:56:12 -05007191
7192 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
7193 {
7194 return error(GL_INVALID_VALUE);
7195 }
7196
7197 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
7198 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
7199 {
7200 return error(GL_INVALID_VALUE);
7201 }
7202
7203 switch(internalformat)
7204 {
Alexis Hetub027aa92015-01-19 15:56:12 -05007205 case GL_DEPTH_COMPONENT:
7206 case GL_DEPTH_COMPONENT16:
7207 case GL_DEPTH_COMPONENT32_OES:
7208 case GL_DEPTH_STENCIL_OES:
7209 case GL_DEPTH24_STENCIL8_OES:
7210 return error(GL_INVALID_OPERATION);
7211 default:
Alexis Hetu460e41f2015-09-01 10:58:37 -04007212 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04007213 GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
7214 if(validationError != GL_NONE)
Alexis Hetu460e41f2015-09-01 10:58:37 -04007215 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04007216 return error(validationError);
Alexis Hetu460e41f2015-09-01 10:58:37 -04007217 }
7218 }
Alexis Hetub027aa92015-01-19 15:56:12 -05007219 }
7220
Nicolas Capensdeda34b2015-04-28 15:21:53 -07007221 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
Alexis Hetub027aa92015-01-19 15:56:12 -05007222 {
7223 return error(GL_INVALID_VALUE);
7224 }
7225
7226 es2::Context *context = es2::getContext();
7227
7228 if(context)
7229 {
7230 es2::Texture3D *texture = context->getTexture3D();
7231
7232 if(!texture)
7233 {
7234 return error(GL_INVALID_OPERATION);
7235 }
7236
7237 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007238 }
7239}
7240
Nicolas Capenseb195b62015-04-28 17:18:42 -07007241void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007242{
Alexis Hetub027aa92015-01-19 15:56:12 -05007243 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
Nicolas Capens57670992015-09-02 16:52:38 -04007244 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
7245 "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",
7246 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007247
Alexis Hetub027aa92015-01-19 15:56:12 -05007248 switch(target)
7249 {
7250 case GL_TEXTURE_3D_OES:
7251 break;
7252 default:
7253 return error(GL_INVALID_ENUM);
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007254 }
Alexis Hetub027aa92015-01-19 15:56:12 -05007255
7256 if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
7257 {
7258 return error(GL_INVALID_VALUE);
7259 }
7260
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04007261 GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
7262 if(validationError != GL_NONE)
Alexis Hetub027aa92015-01-19 15:56:12 -05007263 {
Alexis Hetud9a2e7b2015-10-15 17:22:57 -04007264 return error(validationError);
Alexis Hetub027aa92015-01-19 15:56:12 -05007265 }
7266
7267 if(width == 0 || height == 0 || depth == 0 || data == NULL)
7268 {
7269 return;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007270 }
7271
Alexis Hetub027aa92015-01-19 15:56:12 -05007272 es2::Context *context = es2::getContext();
7273
7274 if(context)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007275 {
Alexis Hetub027aa92015-01-19 15:56:12 -05007276 es2::Texture3D *texture = context->getTexture3D();
7277
7278 if(!texture)
7279 {
7280 return error(GL_INVALID_OPERATION);
7281 }
7282
7283 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
7284 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007285}
7286
Nicolas Capenseb195b62015-04-28 17:18:42 -07007287void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007288{
Alexis Hetub027aa92015-01-19 15:56:12 -05007289 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
Nicolas Capens57670992015-09-02 16:52:38 -04007290 "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
Alexis Hetub027aa92015-01-19 15:56:12 -05007291
7292 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
7293 {
7294 return error(GL_INVALID_ENUM);
7295 }
7296
Alexis Hetub027aa92015-01-19 15:56:12 -05007297 es2::Context *context = es2::getContext();
7298
7299 if(context)
7300 {
7301 if(texture == 0)
7302 {
7303 textarget = GL_NONE;
7304 }
7305 else
7306 {
7307 es2::Texture *tex = context->getTexture(texture);
7308
7309 if(tex == NULL)
7310 {
7311 return error(GL_INVALID_OPERATION);
7312 }
7313
7314 if(tex->isCompressed(textarget, level))
7315 {
7316 return error(GL_INVALID_OPERATION);
7317 }
7318
7319 switch(textarget)
7320 {
7321 case GL_TEXTURE_3D_OES:
7322 if(tex->getTarget() != GL_TEXTURE_3D_OES)
7323 {
7324 return error(GL_INVALID_OPERATION);
7325 }
7326 break;
7327 default:
7328 return error(GL_INVALID_ENUM);
7329 }
7330
7331 if(level != 0)
7332 {
7333 return error(GL_INVALID_VALUE);
7334 }
7335 }
7336
7337 es2::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007338 GLuint framebufferName = 0;
Alexis Hetub027aa92015-01-19 15:56:12 -05007339 if(target == GL_READ_FRAMEBUFFER_ANGLE)
7340 {
7341 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007342 framebufferName = context->getReadFramebufferName();
Alexis Hetub027aa92015-01-19 15:56:12 -05007343 }
7344 else
7345 {
7346 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007347 framebufferName = context->getDrawFramebufferName();
Alexis Hetub027aa92015-01-19 15:56:12 -05007348 }
7349
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007350 if(framebufferName == 0 || !framebuffer)
Alexis Hetub027aa92015-01-19 15:56:12 -05007351 {
7352 return error(GL_INVALID_OPERATION);
7353 }
7354
Alexis Hetu1b2f6282015-04-16 16:27:42 -04007355 egl::GLint clientVersion = context->getClientVersion();
7356
Alexis Hetub027aa92015-01-19 15:56:12 -05007357 switch(attachment)
7358 {
Alexis Hetu1b2f6282015-04-16 16:27:42 -04007359 case GL_COLOR_ATTACHMENT1:
7360 case GL_COLOR_ATTACHMENT2:
7361 case GL_COLOR_ATTACHMENT3:
7362 case GL_COLOR_ATTACHMENT4:
7363 case GL_COLOR_ATTACHMENT5:
7364 case GL_COLOR_ATTACHMENT6:
7365 case GL_COLOR_ATTACHMENT7:
7366 case GL_COLOR_ATTACHMENT8:
7367 case GL_COLOR_ATTACHMENT9:
7368 case GL_COLOR_ATTACHMENT10:
7369 case GL_COLOR_ATTACHMENT11:
7370 case GL_COLOR_ATTACHMENT12:
7371 case GL_COLOR_ATTACHMENT13:
7372 case GL_COLOR_ATTACHMENT14:
7373 case GL_COLOR_ATTACHMENT15:
Alexis Hetu3e02f682015-12-02 12:53:42 -05007374 case GL_COLOR_ATTACHMENT16:
7375 case GL_COLOR_ATTACHMENT17:
7376 case GL_COLOR_ATTACHMENT18:
7377 case GL_COLOR_ATTACHMENT19:
7378 case GL_COLOR_ATTACHMENT20:
7379 case GL_COLOR_ATTACHMENT21:
7380 case GL_COLOR_ATTACHMENT22:
7381 case GL_COLOR_ATTACHMENT23:
7382 case GL_COLOR_ATTACHMENT24:
7383 case GL_COLOR_ATTACHMENT25:
7384 case GL_COLOR_ATTACHMENT26:
7385 case GL_COLOR_ATTACHMENT27:
7386 case GL_COLOR_ATTACHMENT28:
7387 case GL_COLOR_ATTACHMENT29:
7388 case GL_COLOR_ATTACHMENT30:
7389 case GL_COLOR_ATTACHMENT31:
Alexis Hetu1b2f6282015-04-16 16:27:42 -04007390 if(clientVersion < 3)
7391 {
7392 return error(GL_INVALID_ENUM);
7393 }
7394 // fall through
7395 case GL_COLOR_ATTACHMENT0:
7396 if((attachment - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)
7397 {
7398 return error(GL_INVALID_ENUM);
7399 }
7400 framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);
7401 break;
Alexis Hetub027aa92015-01-19 15:56:12 -05007402 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
7403 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
Alexis Hetudcbabfa2015-07-13 13:31:05 -04007404 default:
7405 return error(GL_INVALID_ENUM);
Alexis Hetub027aa92015-01-19 15:56:12 -05007406 }
Nicolas Capens7cc75e12015-01-29 14:44:24 -05007407 }
7408}
Alexis Hetub027aa92015-01-19 15:56:12 -05007409
Nicolas Capenseb195b62015-04-28 17:18:42 -07007410void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04007411{
Nicolas Capensd76b5df2014-10-28 15:54:46 -04007412 if(egl::getClientVersion() == 1)
7413 {
Nicolas Capensa2308052015-04-15 16:50:21 -04007414 return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);
Nicolas Capensd76b5df2014-10-28 15:54:46 -04007415 }
7416
Nicolas Capens4be33702015-04-28 15:13:30 -07007417 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04007418
Nicolas Capensf160b172014-11-26 11:58:23 -05007419 switch(target)
7420 {
7421 case GL_TEXTURE_2D:
7422 case GL_TEXTURE_EXTERNAL_OES:
7423 break;
7424 default:
7425 return error(GL_INVALID_ENUM);
7426 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04007427
Nicolas Capensf160b172014-11-26 11:58:23 -05007428 if(!image)
7429 {
7430 return error(GL_INVALID_OPERATION);
7431 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04007432
Nicolas Capensf160b172014-11-26 11:58:23 -05007433 es2::Context *context = es2::getContext();
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04007434
Nicolas Capensf160b172014-11-26 11:58:23 -05007435 if(context)
7436 {
7437 es2::Texture2D *texture = 0;
Nicolas Capens08e90f02014-11-21 12:49:12 -05007438
Nicolas Capensf160b172014-11-26 11:58:23 -05007439 switch(target)
7440 {
7441 case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
7442 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
Nicolas Capens3713cd42015-06-22 10:41:54 -04007443 default: UNREACHABLE(target);
Nicolas Capensf160b172014-11-26 11:58:23 -05007444 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04007445
Nicolas Capensf160b172014-11-26 11:58:23 -05007446 if(!texture)
7447 {
7448 return error(GL_INVALID_OPERATION);
7449 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04007450
Nicolas Capensf160b172014-11-26 11:58:23 -05007451 egl::Image *glImage = static_cast<egl::Image*>(image);
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04007452
Nicolas Capensf160b172014-11-26 11:58:23 -05007453 texture->setImage(glImage);
7454 }
Nicolas Capense9c5e4f2014-05-28 22:46:43 -04007455}
7456
Nicolas Capenseb195b62015-04-28 17:18:42 -07007457void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
Nicolas Capens7e12ac62014-11-05 17:07:53 -05007458{
Nicolas Capens4be33702015-04-28 15:13:30 -07007459 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
Nicolas Capens7e12ac62014-11-05 17:07:53 -05007460
7461 UNIMPLEMENTED();
7462}
7463
Alexis Hetue7277752015-12-04 11:16:35 -05007464GLboolean IsRenderbufferOES(GLuint renderbuffer)
7465{
7466 return IsRenderbuffer(renderbuffer);
7467}
7468
7469void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
7470{
7471 BindRenderbuffer(target, renderbuffer);
7472}
7473
7474void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
7475{
7476 DeleteRenderbuffers(n, renderbuffers);
7477}
7478
7479void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
7480{
7481 GenRenderbuffers(n, renderbuffers);
7482}
7483
7484void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
7485{
7486 RenderbufferStorage(target, internalformat, width, height);
7487}
7488
7489void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
7490{
7491 GetRenderbufferParameteriv(target, pname, params);
7492}
7493
7494GLboolean IsFramebufferOES(GLuint framebuffer)
7495{
7496 return IsFramebuffer(framebuffer);
7497}
7498
7499void BindFramebufferOES(GLenum target, GLuint framebuffer)
7500{
7501 BindFramebuffer(target, framebuffer);
7502}
7503
7504void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
7505{
7506 DeleteFramebuffers(n, framebuffers);
7507}
7508
7509void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
7510{
7511 GenFramebuffers(n, framebuffers);
7512}
7513
7514GLenum CheckFramebufferStatusOES(GLenum target)
7515{
7516 return CheckFramebufferStatus(target);
7517}
7518
7519void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
7520{
7521 FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
7522}
7523
7524void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
7525{
7526 FramebufferTexture2D(target, attachment, textarget, texture, level);
7527}
7528
7529void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
7530{
7531 GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
7532}
7533
7534void GenerateMipmapOES(GLenum target)
7535{
7536 GenerateMipmap(target);
7537}
7538
Nicolas Capenseb195b62015-04-28 17:18:42 -07007539}
7540
7541extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
John Bauman66b8ab22014-05-06 15:57:45 -04007542{
Nicolas Capensf160b172014-11-26 11:58:23 -05007543 struct Extension
7544 {
7545 const char *name;
7546 __eglMustCastToProperFunctionPointerType address;
7547 };
John Bauman66b8ab22014-05-06 15:57:45 -04007548
Nicolas Capensf160b172014-11-26 11:58:23 -05007549 static const Extension glExtensions[] =
7550 {
Nicolas Capensf6b6d272014-11-03 11:11:08 -05007551 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
7552
Nicolas Capensf160b172014-11-26 11:58:23 -05007553 EXTENSION(glTexImage3DOES),
7554 EXTENSION(glBlitFramebufferANGLE),
Alexis Hetue9233fb2015-02-11 10:31:58 -05007555 EXTENSION(glBlitFramebufferNV),
Nicolas Capensf160b172014-11-26 11:58:23 -05007556 EXTENSION(glRenderbufferStorageMultisampleANGLE),
7557 EXTENSION(glDeleteFencesNV),
7558 EXTENSION(glGenFencesNV),
7559 EXTENSION(glIsFenceNV),
7560 EXTENSION(glTestFenceNV),
7561 EXTENSION(glGetFenceivNV),
7562 EXTENSION(glFinishFenceNV),
7563 EXTENSION(glSetFenceNV),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05007564 EXTENSION(glGetGraphicsResetStatusEXT),
Nicolas Capensf160b172014-11-26 11:58:23 -05007565 EXTENSION(glReadnPixelsEXT),
7566 EXTENSION(glGetnUniformfvEXT),
7567 EXTENSION(glGetnUniformivEXT),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05007568 EXTENSION(glGenQueriesEXT),
Nicolas Capensf160b172014-11-26 11:58:23 -05007569 EXTENSION(glDeleteQueriesEXT),
7570 EXTENSION(glIsQueryEXT),
7571 EXTENSION(glBeginQueryEXT),
7572 EXTENSION(glEndQueryEXT),
7573 EXTENSION(glGetQueryivEXT),
7574 EXTENSION(glGetQueryObjectuivEXT),
7575 EXTENSION(glEGLImageTargetTexture2DOES),
Nicolas Capens7e12ac62014-11-05 17:07:53 -05007576 EXTENSION(glEGLImageTargetRenderbufferStorageOES),
Alexis Hetue8af6d12015-04-17 16:58:45 -04007577 EXTENSION(glDrawElementsInstancedEXT),
7578 EXTENSION(glDrawArraysInstancedEXT),
7579 EXTENSION(glVertexAttribDivisorEXT),
Nicolas Capens0416e5c2015-04-28 15:30:28 -07007580 EXTENSION(glDrawArraysInstancedANGLE),
7581 EXTENSION(glDrawElementsInstancedANGLE),
Alexis Hetub4d557d2015-04-24 17:25:10 -04007582 EXTENSION(glVertexAttribDivisorANGLE),
Alexis Hetue7277752015-12-04 11:16:35 -05007583 EXTENSION(glIsRenderbufferOES),
7584 EXTENSION(glBindRenderbufferOES),
7585 EXTENSION(glDeleteRenderbuffersOES),
7586 EXTENSION(glGenRenderbuffersOES),
7587 EXTENSION(glRenderbufferStorageOES),
7588 EXTENSION(glGetRenderbufferParameterivOES),
7589 EXTENSION(glIsFramebufferOES),
7590 EXTENSION(glBindFramebufferOES),
7591 EXTENSION(glDeleteFramebuffersOES),
7592 EXTENSION(glGenFramebuffersOES),
7593 EXTENSION(glCheckFramebufferStatusOES),
7594 EXTENSION(glFramebufferRenderbufferOES),
7595 EXTENSION(glFramebufferTexture2DOES),
7596 EXTENSION(glGetFramebufferAttachmentParameterivOES),
7597 EXTENSION(glGenerateMipmapOES),
Nicolas Capensf6b6d272014-11-03 11:11:08 -05007598
7599 #undef EXTENSION
Nicolas Capensf160b172014-11-26 11:58:23 -05007600 };
John Bauman66b8ab22014-05-06 15:57:45 -04007601
Nicolas Capensf160b172014-11-26 11:58:23 -05007602 for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
7603 {
7604 if(strcmp(procname, glExtensions[ext].name) == 0)
7605 {
7606 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
7607 }
7608 }
John Bauman66b8ab22014-05-06 15:57:45 -04007609
Nicolas Capensf160b172014-11-26 11:58:23 -05007610 return NULL;
John Bauman66b8ab22014-05-06 15:57:45 -04007611}