blob: 1e5d760972f88fd6495f1c6e040e5587b3a98039 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +000017#include "common/version.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000018
19#include "libGLESv2/main.h"
20#include "libGLESv2/mathutil.h"
21#include "libGLESv2/utilities.h"
22#include "libGLESv2/Buffer.h"
23#include "libGLESv2/Context.h"
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000024#include "libGLESv2/Fence.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000025#include "libGLESv2/Framebuffer.h"
26#include "libGLESv2/Program.h"
27#include "libGLESv2/Renderbuffer.h"
28#include "libGLESv2/Shader.h"
29#include "libGLESv2/Texture.h"
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000030#include "libGLESv2/Query.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000031
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +000032bool validImageSize(GLint level, GLsizei width, GLsizei height)
33{
34 if (level < 0 || width < 0 || height < 0)
35 {
36 return false;
37 }
38
39 if (gl::getContext() && gl::getContext()->supportsNonPower2Texture())
40 {
41 return true;
42 }
43
44 if (level == 0)
45 {
46 return true;
47 }
48
49 if (gl::isPow2(width) && gl::isPow2(height))
50 {
51 return true;
52 }
53
54 return false;
55}
56
daniel@transgaming.com8833dd22012-06-05 19:49:58 +000057// Verify that format/type are one of the combinations from table 3.4.
58bool checkTextureFormatType(GLenum format, GLenum type)
59{
60 // validate <format> by itself (used as secondary key below)
61 switch (format)
62 {
63 case GL_RGBA:
64 case GL_BGRA_EXT:
65 case GL_RGB:
66 case GL_ALPHA:
67 case GL_LUMINANCE:
68 case GL_LUMINANCE_ALPHA:
69 case GL_DEPTH_COMPONENT:
70 case GL_DEPTH_STENCIL_OES:
71 break;
72 default:
73 return error(GL_INVALID_ENUM, false);
74 }
75
76 // invalid <type> -> sets INVALID_ENUM
77 // invalid <format>+<type> combination -> sets INVALID_OPERATION
78 switch (type)
79 {
80 case GL_UNSIGNED_BYTE:
81 switch (format)
82 {
83 case GL_RGBA:
84 case GL_BGRA_EXT:
85 case GL_RGB:
86 case GL_ALPHA:
87 case GL_LUMINANCE:
88 case GL_LUMINANCE_ALPHA:
89 return true;
90 default:
91 return error(GL_INVALID_OPERATION, false);
92 }
93
94 case GL_FLOAT:
95 case GL_HALF_FLOAT_OES:
96 switch (format)
97 {
98 case GL_RGBA:
99 case GL_RGB:
100 case GL_ALPHA:
101 case GL_LUMINANCE:
102 case GL_LUMINANCE_ALPHA:
103 return true;
104 default:
105 return error(GL_INVALID_OPERATION, false);
106 }
107
108 case GL_UNSIGNED_SHORT_4_4_4_4:
109 case GL_UNSIGNED_SHORT_5_5_5_1:
110 switch (format)
111 {
112 case GL_RGBA:
113 return true;
114 default:
115 return error(GL_INVALID_OPERATION, false);
116 }
117
118 case GL_UNSIGNED_SHORT_5_6_5:
119 switch (format)
120 {
121 case GL_RGB:
122 return true;
123 default:
124 return error(GL_INVALID_OPERATION, false);
125 }
126
127 case GL_UNSIGNED_SHORT:
128 case GL_UNSIGNED_INT:
129 switch (format)
130 {
131 case GL_DEPTH_COMPONENT:
132 return true;
133 default:
134 return error(GL_INVALID_OPERATION, false);
135 }
136
137 case GL_UNSIGNED_INT_24_8_OES:
138 switch (format)
139 {
140 case GL_DEPTH_STENCIL_OES:
141 return true;
142 default:
143 return error(GL_INVALID_OPERATION, false);
144 }
145
146 default:
147 return error(GL_INVALID_ENUM, false);
148 }
149}
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000150bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
151 GLint xoffset, GLint yoffset, GLint level, GLenum format,
152 gl::Texture2D *texture)
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000153{
154 if (!texture)
155 {
156 return error(GL_INVALID_OPERATION, false);
157 }
158
daniel@transgaming.com92f49922012-05-09 15:49:19 +0000159 if (compressed != texture->isCompressed(level))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000160 {
161 return error(GL_INVALID_OPERATION, false);
162 }
163
daniel@transgaming.com92f49922012-05-09 15:49:19 +0000164 if (format != GL_NONE && format != texture->getInternalFormat(level))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000165 {
166 return error(GL_INVALID_OPERATION, false);
167 }
168
169 if (compressed)
170 {
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000171 if ((width % 4 != 0 && width != texture->getWidth(0)) ||
172 (height % 4 != 0 && height != texture->getHeight(0)))
173 {
174 return error(GL_INVALID_OPERATION, false);
175 }
176 }
177
178 if (xoffset + width > texture->getWidth(level) ||
179 yoffset + height > texture->getHeight(level))
180 {
181 return error(GL_INVALID_VALUE, false);
182 }
183
184 return true;
185}
186
187bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000188 GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format,
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000189 gl::TextureCubeMap *texture)
190{
191 if (!texture)
192 {
193 return error(GL_INVALID_OPERATION, false);
194 }
195
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000196 if (compressed != texture->isCompressed(target, level))
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000197 {
198 return error(GL_INVALID_OPERATION, false);
199 }
200
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000201 if (format != GL_NONE && format != texture->getInternalFormat(target, level))
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000202 {
203 return error(GL_INVALID_OPERATION, false);
204 }
205
206 if (compressed)
207 {
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000208 if ((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
209 (height % 4 != 0 && height != texture->getHeight(target, 0)))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000210 {
211 return error(GL_INVALID_OPERATION, false);
212 }
213 }
214
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000215 if (xoffset + width > texture->getWidth(target, level) ||
216 yoffset + height > texture->getHeight(target, level))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000217 {
218 return error(GL_INVALID_VALUE, false);
219 }
220
221 return true;
222}
223
daniel@transgaming.comb7915a52011-11-12 03:14:20 +0000224// check for combinations of format and type that are valid for ReadPixels
225bool validReadFormatType(GLenum format, GLenum type)
226{
227 switch (format)
228 {
229 case GL_RGBA:
230 switch (type)
231 {
232 case GL_UNSIGNED_BYTE:
233 break;
234 default:
235 return false;
236 }
237 break;
238 case GL_BGRA_EXT:
239 switch (type)
240 {
241 case GL_UNSIGNED_BYTE:
242 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
243 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
244 break;
245 default:
246 return false;
247 }
248 break;
249 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
250 switch (type)
251 {
252 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
253 break;
254 default:
255 return false;
256 }
257 break;
258 default:
259 return false;
260 }
261 return true;
262}
263
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000264extern "C"
265{
266
267void __stdcall glActiveTexture(GLenum texture)
268{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000269 EVENT("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000270
271 try
272 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000273 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000274
275 if (context)
276 {
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +0000277 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
278 {
279 return error(GL_INVALID_ENUM);
280 }
281
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000282 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000283 }
284 }
285 catch(std::bad_alloc&)
286 {
287 return error(GL_OUT_OF_MEMORY);
288 }
289}
290
291void __stdcall glAttachShader(GLuint program, GLuint shader)
292{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000293 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000294
295 try
296 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000297 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000298
299 if (context)
300 {
301 gl::Program *programObject = context->getProgram(program);
302 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000303
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000304 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000305 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000306 if (context->getShader(program))
307 {
308 return error(GL_INVALID_OPERATION);
309 }
310 else
311 {
312 return error(GL_INVALID_VALUE);
313 }
314 }
315
316 if (!shaderObject)
317 {
318 if (context->getProgram(shader))
319 {
320 return error(GL_INVALID_OPERATION);
321 }
322 else
323 {
324 return error(GL_INVALID_VALUE);
325 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000326 }
327
328 if (!programObject->attachShader(shaderObject))
329 {
330 return error(GL_INVALID_OPERATION);
331 }
332 }
333 }
334 catch(std::bad_alloc&)
335 {
336 return error(GL_OUT_OF_MEMORY);
337 }
338}
339
daniel@transgaming.com86bdb822012-01-20 18:24:39 +0000340void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
341{
342 EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
343
344 try
345 {
346 switch (target)
347 {
348 case GL_ANY_SAMPLES_PASSED_EXT:
349 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
350 break;
351 default:
352 return error(GL_INVALID_ENUM);
353 }
354
355 if (id == 0)
356 {
357 return error(GL_INVALID_OPERATION);
358 }
359
360 gl::Context *context = gl::getNonLostContext();
361
362 if (context)
363 {
364 context->beginQuery(target, id);
365 }
366 }
367 catch(std::bad_alloc&)
368 {
369 return error(GL_OUT_OF_MEMORY);
370 }
371}
372
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000373void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000374{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000375 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000376
377 try
378 {
379 if (index >= gl::MAX_VERTEX_ATTRIBS)
380 {
381 return error(GL_INVALID_VALUE);
382 }
383
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000384 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000385
386 if (context)
387 {
388 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000389
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000390 if (!programObject)
391 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000392 if (context->getShader(program))
393 {
394 return error(GL_INVALID_OPERATION);
395 }
396 else
397 {
398 return error(GL_INVALID_VALUE);
399 }
400 }
401
402 if (strncmp(name, "gl_", 3) == 0)
403 {
404 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000405 }
406
407 programObject->bindAttributeLocation(index, name);
408 }
409 }
410 catch(std::bad_alloc&)
411 {
412 return error(GL_OUT_OF_MEMORY);
413 }
414}
415
416void __stdcall glBindBuffer(GLenum target, GLuint buffer)
417{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000418 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000419
420 try
421 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000422 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000423
424 if (context)
425 {
426 switch (target)
427 {
428 case GL_ARRAY_BUFFER:
429 context->bindArrayBuffer(buffer);
430 return;
431 case GL_ELEMENT_ARRAY_BUFFER:
432 context->bindElementArrayBuffer(buffer);
433 return;
434 default:
435 return error(GL_INVALID_ENUM);
436 }
437 }
438 }
439 catch(std::bad_alloc&)
440 {
441 return error(GL_OUT_OF_MEMORY);
442 }
443}
444
445void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
446{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000447 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000448
449 try
450 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000451 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000452 {
453 return error(GL_INVALID_ENUM);
454 }
455
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000456 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000457
458 if (context)
459 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000460 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
461 {
462 context->bindReadFramebuffer(framebuffer);
463 }
464
465 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
466 {
467 context->bindDrawFramebuffer(framebuffer);
468 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000469 }
470 }
471 catch(std::bad_alloc&)
472 {
473 return error(GL_OUT_OF_MEMORY);
474 }
475}
476
477void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
478{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000479 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000480
481 try
482 {
483 if (target != GL_RENDERBUFFER)
484 {
485 return error(GL_INVALID_ENUM);
486 }
487
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000488 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000489
490 if (context)
491 {
492 context->bindRenderbuffer(renderbuffer);
493 }
494 }
495 catch(std::bad_alloc&)
496 {
497 return error(GL_OUT_OF_MEMORY);
498 }
499}
500
501void __stdcall glBindTexture(GLenum target, GLuint texture)
502{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000503 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000504
505 try
506 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000507 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000508
509 if (context)
510 {
511 gl::Texture *textureObject = context->getTexture(texture);
512
513 if (textureObject && textureObject->getTarget() != target && texture != 0)
514 {
515 return error(GL_INVALID_OPERATION);
516 }
517
518 switch (target)
519 {
520 case GL_TEXTURE_2D:
521 context->bindTexture2D(texture);
522 return;
523 case GL_TEXTURE_CUBE_MAP:
524 context->bindTextureCubeMap(texture);
525 return;
526 default:
527 return error(GL_INVALID_ENUM);
528 }
529 }
530 }
531 catch(std::bad_alloc&)
532 {
533 return error(GL_OUT_OF_MEMORY);
534 }
535}
536
537void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
538{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000539 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000540 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000541
542 try
543 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000544 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000545
546 if (context)
547 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000548 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000549 }
550 }
551 catch(std::bad_alloc&)
552 {
553 return error(GL_OUT_OF_MEMORY);
554 }
555}
556
557void __stdcall glBlendEquation(GLenum mode)
558{
559 glBlendEquationSeparate(mode, mode);
560}
561
562void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
563{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000564 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000565
566 try
567 {
568 switch (modeRGB)
569 {
570 case GL_FUNC_ADD:
571 case GL_FUNC_SUBTRACT:
572 case GL_FUNC_REVERSE_SUBTRACT:
573 break;
574 default:
575 return error(GL_INVALID_ENUM);
576 }
577
578 switch (modeAlpha)
579 {
580 case GL_FUNC_ADD:
581 case GL_FUNC_SUBTRACT:
582 case GL_FUNC_REVERSE_SUBTRACT:
583 break;
584 default:
585 return error(GL_INVALID_ENUM);
586 }
587
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000588 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000589
590 if (context)
591 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000592 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000593 }
594 }
595 catch(std::bad_alloc&)
596 {
597 return error(GL_OUT_OF_MEMORY);
598 }
599}
600
601void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
602{
603 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
604}
605
606void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
607{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000608 EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000609 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000610
611 try
612 {
613 switch (srcRGB)
614 {
615 case GL_ZERO:
616 case GL_ONE:
617 case GL_SRC_COLOR:
618 case GL_ONE_MINUS_SRC_COLOR:
619 case GL_DST_COLOR:
620 case GL_ONE_MINUS_DST_COLOR:
621 case GL_SRC_ALPHA:
622 case GL_ONE_MINUS_SRC_ALPHA:
623 case GL_DST_ALPHA:
624 case GL_ONE_MINUS_DST_ALPHA:
625 case GL_CONSTANT_COLOR:
626 case GL_ONE_MINUS_CONSTANT_COLOR:
627 case GL_CONSTANT_ALPHA:
628 case GL_ONE_MINUS_CONSTANT_ALPHA:
629 case GL_SRC_ALPHA_SATURATE:
630 break;
631 default:
632 return error(GL_INVALID_ENUM);
633 }
634
635 switch (dstRGB)
636 {
637 case GL_ZERO:
638 case GL_ONE:
639 case GL_SRC_COLOR:
640 case GL_ONE_MINUS_SRC_COLOR:
641 case GL_DST_COLOR:
642 case GL_ONE_MINUS_DST_COLOR:
643 case GL_SRC_ALPHA:
644 case GL_ONE_MINUS_SRC_ALPHA:
645 case GL_DST_ALPHA:
646 case GL_ONE_MINUS_DST_ALPHA:
647 case GL_CONSTANT_COLOR:
648 case GL_ONE_MINUS_CONSTANT_COLOR:
649 case GL_CONSTANT_ALPHA:
650 case GL_ONE_MINUS_CONSTANT_ALPHA:
651 break;
652 default:
653 return error(GL_INVALID_ENUM);
654 }
655
656 switch (srcAlpha)
657 {
658 case GL_ZERO:
659 case GL_ONE:
660 case GL_SRC_COLOR:
661 case GL_ONE_MINUS_SRC_COLOR:
662 case GL_DST_COLOR:
663 case GL_ONE_MINUS_DST_COLOR:
664 case GL_SRC_ALPHA:
665 case GL_ONE_MINUS_SRC_ALPHA:
666 case GL_DST_ALPHA:
667 case GL_ONE_MINUS_DST_ALPHA:
668 case GL_CONSTANT_COLOR:
669 case GL_ONE_MINUS_CONSTANT_COLOR:
670 case GL_CONSTANT_ALPHA:
671 case GL_ONE_MINUS_CONSTANT_ALPHA:
672 case GL_SRC_ALPHA_SATURATE:
673 break;
674 default:
675 return error(GL_INVALID_ENUM);
676 }
677
678 switch (dstAlpha)
679 {
680 case GL_ZERO:
681 case GL_ONE:
682 case GL_SRC_COLOR:
683 case GL_ONE_MINUS_SRC_COLOR:
684 case GL_DST_COLOR:
685 case GL_ONE_MINUS_DST_COLOR:
686 case GL_SRC_ALPHA:
687 case GL_ONE_MINUS_SRC_ALPHA:
688 case GL_DST_ALPHA:
689 case GL_ONE_MINUS_DST_ALPHA:
690 case GL_CONSTANT_COLOR:
691 case GL_ONE_MINUS_CONSTANT_COLOR:
692 case GL_CONSTANT_ALPHA:
693 case GL_ONE_MINUS_CONSTANT_ALPHA:
694 break;
695 default:
696 return error(GL_INVALID_ENUM);
697 }
698
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000699 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
700 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
701
702 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
703 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
704
705 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000706 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000707 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
708 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000709 }
710
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000711 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000712
713 if (context)
714 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000715 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000716 }
717 }
718 catch(std::bad_alloc&)
719 {
720 return error(GL_OUT_OF_MEMORY);
721 }
722}
723
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000724void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000725{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000726 EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000727 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000728
729 try
730 {
731 if (size < 0)
732 {
733 return error(GL_INVALID_VALUE);
734 }
735
736 switch (usage)
737 {
738 case GL_STREAM_DRAW:
739 case GL_STATIC_DRAW:
740 case GL_DYNAMIC_DRAW:
741 break;
742 default:
743 return error(GL_INVALID_ENUM);
744 }
745
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000746 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000747
748 if (context)
749 {
750 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000751
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000752 switch (target)
753 {
754 case GL_ARRAY_BUFFER:
755 buffer = context->getArrayBuffer();
756 break;
757 case GL_ELEMENT_ARRAY_BUFFER:
758 buffer = context->getElementArrayBuffer();
759 break;
760 default:
761 return error(GL_INVALID_ENUM);
762 }
763
764 if (!buffer)
765 {
766 return error(GL_INVALID_OPERATION);
767 }
768
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000769 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000770 }
771 }
772 catch(std::bad_alloc&)
773 {
774 return error(GL_OUT_OF_MEMORY);
775 }
776}
777
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000778void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000779{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000780 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000781 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000782
783 try
784 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000785 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000786 {
787 return error(GL_INVALID_VALUE);
788 }
789
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000790 if (data == NULL)
791 {
792 return;
793 }
794
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000795 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000796
797 if (context)
798 {
799 gl::Buffer *buffer;
800
801 switch (target)
802 {
803 case GL_ARRAY_BUFFER:
804 buffer = context->getArrayBuffer();
805 break;
806 case GL_ELEMENT_ARRAY_BUFFER:
807 buffer = context->getElementArrayBuffer();
808 break;
809 default:
810 return error(GL_INVALID_ENUM);
811 }
812
813 if (!buffer)
814 {
815 return error(GL_INVALID_OPERATION);
816 }
817
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000818 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000819 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000820 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000821 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000822
823 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000824 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000825 }
826 catch(std::bad_alloc&)
827 {
828 return error(GL_OUT_OF_MEMORY);
829 }
830}
831
832GLenum __stdcall glCheckFramebufferStatus(GLenum target)
833{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000834 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000835
836 try
837 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000838 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000839 {
840 return error(GL_INVALID_ENUM, 0);
841 }
842
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000843 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000844
845 if (context)
846 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000847 gl::Framebuffer *framebuffer = NULL;
848 if (target == GL_READ_FRAMEBUFFER_ANGLE)
849 {
850 framebuffer = context->getReadFramebuffer();
851 }
852 else
853 {
854 framebuffer = context->getDrawFramebuffer();
855 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000856
857 return framebuffer->completeness();
858 }
859 }
860 catch(std::bad_alloc&)
861 {
862 return error(GL_OUT_OF_MEMORY, 0);
863 }
864
865 return 0;
866}
867
868void __stdcall glClear(GLbitfield mask)
869{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000870 EVENT("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000871
872 try
873 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000874 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000875
876 if (context)
877 {
878 context->clear(mask);
879 }
880 }
881 catch(std::bad_alloc&)
882 {
883 return error(GL_OUT_OF_MEMORY);
884 }
885}
886
887void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
888{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000889 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000890 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000891
892 try
893 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000894 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000895
896 if (context)
897 {
898 context->setClearColor(red, green, blue, alpha);
899 }
900 }
901 catch(std::bad_alloc&)
902 {
903 return error(GL_OUT_OF_MEMORY);
904 }
905}
906
907void __stdcall glClearDepthf(GLclampf depth)
908{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000909 EVENT("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000910
911 try
912 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000913 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000914
915 if (context)
916 {
917 context->setClearDepth(depth);
918 }
919 }
920 catch(std::bad_alloc&)
921 {
922 return error(GL_OUT_OF_MEMORY);
923 }
924}
925
926void __stdcall glClearStencil(GLint s)
927{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000928 EVENT("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000929
930 try
931 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000932 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000933
934 if (context)
935 {
936 context->setClearStencil(s);
937 }
938 }
939 catch(std::bad_alloc&)
940 {
941 return error(GL_OUT_OF_MEMORY);
942 }
943}
944
945void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
946{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000947 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000948 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000949
950 try
951 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000952 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000953
954 if (context)
955 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000956 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000957 }
958 }
959 catch(std::bad_alloc&)
960 {
961 return error(GL_OUT_OF_MEMORY);
962 }
963}
964
965void __stdcall glCompileShader(GLuint shader)
966{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000967 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000968
969 try
970 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000971 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000972
973 if (context)
974 {
975 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000976
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000977 if (!shaderObject)
978 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000979 if (context->getProgram(shader))
980 {
981 return error(GL_INVALID_OPERATION);
982 }
983 else
984 {
985 return error(GL_INVALID_VALUE);
986 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000987 }
988
989 shaderObject->compile();
990 }
991 }
992 catch(std::bad_alloc&)
993 {
994 return error(GL_OUT_OF_MEMORY);
995 }
996}
997
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000998void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
999 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001000{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001001 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001002 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001003 target, level, internalformat, width, height, border, imageSize, data);
1004
1005 try
1006 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001007 if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001008 {
1009 return error(GL_INVALID_VALUE);
1010 }
1011
daniel@transgaming.com01868132010-08-24 19:21:17 +00001012 switch (internalformat)
1013 {
1014 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1015 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001016 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1017 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001018 break;
1019 default:
1020 return error(GL_INVALID_ENUM);
1021 }
1022
1023 if (border != 0)
1024 {
1025 return error(GL_INVALID_VALUE);
1026 }
1027
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001028 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001029
1030 if (context)
1031 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001032 if (level > context->getMaximumTextureLevel())
1033 {
1034 return error(GL_INVALID_VALUE);
1035 }
1036
1037 switch (target)
1038 {
1039 case GL_TEXTURE_2D:
1040 if (width > (context->getMaximumTextureDimension() >> level) ||
1041 height > (context->getMaximumTextureDimension() >> level))
1042 {
1043 return error(GL_INVALID_VALUE);
1044 }
1045 break;
1046 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1047 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1048 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1049 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1050 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1051 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1052 if (width != height)
1053 {
1054 return error(GL_INVALID_VALUE);
1055 }
1056
1057 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1058 height > (context->getMaximumCubeTextureDimension() >> level))
1059 {
1060 return error(GL_INVALID_VALUE);
1061 }
1062 break;
1063 default:
1064 return error(GL_INVALID_ENUM);
1065 }
1066
gman@chromium.org50c526d2011-08-10 05:19:44 +00001067 switch (internalformat) {
1068 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1069 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1070 if (!context->supportsDXT1Textures())
1071 {
1072 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1073 }
1074 break;
1075 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1076 if (!context->supportsDXT3Textures())
1077 {
1078 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1079 }
1080 break;
1081 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1082 if (!context->supportsDXT5Textures())
1083 {
1084 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1085 }
1086 break;
1087 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001088 }
1089
1090 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
1091 {
1092 return error(GL_INVALID_VALUE);
1093 }
1094
1095 if (target == GL_TEXTURE_2D)
1096 {
1097 gl::Texture2D *texture = context->getTexture2D();
1098
1099 if (!texture)
1100 {
1101 return error(GL_INVALID_OPERATION);
1102 }
1103
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001104 if (texture->isImmutable())
1105 {
1106 return error(GL_INVALID_OPERATION);
1107 }
1108
daniel@transgaming.com01868132010-08-24 19:21:17 +00001109 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
1110 }
1111 else
1112 {
1113 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1114
1115 if (!texture)
1116 {
1117 return error(GL_INVALID_OPERATION);
1118 }
1119
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001120 if (texture->isImmutable())
1121 {
1122 return error(GL_INVALID_OPERATION);
1123 }
1124
daniel@transgaming.com01868132010-08-24 19:21:17 +00001125 switch (target)
1126 {
1127 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1128 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1129 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1130 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1131 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1132 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1133 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
1134 break;
1135 default: UNREACHABLE();
1136 }
1137 }
1138 }
1139
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001140 }
1141 catch(std::bad_alloc&)
1142 {
1143 return error(GL_OUT_OF_MEMORY);
1144 }
1145}
1146
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001147void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
1148 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001149{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001150 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001151 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001152 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001153 target, level, xoffset, yoffset, width, height, format, imageSize, data);
1154
1155 try
1156 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00001157 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +00001158 {
1159 return error(GL_INVALID_ENUM);
1160 }
1161
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001162 if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001163 {
1164 return error(GL_INVALID_VALUE);
1165 }
1166
daniel@transgaming.com01868132010-08-24 19:21:17 +00001167 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001168 {
daniel@transgaming.com01868132010-08-24 19:21:17 +00001169 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1170 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001171 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1172 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001173 break;
1174 default:
1175 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +00001176 }
1177
daniel@transgaming.com01868132010-08-24 19:21:17 +00001178 if (width == 0 || height == 0 || data == NULL)
1179 {
1180 return;
1181 }
1182
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001183 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001184
1185 if (context)
1186 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001187 if (level > context->getMaximumTextureLevel())
1188 {
1189 return error(GL_INVALID_VALUE);
1190 }
1191
gman@chromium.org50c526d2011-08-10 05:19:44 +00001192 switch (format) {
1193 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1194 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1195 if (!context->supportsDXT1Textures())
1196 {
1197 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1198 }
1199 break;
1200 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1201 if (!context->supportsDXT3Textures())
1202 {
1203 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1204 }
1205 break;
1206 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1207 if (!context->supportsDXT5Textures())
1208 {
1209 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1210 }
1211 break;
1212 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001213 }
1214
1215 if (imageSize != gl::ComputeCompressedSize(width, height, format))
1216 {
1217 return error(GL_INVALID_VALUE);
1218 }
1219
1220 if (xoffset % 4 != 0 || yoffset % 4 != 0)
1221 {
1222 return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
gman@chromium.org50c526d2011-08-10 05:19:44 +00001223 // does not exist unless DXT textures are supported.
daniel@transgaming.com01868132010-08-24 19:21:17 +00001224 }
1225
1226 if (target == GL_TEXTURE_2D)
1227 {
1228 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001229 if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001230 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001231 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
daniel@transgaming.com01868132010-08-24 19:21:17 +00001232 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001233 }
1234 else if (gl::IsCubemapTextureTarget(target))
1235 {
1236 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00001237 if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, texture))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001238 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001239 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
daniel@transgaming.com01868132010-08-24 19:21:17 +00001240 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001241 }
1242 else
1243 {
1244 UNREACHABLE();
1245 }
1246 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001247 }
1248 catch(std::bad_alloc&)
1249 {
1250 return error(GL_OUT_OF_MEMORY);
1251 }
1252}
1253
1254void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1255{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001256 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001257 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001258 target, level, internalformat, x, y, width, height, border);
1259
1260 try
1261 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001262 if (!validImageSize(level, width, height))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001263 {
1264 return error(GL_INVALID_VALUE);
1265 }
1266
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001267 if (border != 0)
1268 {
1269 return error(GL_INVALID_VALUE);
1270 }
1271
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001272 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001273
1274 if (context)
1275 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00001276 if (level > context->getMaximumTextureLevel())
1277 {
1278 return error(GL_INVALID_VALUE);
1279 }
1280
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001281 switch (target)
1282 {
1283 case GL_TEXTURE_2D:
1284 if (width > (context->getMaximumTextureDimension() >> level) ||
1285 height > (context->getMaximumTextureDimension() >> level))
1286 {
1287 return error(GL_INVALID_VALUE);
1288 }
1289 break;
1290 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1291 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1292 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1293 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1294 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1295 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1296 if (width != height)
1297 {
1298 return error(GL_INVALID_VALUE);
1299 }
1300
1301 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1302 height > (context->getMaximumCubeTextureDimension() >> level))
1303 {
1304 return error(GL_INVALID_VALUE);
1305 }
1306 break;
1307 default:
1308 return error(GL_INVALID_ENUM);
1309 }
1310
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001311 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001312
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001313 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1314 {
1315 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1316 }
1317
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001318 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1319 {
1320 return error(GL_INVALID_OPERATION);
1321 }
1322
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001323 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001324 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001325
1326 // [OpenGL ES 2.0.24] table 3.9
1327 switch (internalformat)
1328 {
1329 case GL_ALPHA:
1330 if (colorbufferFormat != GL_ALPHA &&
1331 colorbufferFormat != GL_RGBA &&
1332 colorbufferFormat != GL_RGBA4 &&
1333 colorbufferFormat != GL_RGB5_A1 &&
1334 colorbufferFormat != GL_RGBA8_OES)
1335 {
1336 return error(GL_INVALID_OPERATION);
1337 }
1338 break;
1339 case GL_LUMINANCE:
1340 case GL_RGB:
1341 if (colorbufferFormat != GL_RGB &&
1342 colorbufferFormat != GL_RGB565 &&
1343 colorbufferFormat != GL_RGB8_OES &&
1344 colorbufferFormat != GL_RGBA &&
1345 colorbufferFormat != GL_RGBA4 &&
1346 colorbufferFormat != GL_RGB5_A1 &&
1347 colorbufferFormat != GL_RGBA8_OES)
1348 {
1349 return error(GL_INVALID_OPERATION);
1350 }
1351 break;
1352 case GL_LUMINANCE_ALPHA:
1353 case GL_RGBA:
1354 if (colorbufferFormat != GL_RGBA &&
1355 colorbufferFormat != GL_RGBA4 &&
1356 colorbufferFormat != GL_RGB5_A1 &&
1357 colorbufferFormat != GL_RGBA8_OES)
1358 {
1359 return error(GL_INVALID_OPERATION);
1360 }
1361 break;
1362 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1363 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001364 if (context->supportsDXT1Textures())
1365 {
1366 return error(GL_INVALID_OPERATION);
1367 }
1368 else
1369 {
1370 return error(GL_INVALID_ENUM);
1371 }
1372 break;
1373 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1374 if (context->supportsDXT3Textures())
1375 {
1376 return error(GL_INVALID_OPERATION);
1377 }
1378 else
1379 {
1380 return error(GL_INVALID_ENUM);
1381 }
1382 break;
1383 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1384 if (context->supportsDXT5Textures())
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001385 {
1386 return error(GL_INVALID_OPERATION);
1387 }
1388 else
1389 {
1390 return error(GL_INVALID_ENUM);
1391 }
1392 break;
daniel@transgaming.com0c854682012-05-31 01:14:11 +00001393 case GL_DEPTH_COMPONENT:
1394 case GL_DEPTH_COMPONENT16:
1395 case GL_DEPTH_COMPONENT32_OES:
1396 case GL_DEPTH_STENCIL_OES:
1397 case GL_DEPTH24_STENCIL8_OES:
1398 if (context->supportsDepthTextures())
1399 {
1400 return error(GL_INVALID_OPERATION);
1401 }
1402 else
1403 {
1404 return error(GL_INVALID_ENUM);
1405 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001406 default:
1407 return error(GL_INVALID_ENUM);
1408 }
1409
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001410 if (target == GL_TEXTURE_2D)
1411 {
1412 gl::Texture2D *texture = context->getTexture2D();
1413
1414 if (!texture)
1415 {
1416 return error(GL_INVALID_OPERATION);
1417 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001418
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001419 if (texture->isImmutable())
1420 {
1421 return error(GL_INVALID_OPERATION);
1422 }
1423
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001424 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001425 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001426 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001427 {
1428 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1429
1430 if (!texture)
1431 {
1432 return error(GL_INVALID_OPERATION);
1433 }
1434
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001435 if (texture->isImmutable())
1436 {
1437 return error(GL_INVALID_OPERATION);
1438 }
1439
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001440 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001441 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001442 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001443 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001444 }
1445 catch(std::bad_alloc&)
1446 {
1447 return error(GL_OUT_OF_MEMORY);
1448 }
1449}
1450
1451void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1452{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001453 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001454 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001455 target, level, xoffset, yoffset, x, y, width, height);
1456
1457 try
1458 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00001459 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001460 {
1461 return error(GL_INVALID_ENUM);
1462 }
1463
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001464 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001465 {
1466 return error(GL_INVALID_VALUE);
1467 }
1468
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001469 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1470 {
1471 return error(GL_INVALID_VALUE);
1472 }
1473
1474 if (width == 0 || height == 0)
1475 {
1476 return;
1477 }
1478
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001479 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001480
1481 if (context)
1482 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001483 if (level > context->getMaximumTextureLevel())
1484 {
1485 return error(GL_INVALID_VALUE);
1486 }
1487
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001488 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001489
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001490 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1491 {
1492 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1493 }
1494
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001495 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1496 {
1497 return error(GL_INVALID_OPERATION);
1498 }
1499
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001500 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001501 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001502 gl::Texture *texture = NULL;
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001503 GLenum textureFormat = GL_RGBA;
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001504
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001505 if (target == GL_TEXTURE_2D)
1506 {
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001507 gl::Texture2D *tex2d = context->getTexture2D();
1508
1509 if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, tex2d))
1510 {
1511 return; // error already registered by validateSubImageParams
1512 }
daniel@transgaming.com92f49922012-05-09 15:49:19 +00001513 textureFormat = tex2d->getInternalFormat(level);
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001514 texture = tex2d;
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001515 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001516 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001517 {
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001518 gl::TextureCubeMap *texcube = context->getTextureCubeMap();
1519
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00001520 if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, texcube))
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001521 {
1522 return; // error already registered by validateSubImageParams
1523 }
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00001524 textureFormat = texcube->getInternalFormat(target, level);
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001525 texture = texcube;
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001526 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001527 else UNREACHABLE();
1528
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001529 // [OpenGL ES 2.0.24] table 3.9
1530 switch (textureFormat)
1531 {
1532 case GL_ALPHA:
1533 if (colorbufferFormat != GL_ALPHA &&
1534 colorbufferFormat != GL_RGBA &&
1535 colorbufferFormat != GL_RGBA4 &&
1536 colorbufferFormat != GL_RGB5_A1 &&
1537 colorbufferFormat != GL_RGBA8_OES)
1538 {
1539 return error(GL_INVALID_OPERATION);
1540 }
1541 break;
1542 case GL_LUMINANCE:
1543 case GL_RGB:
1544 if (colorbufferFormat != GL_RGB &&
1545 colorbufferFormat != GL_RGB565 &&
1546 colorbufferFormat != GL_RGB8_OES &&
1547 colorbufferFormat != GL_RGBA &&
1548 colorbufferFormat != GL_RGBA4 &&
1549 colorbufferFormat != GL_RGB5_A1 &&
1550 colorbufferFormat != GL_RGBA8_OES)
1551 {
1552 return error(GL_INVALID_OPERATION);
1553 }
1554 break;
1555 case GL_LUMINANCE_ALPHA:
1556 case GL_RGBA:
1557 if (colorbufferFormat != GL_RGBA &&
1558 colorbufferFormat != GL_RGBA4 &&
1559 colorbufferFormat != GL_RGB5_A1 &&
1560 colorbufferFormat != GL_RGBA8_OES)
1561 {
1562 return error(GL_INVALID_OPERATION);
1563 }
1564 break;
1565 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1566 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001567 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1568 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001569 return error(GL_INVALID_OPERATION);
daniel@transgaming.com0c854682012-05-31 01:14:11 +00001570 case GL_DEPTH_COMPONENT:
1571 case GL_DEPTH_STENCIL_OES:
1572 return error(GL_INVALID_OPERATION);
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001573 default:
1574 return error(GL_INVALID_OPERATION);
1575 }
1576
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001577 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001578 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001579 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001580
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001581 catch(std::bad_alloc&)
1582 {
1583 return error(GL_OUT_OF_MEMORY);
1584 }
1585}
1586
1587GLuint __stdcall glCreateProgram(void)
1588{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001589 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001590
1591 try
1592 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001593 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001594
1595 if (context)
1596 {
1597 return context->createProgram();
1598 }
1599 }
1600 catch(std::bad_alloc&)
1601 {
1602 return error(GL_OUT_OF_MEMORY, 0);
1603 }
1604
1605 return 0;
1606}
1607
1608GLuint __stdcall glCreateShader(GLenum type)
1609{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001610 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001611
1612 try
1613 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001614 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001615
1616 if (context)
1617 {
1618 switch (type)
1619 {
1620 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001621 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001622 return context->createShader(type);
1623 default:
1624 return error(GL_INVALID_ENUM, 0);
1625 }
1626 }
1627 }
1628 catch(std::bad_alloc&)
1629 {
1630 return error(GL_OUT_OF_MEMORY, 0);
1631 }
1632
1633 return 0;
1634}
1635
1636void __stdcall glCullFace(GLenum mode)
1637{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001638 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001639
1640 try
1641 {
1642 switch (mode)
1643 {
1644 case GL_FRONT:
1645 case GL_BACK:
1646 case GL_FRONT_AND_BACK:
1647 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001648 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001649
1650 if (context)
1651 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001652 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001653 }
1654 }
1655 break;
1656 default:
1657 return error(GL_INVALID_ENUM);
1658 }
1659 }
1660 catch(std::bad_alloc&)
1661 {
1662 return error(GL_OUT_OF_MEMORY);
1663 }
1664}
1665
1666void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1667{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001668 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001669
1670 try
1671 {
1672 if (n < 0)
1673 {
1674 return error(GL_INVALID_VALUE);
1675 }
1676
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001677 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001678
1679 if (context)
1680 {
1681 for (int i = 0; i < n; i++)
1682 {
1683 context->deleteBuffer(buffers[i]);
1684 }
1685 }
1686 }
1687 catch(std::bad_alloc&)
1688 {
1689 return error(GL_OUT_OF_MEMORY);
1690 }
1691}
1692
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001693void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1694{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001695 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001696
1697 try
1698 {
1699 if (n < 0)
1700 {
1701 return error(GL_INVALID_VALUE);
1702 }
1703
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001704 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001705
1706 if (context)
1707 {
1708 for (int i = 0; i < n; i++)
1709 {
1710 context->deleteFence(fences[i]);
1711 }
1712 }
1713 }
1714 catch(std::bad_alloc&)
1715 {
1716 return error(GL_OUT_OF_MEMORY);
1717 }
1718}
1719
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001720void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1721{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001722 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001723
1724 try
1725 {
1726 if (n < 0)
1727 {
1728 return error(GL_INVALID_VALUE);
1729 }
1730
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001731 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001732
1733 if (context)
1734 {
1735 for (int i = 0; i < n; i++)
1736 {
1737 if (framebuffers[i] != 0)
1738 {
1739 context->deleteFramebuffer(framebuffers[i]);
1740 }
1741 }
1742 }
1743 }
1744 catch(std::bad_alloc&)
1745 {
1746 return error(GL_OUT_OF_MEMORY);
1747 }
1748}
1749
1750void __stdcall glDeleteProgram(GLuint program)
1751{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001752 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001753
1754 try
1755 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001756 if (program == 0)
1757 {
1758 return;
1759 }
1760
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001761 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001762
1763 if (context)
1764 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001765 if (!context->getProgram(program))
1766 {
1767 if(context->getShader(program))
1768 {
1769 return error(GL_INVALID_OPERATION);
1770 }
1771 else
1772 {
1773 return error(GL_INVALID_VALUE);
1774 }
1775 }
1776
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001777 context->deleteProgram(program);
1778 }
1779 }
1780 catch(std::bad_alloc&)
1781 {
1782 return error(GL_OUT_OF_MEMORY);
1783 }
1784}
1785
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00001786void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
1787{
1788 EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
1789
1790 try
1791 {
1792 if (n < 0)
1793 {
1794 return error(GL_INVALID_VALUE);
1795 }
1796
1797 gl::Context *context = gl::getNonLostContext();
1798
1799 if (context)
1800 {
1801 for (int i = 0; i < n; i++)
1802 {
1803 context->deleteQuery(ids[i]);
1804 }
1805 }
1806 }
1807 catch(std::bad_alloc&)
1808 {
1809 return error(GL_OUT_OF_MEMORY);
1810 }
1811}
1812
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001813void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1814{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001815 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001816
1817 try
1818 {
1819 if (n < 0)
1820 {
1821 return error(GL_INVALID_VALUE);
1822 }
1823
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001824 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001825
1826 if (context)
1827 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001828 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001829 {
1830 context->deleteRenderbuffer(renderbuffers[i]);
1831 }
1832 }
1833 }
1834 catch(std::bad_alloc&)
1835 {
1836 return error(GL_OUT_OF_MEMORY);
1837 }
1838}
1839
1840void __stdcall glDeleteShader(GLuint shader)
1841{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001842 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001843
1844 try
1845 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001846 if (shader == 0)
1847 {
1848 return;
1849 }
1850
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001851 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001852
1853 if (context)
1854 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001855 if (!context->getShader(shader))
1856 {
1857 if(context->getProgram(shader))
1858 {
1859 return error(GL_INVALID_OPERATION);
1860 }
1861 else
1862 {
1863 return error(GL_INVALID_VALUE);
1864 }
1865 }
1866
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001867 context->deleteShader(shader);
1868 }
1869 }
1870 catch(std::bad_alloc&)
1871 {
1872 return error(GL_OUT_OF_MEMORY);
1873 }
1874}
1875
1876void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1877{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001878 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001879
1880 try
1881 {
1882 if (n < 0)
1883 {
1884 return error(GL_INVALID_VALUE);
1885 }
1886
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001887 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001888
1889 if (context)
1890 {
1891 for (int i = 0; i < n; i++)
1892 {
1893 if (textures[i] != 0)
1894 {
1895 context->deleteTexture(textures[i]);
1896 }
1897 }
1898 }
1899 }
1900 catch(std::bad_alloc&)
1901 {
1902 return error(GL_OUT_OF_MEMORY);
1903 }
1904}
1905
1906void __stdcall glDepthFunc(GLenum func)
1907{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001908 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001909
1910 try
1911 {
1912 switch (func)
1913 {
1914 case GL_NEVER:
1915 case GL_ALWAYS:
1916 case GL_LESS:
1917 case GL_LEQUAL:
1918 case GL_EQUAL:
1919 case GL_GREATER:
1920 case GL_GEQUAL:
1921 case GL_NOTEQUAL:
1922 break;
1923 default:
1924 return error(GL_INVALID_ENUM);
1925 }
1926
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001927 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001928
1929 if (context)
1930 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001931 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001932 }
1933 }
1934 catch(std::bad_alloc&)
1935 {
1936 return error(GL_OUT_OF_MEMORY);
1937 }
1938}
1939
1940void __stdcall glDepthMask(GLboolean flag)
1941{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001942 EVENT("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001943
1944 try
1945 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001946 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001947
1948 if (context)
1949 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001950 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001951 }
1952 }
1953 catch(std::bad_alloc&)
1954 {
1955 return error(GL_OUT_OF_MEMORY);
1956 }
1957}
1958
1959void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1960{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001961 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001962
1963 try
1964 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001965 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001966
1967 if (context)
1968 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001969 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001970 }
1971 }
1972 catch(std::bad_alloc&)
1973 {
1974 return error(GL_OUT_OF_MEMORY);
1975 }
1976}
1977
1978void __stdcall glDetachShader(GLuint program, GLuint shader)
1979{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001980 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001981
1982 try
1983 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001984 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001985
1986 if (context)
1987 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001988
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001989 gl::Program *programObject = context->getProgram(program);
1990 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001991
1992 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001993 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001994 gl::Shader *shaderByProgramHandle;
1995 shaderByProgramHandle = context->getShader(program);
1996 if (!shaderByProgramHandle)
1997 {
1998 return error(GL_INVALID_VALUE);
1999 }
2000 else
2001 {
2002 return error(GL_INVALID_OPERATION);
2003 }
2004 }
2005
2006 if (!shaderObject)
2007 {
2008 gl::Program *programByShaderHandle = context->getProgram(shader);
2009 if (!programByShaderHandle)
2010 {
2011 return error(GL_INVALID_VALUE);
2012 }
2013 else
2014 {
2015 return error(GL_INVALID_OPERATION);
2016 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002017 }
2018
2019 if (!programObject->detachShader(shaderObject))
2020 {
2021 return error(GL_INVALID_OPERATION);
2022 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002023 }
2024 }
2025 catch(std::bad_alloc&)
2026 {
2027 return error(GL_OUT_OF_MEMORY);
2028 }
2029}
2030
2031void __stdcall glDisable(GLenum cap)
2032{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002033 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002034
2035 try
2036 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002037 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002038
2039 if (context)
2040 {
2041 switch (cap)
2042 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002043 case GL_CULL_FACE: context->setCullFace(false); break;
2044 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
2045 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
2046 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
2047 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
2048 case GL_STENCIL_TEST: context->setStencilTest(false); break;
2049 case GL_DEPTH_TEST: context->setDepthTest(false); break;
2050 case GL_BLEND: context->setBlend(false); break;
2051 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002052 default:
2053 return error(GL_INVALID_ENUM);
2054 }
2055 }
2056 }
2057 catch(std::bad_alloc&)
2058 {
2059 return error(GL_OUT_OF_MEMORY);
2060 }
2061}
2062
2063void __stdcall glDisableVertexAttribArray(GLuint index)
2064{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002065 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002066
2067 try
2068 {
2069 if (index >= gl::MAX_VERTEX_ATTRIBS)
2070 {
2071 return error(GL_INVALID_VALUE);
2072 }
2073
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002074 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002075
2076 if (context)
2077 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002078 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002079 }
2080 }
2081 catch(std::bad_alloc&)
2082 {
2083 return error(GL_OUT_OF_MEMORY);
2084 }
2085}
2086
2087void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
2088{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002089 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002090
2091 try
2092 {
2093 if (count < 0 || first < 0)
2094 {
2095 return error(GL_INVALID_VALUE);
2096 }
2097
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002098 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002099
2100 if (context)
2101 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002102 context->drawArrays(mode, first, count, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002103 }
2104 }
2105 catch(std::bad_alloc&)
2106 {
2107 return error(GL_OUT_OF_MEMORY);
2108 }
2109}
2110
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002111void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
2112{
2113 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
2114
2115 try
2116 {
2117 if (count < 0 || first < 0 || primcount < 0)
2118 {
2119 return error(GL_INVALID_VALUE);
2120 }
2121
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002122 if (primcount > 0)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002123 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002124 gl::Context *context = gl::getNonLostContext();
2125
2126 if (context)
2127 {
2128 context->drawArrays(mode, first, count, primcount);
2129 }
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002130 }
2131 }
2132 catch(std::bad_alloc&)
2133 {
2134 return error(GL_OUT_OF_MEMORY);
2135 }
2136}
2137
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002138void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002139{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002140 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002141 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002142
2143 try
2144 {
2145 if (count < 0)
2146 {
2147 return error(GL_INVALID_VALUE);
2148 }
2149
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002150 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002151
2152 if (context)
2153 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002154 switch (type)
2155 {
2156 case GL_UNSIGNED_BYTE:
2157 case GL_UNSIGNED_SHORT:
2158 break;
2159 case GL_UNSIGNED_INT:
2160 if (!context->supports32bitIndices())
2161 {
2162 return error(GL_INVALID_ENUM);
2163 }
2164 break;
2165 default:
2166 return error(GL_INVALID_ENUM);
2167 }
2168
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002169 context->drawElements(mode, count, type, indices, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002170 }
2171 }
2172 catch(std::bad_alloc&)
2173 {
2174 return error(GL_OUT_OF_MEMORY);
2175 }
2176}
2177
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002178void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)
2179{
2180 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)",
2181 mode, count, type, indices, primcount);
2182
2183 try
2184 {
2185 if (count < 0 || primcount < 0)
2186 {
2187 return error(GL_INVALID_VALUE);
2188 }
2189
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002190 if (primcount > 0)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002191 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002192 gl::Context *context = gl::getNonLostContext();
2193
2194 if (context)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002195 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002196 switch (type)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002197 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002198 case GL_UNSIGNED_BYTE:
2199 case GL_UNSIGNED_SHORT:
2200 break;
2201 case GL_UNSIGNED_INT:
2202 if (!context->supports32bitIndices())
2203 {
2204 return error(GL_INVALID_ENUM);
2205 }
2206 break;
2207 default:
2208 return error(GL_INVALID_ENUM);
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002209 }
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002210
2211 context->drawElements(mode, count, type, indices, primcount);
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002212 }
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002213 }
2214 }
2215 catch(std::bad_alloc&)
2216 {
2217 return error(GL_OUT_OF_MEMORY);
2218 }
2219}
2220
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002221void __stdcall glEnable(GLenum cap)
2222{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002223 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002224
2225 try
2226 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002227 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002228
2229 if (context)
2230 {
2231 switch (cap)
2232 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002233 case GL_CULL_FACE: context->setCullFace(true); break;
2234 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
2235 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
2236 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
2237 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
2238 case GL_STENCIL_TEST: context->setStencilTest(true); break;
2239 case GL_DEPTH_TEST: context->setDepthTest(true); break;
2240 case GL_BLEND: context->setBlend(true); break;
2241 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002242 default:
2243 return error(GL_INVALID_ENUM);
2244 }
2245 }
2246 }
2247 catch(std::bad_alloc&)
2248 {
2249 return error(GL_OUT_OF_MEMORY);
2250 }
2251}
2252
2253void __stdcall glEnableVertexAttribArray(GLuint index)
2254{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002255 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002256
2257 try
2258 {
2259 if (index >= gl::MAX_VERTEX_ATTRIBS)
2260 {
2261 return error(GL_INVALID_VALUE);
2262 }
2263
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002264 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002265
2266 if (context)
2267 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002268 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002269 }
2270 }
2271 catch(std::bad_alloc&)
2272 {
2273 return error(GL_OUT_OF_MEMORY);
2274 }
2275}
2276
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00002277void __stdcall glEndQueryEXT(GLenum target)
2278{
2279 EVENT("GLenum target = 0x%X)", target);
2280
2281 try
2282 {
2283 switch (target)
2284 {
2285 case GL_ANY_SAMPLES_PASSED_EXT:
2286 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
2287 break;
2288 default:
2289 return error(GL_INVALID_ENUM);
2290 }
2291
2292 gl::Context *context = gl::getNonLostContext();
2293
2294 if (context)
2295 {
2296 context->endQuery(target);
2297 }
2298 }
2299 catch(std::bad_alloc&)
2300 {
2301 return error(GL_OUT_OF_MEMORY);
2302 }
2303}
2304
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002305void __stdcall glFinishFenceNV(GLuint fence)
2306{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002307 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002308
2309 try
2310 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002311 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002312
2313 if (context)
2314 {
2315 gl::Fence* fenceObject = context->getFence(fence);
2316
2317 if (fenceObject == NULL)
2318 {
2319 return error(GL_INVALID_OPERATION);
2320 }
2321
2322 fenceObject->finishFence();
2323 }
2324 }
2325 catch(std::bad_alloc&)
2326 {
2327 return error(GL_OUT_OF_MEMORY);
2328 }
2329}
2330
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002331void __stdcall glFinish(void)
2332{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002333 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002334
2335 try
2336 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002337 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002338
2339 if (context)
2340 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002341 context->sync(true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002342 }
2343 }
2344 catch(std::bad_alloc&)
2345 {
2346 return error(GL_OUT_OF_MEMORY);
2347 }
2348}
2349
2350void __stdcall glFlush(void)
2351{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002352 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002353
2354 try
2355 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002356 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002357
2358 if (context)
2359 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002360 context->sync(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002361 }
2362 }
2363 catch(std::bad_alloc&)
2364 {
2365 return error(GL_OUT_OF_MEMORY);
2366 }
2367}
2368
2369void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2370{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002371 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002372 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002373
2374 try
2375 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002376 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002377 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002378 {
2379 return error(GL_INVALID_ENUM);
2380 }
2381
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002382 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002383
2384 if (context)
2385 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002386 gl::Framebuffer *framebuffer = NULL;
2387 GLuint framebufferHandle = 0;
2388 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2389 {
2390 framebuffer = context->getReadFramebuffer();
2391 framebufferHandle = context->getReadFramebufferHandle();
2392 }
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002393 else
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002394 {
2395 framebuffer = context->getDrawFramebuffer();
2396 framebufferHandle = context->getDrawFramebufferHandle();
2397 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002398
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002399 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002400 {
2401 return error(GL_INVALID_OPERATION);
2402 }
2403
2404 switch (attachment)
2405 {
2406 case GL_COLOR_ATTACHMENT0:
2407 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2408 break;
2409 case GL_DEPTH_ATTACHMENT:
2410 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2411 break;
2412 case GL_STENCIL_ATTACHMENT:
2413 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2414 break;
2415 default:
2416 return error(GL_INVALID_ENUM);
2417 }
2418 }
2419 }
2420 catch(std::bad_alloc&)
2421 {
2422 return error(GL_OUT_OF_MEMORY);
2423 }
2424}
2425
2426void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2427{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002428 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002429 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002430
2431 try
2432 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002433 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002434 {
2435 return error(GL_INVALID_ENUM);
2436 }
2437
2438 switch (attachment)
2439 {
2440 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002441 case GL_DEPTH_ATTACHMENT:
2442 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002443 break;
2444 default:
2445 return error(GL_INVALID_ENUM);
2446 }
2447
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002448 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002449
2450 if (context)
2451 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002452 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002453 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002454 textarget = GL_NONE;
2455 }
2456 else
2457 {
2458 gl::Texture *tex = context->getTexture(texture);
2459
2460 if (tex == NULL)
2461 {
2462 return error(GL_INVALID_OPERATION);
2463 }
2464
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002465 switch (textarget)
2466 {
2467 case GL_TEXTURE_2D:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002468 {
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002469 if (tex->getTarget() != GL_TEXTURE_2D)
2470 {
2471 return error(GL_INVALID_OPERATION);
2472 }
2473 gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
daniel@transgaming.com92f49922012-05-09 15:49:19 +00002474 if (tex2d->isCompressed(0))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002475 {
2476 return error(GL_INVALID_OPERATION);
2477 }
2478 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002479 }
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002480
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002481 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002482 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002483 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002484 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002485 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002486 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002487 {
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002488 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2489 {
2490 return error(GL_INVALID_OPERATION);
2491 }
2492 gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00002493 if (texcube->isCompressed(textarget, level))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002494 {
2495 return error(GL_INVALID_OPERATION);
2496 }
2497 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002498 }
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002499
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002500 default:
2501 return error(GL_INVALID_ENUM);
2502 }
2503
2504 if (level != 0)
2505 {
2506 return error(GL_INVALID_VALUE);
2507 }
2508 }
2509
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002510 gl::Framebuffer *framebuffer = NULL;
2511 GLuint framebufferHandle = 0;
2512 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2513 {
2514 framebuffer = context->getReadFramebuffer();
2515 framebufferHandle = context->getReadFramebufferHandle();
2516 }
2517 else
2518 {
2519 framebuffer = context->getDrawFramebuffer();
2520 framebufferHandle = context->getDrawFramebufferHandle();
2521 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002522
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002523 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002524 {
2525 return error(GL_INVALID_OPERATION);
2526 }
2527
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002528 switch (attachment)
2529 {
2530 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2531 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2532 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2533 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002534 }
2535 }
2536 catch(std::bad_alloc&)
2537 {
2538 return error(GL_OUT_OF_MEMORY);
2539 }
2540}
2541
2542void __stdcall glFrontFace(GLenum mode)
2543{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002544 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002545
2546 try
2547 {
2548 switch (mode)
2549 {
2550 case GL_CW:
2551 case GL_CCW:
2552 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002553 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002554
2555 if (context)
2556 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002557 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002558 }
2559 }
2560 break;
2561 default:
2562 return error(GL_INVALID_ENUM);
2563 }
2564 }
2565 catch(std::bad_alloc&)
2566 {
2567 return error(GL_OUT_OF_MEMORY);
2568 }
2569}
2570
2571void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2572{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002573 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002574
2575 try
2576 {
2577 if (n < 0)
2578 {
2579 return error(GL_INVALID_VALUE);
2580 }
2581
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002582 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002583
2584 if (context)
2585 {
2586 for (int i = 0; i < n; i++)
2587 {
2588 buffers[i] = context->createBuffer();
2589 }
2590 }
2591 }
2592 catch(std::bad_alloc&)
2593 {
2594 return error(GL_OUT_OF_MEMORY);
2595 }
2596}
2597
2598void __stdcall glGenerateMipmap(GLenum target)
2599{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002600 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002601
2602 try
2603 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002604 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002605
2606 if (context)
2607 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002608 switch (target)
2609 {
2610 case GL_TEXTURE_2D:
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002611 {
2612 gl::Texture2D *tex2d = context->getTexture2D();
2613
daniel@transgaming.com92f49922012-05-09 15:49:19 +00002614 if (tex2d->isCompressed(0))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002615 {
2616 return error(GL_INVALID_OPERATION);
2617 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00002618 if (tex2d->isDepth(0))
2619 {
2620 return error(GL_INVALID_OPERATION);
2621 }
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002622
2623 tex2d->generateMipmaps();
2624 break;
2625 }
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002626
2627 case GL_TEXTURE_CUBE_MAP:
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002628 {
2629 gl::TextureCubeMap *texcube = context->getTextureCubeMap();
2630
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00002631 if (texcube->isCompressed(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002632 {
2633 return error(GL_INVALID_OPERATION);
2634 }
2635
2636 texcube->generateMipmaps();
2637 break;
2638 }
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002639
2640 default:
2641 return error(GL_INVALID_ENUM);
2642 }
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002643 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002644 }
2645 catch(std::bad_alloc&)
2646 {
2647 return error(GL_OUT_OF_MEMORY);
2648 }
2649}
2650
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002651void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2652{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002653 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002654
2655 try
2656 {
2657 if (n < 0)
2658 {
2659 return error(GL_INVALID_VALUE);
2660 }
2661
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002662 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002663
2664 if (context)
2665 {
2666 for (int i = 0; i < n; i++)
2667 {
2668 fences[i] = context->createFence();
2669 }
2670 }
2671 }
2672 catch(std::bad_alloc&)
2673 {
2674 return error(GL_OUT_OF_MEMORY);
2675 }
2676}
2677
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002678void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2679{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002680 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002681
2682 try
2683 {
2684 if (n < 0)
2685 {
2686 return error(GL_INVALID_VALUE);
2687 }
2688
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002689 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002690
2691 if (context)
2692 {
2693 for (int i = 0; i < n; i++)
2694 {
2695 framebuffers[i] = context->createFramebuffer();
2696 }
2697 }
2698 }
2699 catch(std::bad_alloc&)
2700 {
2701 return error(GL_OUT_OF_MEMORY);
2702 }
2703}
2704
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00002705void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
2706{
2707 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
2708
2709 try
2710 {
2711 if (n < 0)
2712 {
2713 return error(GL_INVALID_VALUE);
2714 }
2715
2716 gl::Context *context = gl::getNonLostContext();
2717
2718 if (context)
2719 {
2720 for (int i = 0; i < n; i++)
2721 {
2722 ids[i] = context->createQuery();
2723 }
2724 }
2725 }
2726 catch(std::bad_alloc&)
2727 {
2728 return error(GL_OUT_OF_MEMORY);
2729 }
2730}
2731
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002732void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2733{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002734 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002735
2736 try
2737 {
2738 if (n < 0)
2739 {
2740 return error(GL_INVALID_VALUE);
2741 }
2742
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002743 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002744
2745 if (context)
2746 {
2747 for (int i = 0; i < n; i++)
2748 {
2749 renderbuffers[i] = context->createRenderbuffer();
2750 }
2751 }
2752 }
2753 catch(std::bad_alloc&)
2754 {
2755 return error(GL_OUT_OF_MEMORY);
2756 }
2757}
2758
2759void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2760{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002761 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002762
2763 try
2764 {
2765 if (n < 0)
2766 {
2767 return error(GL_INVALID_VALUE);
2768 }
2769
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002770 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002771
2772 if (context)
2773 {
2774 for (int i = 0; i < n; i++)
2775 {
2776 textures[i] = context->createTexture();
2777 }
2778 }
2779 }
2780 catch(std::bad_alloc&)
2781 {
2782 return error(GL_OUT_OF_MEMORY);
2783 }
2784}
2785
daniel@transgaming.com85423182010-04-22 13:35:27 +00002786void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002787{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002788 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002789 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002790 program, index, bufsize, length, size, type, name);
2791
2792 try
2793 {
2794 if (bufsize < 0)
2795 {
2796 return error(GL_INVALID_VALUE);
2797 }
2798
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002799 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com85423182010-04-22 13:35:27 +00002800
2801 if (context)
2802 {
2803 gl::Program *programObject = context->getProgram(program);
2804
2805 if (!programObject)
2806 {
2807 if (context->getShader(program))
2808 {
2809 return error(GL_INVALID_OPERATION);
2810 }
2811 else
2812 {
2813 return error(GL_INVALID_VALUE);
2814 }
2815 }
2816
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002817 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002818 {
2819 return error(GL_INVALID_VALUE);
2820 }
2821
2822 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2823 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002824 }
2825 catch(std::bad_alloc&)
2826 {
2827 return error(GL_OUT_OF_MEMORY);
2828 }
2829}
2830
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002831void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002832{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002833 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002834 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002835 program, index, bufsize, length, size, type, name);
2836
2837 try
2838 {
2839 if (bufsize < 0)
2840 {
2841 return error(GL_INVALID_VALUE);
2842 }
2843
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002844 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002845
2846 if (context)
2847 {
2848 gl::Program *programObject = context->getProgram(program);
2849
2850 if (!programObject)
2851 {
2852 if (context->getShader(program))
2853 {
2854 return error(GL_INVALID_OPERATION);
2855 }
2856 else
2857 {
2858 return error(GL_INVALID_VALUE);
2859 }
2860 }
2861
2862 if (index >= (GLuint)programObject->getActiveUniformCount())
2863 {
2864 return error(GL_INVALID_VALUE);
2865 }
2866
2867 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2868 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002869 }
2870 catch(std::bad_alloc&)
2871 {
2872 return error(GL_OUT_OF_MEMORY);
2873 }
2874}
2875
2876void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2877{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002878 EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002879 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002880
2881 try
2882 {
2883 if (maxcount < 0)
2884 {
2885 return error(GL_INVALID_VALUE);
2886 }
2887
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002888 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002889
2890 if (context)
2891 {
2892 gl::Program *programObject = context->getProgram(program);
2893
2894 if (!programObject)
2895 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002896 if (context->getShader(program))
2897 {
2898 return error(GL_INVALID_OPERATION);
2899 }
2900 else
2901 {
2902 return error(GL_INVALID_VALUE);
2903 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002904 }
2905
2906 return programObject->getAttachedShaders(maxcount, count, shaders);
2907 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002908 }
2909 catch(std::bad_alloc&)
2910 {
2911 return error(GL_OUT_OF_MEMORY);
2912 }
2913}
2914
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002915int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002916{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002917 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002918
2919 try
2920 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002921 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002922
2923 if (context)
2924 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002925
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002926 gl::Program *programObject = context->getProgram(program);
2927
2928 if (!programObject)
2929 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002930 if (context->getShader(program))
2931 {
2932 return error(GL_INVALID_OPERATION, -1);
2933 }
2934 else
2935 {
2936 return error(GL_INVALID_VALUE, -1);
2937 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002938 }
2939
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002940 if (!programObject->isLinked())
2941 {
2942 return error(GL_INVALID_OPERATION, -1);
2943 }
2944
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002945 return programObject->getAttributeLocation(name);
2946 }
2947 }
2948 catch(std::bad_alloc&)
2949 {
2950 return error(GL_OUT_OF_MEMORY, -1);
2951 }
2952
2953 return -1;
2954}
2955
2956void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2957{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002958 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002959
2960 try
2961 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002962 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002963
2964 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002965 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002966 if (!(context->getBooleanv(pname, params)))
2967 {
2968 GLenum nativeType;
2969 unsigned int numParams = 0;
2970 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2971 return error(GL_INVALID_ENUM);
2972
2973 if (numParams == 0)
2974 return; // it is known that the pname is valid, but there are no parameters to return
2975
2976 if (nativeType == GL_FLOAT)
2977 {
2978 GLfloat *floatParams = NULL;
2979 floatParams = new GLfloat[numParams];
2980
2981 context->getFloatv(pname, floatParams);
2982
2983 for (unsigned int i = 0; i < numParams; ++i)
2984 {
2985 if (floatParams[i] == 0.0f)
2986 params[i] = GL_FALSE;
2987 else
2988 params[i] = GL_TRUE;
2989 }
2990
2991 delete [] floatParams;
2992 }
2993 else if (nativeType == GL_INT)
2994 {
2995 GLint *intParams = NULL;
2996 intParams = new GLint[numParams];
2997
2998 context->getIntegerv(pname, intParams);
2999
3000 for (unsigned int i = 0; i < numParams; ++i)
3001 {
3002 if (intParams[i] == 0)
3003 params[i] = GL_FALSE;
3004 else
3005 params[i] = GL_TRUE;
3006 }
3007
3008 delete [] intParams;
3009 }
3010 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003011 }
3012 }
3013 catch(std::bad_alloc&)
3014 {
3015 return error(GL_OUT_OF_MEMORY);
3016 }
3017}
3018
3019void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
3020{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003021 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003022
3023 try
3024 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003025 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00003026
3027 if (context)
3028 {
3029 gl::Buffer *buffer;
3030
3031 switch (target)
3032 {
3033 case GL_ARRAY_BUFFER:
3034 buffer = context->getArrayBuffer();
3035 break;
3036 case GL_ELEMENT_ARRAY_BUFFER:
3037 buffer = context->getElementArrayBuffer();
3038 break;
3039 default: return error(GL_INVALID_ENUM);
3040 }
3041
3042 if (!buffer)
3043 {
3044 // A null buffer means that "0" is bound to the requested buffer target
3045 return error(GL_INVALID_OPERATION);
3046 }
3047
3048 switch (pname)
3049 {
3050 case GL_BUFFER_USAGE:
3051 *params = buffer->usage();
3052 break;
3053 case GL_BUFFER_SIZE:
3054 *params = buffer->size();
3055 break;
3056 default: return error(GL_INVALID_ENUM);
3057 }
3058 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003059 }
3060 catch(std::bad_alloc&)
3061 {
3062 return error(GL_OUT_OF_MEMORY);
3063 }
3064}
3065
3066GLenum __stdcall glGetError(void)
3067{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003068 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003069
3070 gl::Context *context = gl::getContext();
3071
3072 if (context)
3073 {
daniel@transgaming.com82b28912011-12-12 21:01:35 +00003074 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003075 }
3076
3077 return GL_NO_ERROR;
3078}
3079
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003080void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
3081{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003082 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003083
3084 try
3085 {
3086
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003087 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003088
3089 if (context)
3090 {
3091 gl::Fence *fenceObject = context->getFence(fence);
3092
3093 if (fenceObject == NULL)
3094 {
3095 return error(GL_INVALID_OPERATION);
3096 }
3097
3098 fenceObject->getFenceiv(pname, params);
3099 }
3100 }
3101 catch(std::bad_alloc&)
3102 {
3103 return error(GL_OUT_OF_MEMORY);
3104 }
3105}
3106
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003107void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
3108{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003109 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003110
3111 try
3112 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003113 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003114
3115 if (context)
3116 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003117 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003118 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003119 GLenum nativeType;
3120 unsigned int numParams = 0;
3121 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3122 return error(GL_INVALID_ENUM);
3123
3124 if (numParams == 0)
3125 return; // it is known that the pname is valid, but that there are no parameters to return.
3126
3127 if (nativeType == GL_BOOL)
3128 {
3129 GLboolean *boolParams = NULL;
3130 boolParams = new GLboolean[numParams];
3131
3132 context->getBooleanv(pname, boolParams);
3133
3134 for (unsigned int i = 0; i < numParams; ++i)
3135 {
3136 if (boolParams[i] == GL_FALSE)
3137 params[i] = 0.0f;
3138 else
3139 params[i] = 1.0f;
3140 }
3141
3142 delete [] boolParams;
3143 }
3144 else if (nativeType == GL_INT)
3145 {
3146 GLint *intParams = NULL;
3147 intParams = new GLint[numParams];
3148
3149 context->getIntegerv(pname, intParams);
3150
3151 for (unsigned int i = 0; i < numParams; ++i)
3152 {
3153 params[i] = (GLfloat)intParams[i];
3154 }
3155
3156 delete [] intParams;
3157 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003158 }
3159 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003160 }
3161 catch(std::bad_alloc&)
3162 {
3163 return error(GL_OUT_OF_MEMORY);
3164 }
3165}
3166
3167void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
3168{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003169 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003170 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003171
3172 try
3173 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003174 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003175
3176 if (context)
3177 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003178 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003179 {
3180 return error(GL_INVALID_ENUM);
3181 }
3182
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003183 gl::Framebuffer *framebuffer = NULL;
3184 if (target == GL_READ_FRAMEBUFFER_ANGLE)
3185 {
3186 if(context->getReadFramebufferHandle() == 0)
3187 {
3188 return error(GL_INVALID_OPERATION);
3189 }
3190
3191 framebuffer = context->getReadFramebuffer();
3192 }
3193 else
3194 {
3195 if (context->getDrawFramebufferHandle() == 0)
3196 {
3197 return error(GL_INVALID_OPERATION);
3198 }
3199
3200 framebuffer = context->getDrawFramebuffer();
3201 }
3202
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003203 GLenum attachmentType;
3204 GLuint attachmentHandle;
3205 switch (attachment)
3206 {
3207 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003208 attachmentType = framebuffer->getColorbufferType();
3209 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003210 break;
3211 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003212 attachmentType = framebuffer->getDepthbufferType();
3213 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003214 break;
3215 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003216 attachmentType = framebuffer->getStencilbufferType();
3217 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003218 break;
3219 default: return error(GL_INVALID_ENUM);
3220 }
3221
3222 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00003223 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003224 {
3225 attachmentObjectType = attachmentType;
3226 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +00003227 else if (gl::IsInternalTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003228 {
3229 attachmentObjectType = GL_TEXTURE;
3230 }
apatrick@chromium.orga1d80592012-01-25 21:52:10 +00003231 else
3232 {
3233 UNREACHABLE();
3234 return;
3235 }
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003236
3237 switch (pname)
3238 {
3239 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3240 *params = attachmentObjectType;
3241 break;
3242 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3243 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
3244 {
3245 *params = attachmentHandle;
3246 }
3247 else
3248 {
3249 return error(GL_INVALID_ENUM);
3250 }
3251 break;
3252 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3253 if (attachmentObjectType == GL_TEXTURE)
3254 {
3255 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
3256 }
3257 else
3258 {
3259 return error(GL_INVALID_ENUM);
3260 }
3261 break;
3262 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3263 if (attachmentObjectType == GL_TEXTURE)
3264 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00003265 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003266 {
3267 *params = attachmentType;
3268 }
3269 else
3270 {
3271 *params = 0;
3272 }
3273 }
3274 else
3275 {
3276 return error(GL_INVALID_ENUM);
3277 }
3278 break;
3279 default:
3280 return error(GL_INVALID_ENUM);
3281 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003282 }
3283 }
3284 catch(std::bad_alloc&)
3285 {
3286 return error(GL_OUT_OF_MEMORY);
3287 }
3288}
3289
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00003290GLenum __stdcall glGetGraphicsResetStatusEXT(void)
3291{
3292 EVENT("()");
3293
3294 try
3295 {
3296 gl::Context *context = gl::getContext();
3297
3298 if (context)
3299 {
3300 return context->getResetStatus();
3301 }
3302
3303 return GL_NO_ERROR;
3304 }
3305 catch(std::bad_alloc&)
3306 {
3307 return GL_OUT_OF_MEMORY;
3308 }
3309}
3310
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003311void __stdcall glGetIntegerv(GLenum pname, GLint* params)
3312{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003313 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003314
3315 try
3316 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003317 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003318
3319 if (context)
3320 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003321 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003322 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003323 GLenum nativeType;
3324 unsigned int numParams = 0;
3325 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3326 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003327
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003328 if (numParams == 0)
3329 return; // it is known that pname is valid, but there are no parameters to return
3330
3331 if (nativeType == GL_BOOL)
3332 {
3333 GLboolean *boolParams = NULL;
3334 boolParams = new GLboolean[numParams];
3335
3336 context->getBooleanv(pname, boolParams);
3337
3338 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003339 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003340 if (boolParams[i] == GL_FALSE)
3341 params[i] = 0;
3342 else
3343 params[i] = 1;
3344 }
3345
3346 delete [] boolParams;
3347 }
3348 else if (nativeType == GL_FLOAT)
3349 {
3350 GLfloat *floatParams = NULL;
3351 floatParams = new GLfloat[numParams];
3352
3353 context->getFloatv(pname, floatParams);
3354
3355 for (unsigned int i = 0; i < numParams; ++i)
3356 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00003357 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003358 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003359 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003360 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003361 else
3362 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003363 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003364
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003365 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003366 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003367 }
3368 }
3369 }
3370 catch(std::bad_alloc&)
3371 {
3372 return error(GL_OUT_OF_MEMORY);
3373 }
3374}
3375
3376void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3377{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003378 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003379
3380 try
3381 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003382 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003383
3384 if (context)
3385 {
3386 gl::Program *programObject = context->getProgram(program);
3387
3388 if (!programObject)
3389 {
3390 return error(GL_INVALID_VALUE);
3391 }
3392
3393 switch (pname)
3394 {
3395 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003396 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003397 return;
3398 case GL_LINK_STATUS:
3399 *params = programObject->isLinked();
3400 return;
3401 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003402 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003403 return;
3404 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003405 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003406 return;
3407 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003408 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003409 return;
3410 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003411 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003412 return;
3413 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003414 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003415 return;
3416 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003417 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003418 return;
3419 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003420 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003421 return;
3422 default:
3423 return error(GL_INVALID_ENUM);
3424 }
3425 }
3426 }
3427 catch(std::bad_alloc&)
3428 {
3429 return error(GL_OUT_OF_MEMORY);
3430 }
3431}
3432
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003433void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003434{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003435 EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003436 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003437
3438 try
3439 {
3440 if (bufsize < 0)
3441 {
3442 return error(GL_INVALID_VALUE);
3443 }
3444
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003445 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003446
3447 if (context)
3448 {
3449 gl::Program *programObject = context->getProgram(program);
3450
3451 if (!programObject)
3452 {
3453 return error(GL_INVALID_VALUE);
3454 }
3455
3456 programObject->getInfoLog(bufsize, length, infolog);
3457 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003458 }
3459 catch(std::bad_alloc&)
3460 {
3461 return error(GL_OUT_OF_MEMORY);
3462 }
3463}
3464
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003465void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3466{
3467 EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
3468
3469 try
3470 {
3471 switch (pname)
3472 {
3473 case GL_CURRENT_QUERY_EXT:
3474 break;
3475 default:
3476 return error(GL_INVALID_ENUM);
3477 }
3478
3479 gl::Context *context = gl::getNonLostContext();
3480
3481 if (context)
3482 {
3483 params[0] = context->getActiveQuery(target);
3484 }
3485 }
3486 catch(std::bad_alloc&)
3487 {
3488 return error(GL_OUT_OF_MEMORY);
3489 }
3490}
3491
3492void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
3493{
3494 EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
3495
3496 try
3497 {
3498 switch (pname)
3499 {
3500 case GL_QUERY_RESULT_EXT:
3501 case GL_QUERY_RESULT_AVAILABLE_EXT:
3502 break;
3503 default:
3504 return error(GL_INVALID_ENUM);
3505 }
3506 gl::Context *context = gl::getNonLostContext();
3507
3508 if (context)
3509 {
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003510 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
3511
3512 if (!queryObject)
3513 {
3514 return error(GL_INVALID_OPERATION);
3515 }
3516
3517 if (context->getActiveQuery(queryObject->getType()) == id)
3518 {
3519 return error(GL_INVALID_OPERATION);
3520 }
3521
3522 switch(pname)
3523 {
3524 case GL_QUERY_RESULT_EXT:
3525 params[0] = queryObject->getResult();
3526 break;
3527 case GL_QUERY_RESULT_AVAILABLE_EXT:
3528 params[0] = queryObject->isResultAvailable();
3529 break;
3530 default:
3531 ASSERT(false);
3532 }
3533 }
3534 }
3535 catch(std::bad_alloc&)
3536 {
3537 return error(GL_OUT_OF_MEMORY);
3538 }
3539}
3540
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003541void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3542{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003543 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003544
3545 try
3546 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003547 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003548
3549 if (context)
3550 {
3551 if (target != GL_RENDERBUFFER)
3552 {
3553 return error(GL_INVALID_ENUM);
3554 }
3555
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003556 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003557 {
3558 return error(GL_INVALID_OPERATION);
3559 }
3560
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003561 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003562
3563 switch (pname)
3564 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003565 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3566 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3567 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3568 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3569 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3570 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3571 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3572 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3573 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003574 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003575 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003576 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003577 *params = renderbuffer->getSamples();
3578 }
3579 else
3580 {
3581 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003582 }
3583 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003584 default:
3585 return error(GL_INVALID_ENUM);
3586 }
3587 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003588 }
3589 catch(std::bad_alloc&)
3590 {
3591 return error(GL_OUT_OF_MEMORY);
3592 }
3593}
3594
3595void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3596{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003597 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003598
3599 try
3600 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003601 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003602
3603 if (context)
3604 {
3605 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003606
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003607 if (!shaderObject)
3608 {
3609 return error(GL_INVALID_VALUE);
3610 }
3611
3612 switch (pname)
3613 {
3614 case GL_SHADER_TYPE:
3615 *params = shaderObject->getType();
3616 return;
3617 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003618 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003619 return;
3620 case GL_COMPILE_STATUS:
3621 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3622 return;
3623 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003624 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003625 return;
3626 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003627 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003628 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003629 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3630 *params = shaderObject->getTranslatedSourceLength();
3631 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003632 default:
3633 return error(GL_INVALID_ENUM);
3634 }
3635 }
3636 }
3637 catch(std::bad_alloc&)
3638 {
3639 return error(GL_OUT_OF_MEMORY);
3640 }
3641}
3642
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003643void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003644{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003645 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003646 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003647
3648 try
3649 {
3650 if (bufsize < 0)
3651 {
3652 return error(GL_INVALID_VALUE);
3653 }
3654
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003655 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003656
3657 if (context)
3658 {
3659 gl::Shader *shaderObject = context->getShader(shader);
3660
3661 if (!shaderObject)
3662 {
3663 return error(GL_INVALID_VALUE);
3664 }
3665
3666 shaderObject->getInfoLog(bufsize, length, infolog);
3667 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003668 }
3669 catch(std::bad_alloc&)
3670 {
3671 return error(GL_OUT_OF_MEMORY);
3672 }
3673}
3674
3675void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3676{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003677 EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003678 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003679
3680 try
3681 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003682 switch (shadertype)
3683 {
3684 case GL_VERTEX_SHADER:
3685 case GL_FRAGMENT_SHADER:
3686 break;
3687 default:
3688 return error(GL_INVALID_ENUM);
3689 }
3690
3691 switch (precisiontype)
3692 {
3693 case GL_LOW_FLOAT:
3694 case GL_MEDIUM_FLOAT:
3695 case GL_HIGH_FLOAT:
3696 // Assume IEEE 754 precision
3697 range[0] = 127;
3698 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003699 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003700 break;
3701 case GL_LOW_INT:
3702 case GL_MEDIUM_INT:
3703 case GL_HIGH_INT:
3704 // Some (most) hardware only supports single-precision floating-point numbers,
3705 // which can accurately represent integers up to +/-16777216
3706 range[0] = 24;
3707 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003708 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003709 break;
3710 default:
3711 return error(GL_INVALID_ENUM);
3712 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003713 }
3714 catch(std::bad_alloc&)
3715 {
3716 return error(GL_OUT_OF_MEMORY);
3717 }
3718}
3719
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003720void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003721{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003722 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003723 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003724
3725 try
3726 {
3727 if (bufsize < 0)
3728 {
3729 return error(GL_INVALID_VALUE);
3730 }
3731
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003732 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003733
3734 if (context)
3735 {
3736 gl::Shader *shaderObject = context->getShader(shader);
3737
3738 if (!shaderObject)
3739 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003740 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003741 }
3742
3743 shaderObject->getSource(bufsize, length, source);
3744 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003745 }
3746 catch(std::bad_alloc&)
3747 {
3748 return error(GL_OUT_OF_MEMORY);
3749 }
3750}
3751
zmo@google.coma574f782011-10-03 21:45:23 +00003752void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3753{
3754 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3755 shader, bufsize, length, source);
3756
3757 try
3758 {
3759 if (bufsize < 0)
3760 {
3761 return error(GL_INVALID_VALUE);
3762 }
3763
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003764 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003765
3766 if (context)
3767 {
3768 gl::Shader *shaderObject = context->getShader(shader);
3769
3770 if (!shaderObject)
3771 {
3772 return error(GL_INVALID_OPERATION);
3773 }
3774
3775 shaderObject->getTranslatedSource(bufsize, length, source);
3776 }
3777 }
3778 catch(std::bad_alloc&)
3779 {
3780 return error(GL_OUT_OF_MEMORY);
3781 }
3782}
3783
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003784const GLubyte* __stdcall glGetString(GLenum name)
3785{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003786 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003787
3788 try
3789 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003790 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003791
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003792 switch (name)
3793 {
3794 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003795 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003796 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003797 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003798 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003799 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003800 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003801 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003802 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003803 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003804 default:
3805 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3806 }
3807 }
3808 catch(std::bad_alloc&)
3809 {
3810 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3811 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003812}
3813
3814void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3815{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003816 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003817
3818 try
3819 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003820 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003821
3822 if (context)
3823 {
3824 gl::Texture *texture;
3825
3826 switch (target)
3827 {
3828 case GL_TEXTURE_2D:
3829 texture = context->getTexture2D();
3830 break;
3831 case GL_TEXTURE_CUBE_MAP:
3832 texture = context->getTextureCubeMap();
3833 break;
3834 default:
3835 return error(GL_INVALID_ENUM);
3836 }
3837
3838 switch (pname)
3839 {
3840 case GL_TEXTURE_MAG_FILTER:
3841 *params = (GLfloat)texture->getMagFilter();
3842 break;
3843 case GL_TEXTURE_MIN_FILTER:
3844 *params = (GLfloat)texture->getMinFilter();
3845 break;
3846 case GL_TEXTURE_WRAP_S:
3847 *params = (GLfloat)texture->getWrapS();
3848 break;
3849 case GL_TEXTURE_WRAP_T:
3850 *params = (GLfloat)texture->getWrapT();
3851 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003852 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3853 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3854 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003855 case GL_TEXTURE_USAGE_ANGLE:
3856 *params = (GLfloat)texture->getUsage();
3857 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003858 default:
3859 return error(GL_INVALID_ENUM);
3860 }
3861 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003862 }
3863 catch(std::bad_alloc&)
3864 {
3865 return error(GL_OUT_OF_MEMORY);
3866 }
3867}
3868
3869void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3870{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003871 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003872
3873 try
3874 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003875 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003876
3877 if (context)
3878 {
3879 gl::Texture *texture;
3880
3881 switch (target)
3882 {
3883 case GL_TEXTURE_2D:
3884 texture = context->getTexture2D();
3885 break;
3886 case GL_TEXTURE_CUBE_MAP:
3887 texture = context->getTextureCubeMap();
3888 break;
3889 default:
3890 return error(GL_INVALID_ENUM);
3891 }
3892
3893 switch (pname)
3894 {
3895 case GL_TEXTURE_MAG_FILTER:
3896 *params = texture->getMagFilter();
3897 break;
3898 case GL_TEXTURE_MIN_FILTER:
3899 *params = texture->getMinFilter();
3900 break;
3901 case GL_TEXTURE_WRAP_S:
3902 *params = texture->getWrapS();
3903 break;
3904 case GL_TEXTURE_WRAP_T:
3905 *params = texture->getWrapT();
3906 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003907 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3908 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3909 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003910 case GL_TEXTURE_USAGE_ANGLE:
3911 *params = texture->getUsage();
3912 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003913 default:
3914 return error(GL_INVALID_ENUM);
3915 }
3916 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003917 }
3918 catch(std::bad_alloc&)
3919 {
3920 return error(GL_OUT_OF_MEMORY);
3921 }
3922}
3923
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003924void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3925{
3926 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3927 program, location, bufSize, params);
3928
3929 try
3930 {
3931 if (bufSize < 0)
3932 {
3933 return error(GL_INVALID_VALUE);
3934 }
3935
3936 gl::Context *context = gl::getNonLostContext();
3937
3938 if (context)
3939 {
3940 if (program == 0)
3941 {
3942 return error(GL_INVALID_VALUE);
3943 }
3944
3945 gl::Program *programObject = context->getProgram(program);
3946
3947 if (!programObject || !programObject->isLinked())
3948 {
3949 return error(GL_INVALID_OPERATION);
3950 }
3951
3952 if (!programObject->getUniformfv(location, &bufSize, params))
3953 {
3954 return error(GL_INVALID_OPERATION);
3955 }
3956 }
3957 }
3958 catch(std::bad_alloc&)
3959 {
3960 return error(GL_OUT_OF_MEMORY);
3961 }
3962}
3963
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003964void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3965{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003966 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003967
3968 try
3969 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003970 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003971
3972 if (context)
3973 {
3974 if (program == 0)
3975 {
3976 return error(GL_INVALID_VALUE);
3977 }
3978
3979 gl::Program *programObject = context->getProgram(program);
3980
3981 if (!programObject || !programObject->isLinked())
3982 {
3983 return error(GL_INVALID_OPERATION);
3984 }
3985
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003986 if (!programObject->getUniformfv(location, NULL, params))
3987 {
3988 return error(GL_INVALID_OPERATION);
3989 }
3990 }
3991 }
3992 catch(std::bad_alloc&)
3993 {
3994 return error(GL_OUT_OF_MEMORY);
3995 }
3996}
3997
3998void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3999{
4000 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
4001 program, location, bufSize, params);
4002
4003 try
4004 {
4005 if (bufSize < 0)
4006 {
4007 return error(GL_INVALID_VALUE);
4008 }
4009
4010 gl::Context *context = gl::getNonLostContext();
4011
4012 if (context)
4013 {
4014 if (program == 0)
4015 {
4016 return error(GL_INVALID_VALUE);
4017 }
4018
4019 gl::Program *programObject = context->getProgram(program);
4020
4021 if (!programObject || !programObject->isLinked())
4022 {
4023 return error(GL_INVALID_OPERATION);
4024 }
4025
4026 if (!programObject)
4027 {
4028 return error(GL_INVALID_OPERATION);
4029 }
4030
4031 if (!programObject->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004032 {
4033 return error(GL_INVALID_OPERATION);
4034 }
4035 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004036 }
4037 catch(std::bad_alloc&)
4038 {
4039 return error(GL_OUT_OF_MEMORY);
4040 }
4041}
4042
4043void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
4044{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004045 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004046
4047 try
4048 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004049 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004050
4051 if (context)
4052 {
4053 if (program == 0)
4054 {
4055 return error(GL_INVALID_VALUE);
4056 }
4057
4058 gl::Program *programObject = context->getProgram(program);
4059
4060 if (!programObject || !programObject->isLinked())
4061 {
4062 return error(GL_INVALID_OPERATION);
4063 }
4064
4065 if (!programObject)
4066 {
4067 return error(GL_INVALID_OPERATION);
4068 }
4069
daniel@transgaming.com9a849122011-11-12 03:18:00 +00004070 if (!programObject->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004071 {
4072 return error(GL_INVALID_OPERATION);
4073 }
4074 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004075 }
4076 catch(std::bad_alloc&)
4077 {
4078 return error(GL_OUT_OF_MEMORY);
4079 }
4080}
4081
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004082int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004083{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004084 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004085
4086 try
4087 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004088 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004089
4090 if (strstr(name, "gl_") == name)
4091 {
4092 return -1;
4093 }
4094
4095 if (context)
4096 {
4097 gl::Program *programObject = context->getProgram(program);
4098
4099 if (!programObject)
4100 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00004101 if (context->getShader(program))
4102 {
4103 return error(GL_INVALID_OPERATION, -1);
4104 }
4105 else
4106 {
4107 return error(GL_INVALID_VALUE, -1);
4108 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004109 }
4110
4111 if (!programObject->isLinked())
4112 {
4113 return error(GL_INVALID_OPERATION, -1);
4114 }
4115
daniel@transgaming.com024f1a92011-09-20 16:06:25 +00004116 return programObject->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004117 }
4118 }
4119 catch(std::bad_alloc&)
4120 {
4121 return error(GL_OUT_OF_MEMORY, -1);
4122 }
4123
4124 return -1;
4125}
4126
4127void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
4128{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004129 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004130
4131 try
4132 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004133 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004134
daniel@transgaming.come0078962010-04-15 20:45:08 +00004135 if (context)
4136 {
4137 if (index >= gl::MAX_VERTEX_ATTRIBS)
4138 {
4139 return error(GL_INVALID_VALUE);
4140 }
4141
daniel@transgaming.com83921382011-01-08 05:46:00 +00004142 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004143
daniel@transgaming.come0078962010-04-15 20:45:08 +00004144 switch (pname)
4145 {
4146 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004147 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004148 break;
4149 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004150 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004151 break;
4152 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004153 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004154 break;
4155 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004156 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004157 break;
4158 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004159 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004160 break;
4161 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004162 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004163 break;
4164 case GL_CURRENT_VERTEX_ATTRIB:
4165 for (int i = 0; i < 4; ++i)
4166 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004167 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004168 }
4169 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004170 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4171 *params = (GLfloat)attribState.mDivisor;
4172 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004173 default: return error(GL_INVALID_ENUM);
4174 }
4175 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004176 }
4177 catch(std::bad_alloc&)
4178 {
4179 return error(GL_OUT_OF_MEMORY);
4180 }
4181}
4182
4183void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
4184{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004185 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004186
4187 try
4188 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004189 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004190
daniel@transgaming.come0078962010-04-15 20:45:08 +00004191 if (context)
4192 {
4193 if (index >= gl::MAX_VERTEX_ATTRIBS)
4194 {
4195 return error(GL_INVALID_VALUE);
4196 }
4197
daniel@transgaming.com83921382011-01-08 05:46:00 +00004198 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004199
daniel@transgaming.come0078962010-04-15 20:45:08 +00004200 switch (pname)
4201 {
4202 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004203 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004204 break;
4205 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004206 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004207 break;
4208 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004209 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004210 break;
4211 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004212 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004213 break;
4214 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004215 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004216 break;
4217 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004218 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004219 break;
4220 case GL_CURRENT_VERTEX_ATTRIB:
4221 for (int i = 0; i < 4; ++i)
4222 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004223 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004224 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4225 }
4226 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004227 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4228 *params = (GLint)attribState.mDivisor;
4229 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004230 default: return error(GL_INVALID_ENUM);
4231 }
4232 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004233 }
4234 catch(std::bad_alloc&)
4235 {
4236 return error(GL_OUT_OF_MEMORY);
4237 }
4238}
4239
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004240void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004241{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004242 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004243
4244 try
4245 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004246 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004247
daniel@transgaming.come0078962010-04-15 20:45:08 +00004248 if (context)
4249 {
4250 if (index >= gl::MAX_VERTEX_ATTRIBS)
4251 {
4252 return error(GL_INVALID_VALUE);
4253 }
4254
4255 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4256 {
4257 return error(GL_INVALID_ENUM);
4258 }
4259
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004260 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00004261 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004262 }
4263 catch(std::bad_alloc&)
4264 {
4265 return error(GL_OUT_OF_MEMORY);
4266 }
4267}
4268
4269void __stdcall glHint(GLenum target, GLenum mode)
4270{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004271 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004272
4273 try
4274 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004275 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004276 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004277 case GL_FASTEST:
4278 case GL_NICEST:
4279 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004280 break;
4281 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004282 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004283 }
4284
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004285 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004286 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004287 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004288 case GL_GENERATE_MIPMAP_HINT:
4289 if (context) context->setGenerateMipmapHint(mode);
4290 break;
4291 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4292 if (context) context->setFragmentShaderDerivativeHint(mode);
4293 break;
4294 default:
4295 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004296 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004297 }
4298 catch(std::bad_alloc&)
4299 {
4300 return error(GL_OUT_OF_MEMORY);
4301 }
4302}
4303
4304GLboolean __stdcall glIsBuffer(GLuint buffer)
4305{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004306 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004307
4308 try
4309 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004310 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004311
4312 if (context && buffer)
4313 {
4314 gl::Buffer *bufferObject = context->getBuffer(buffer);
4315
4316 if (bufferObject)
4317 {
4318 return GL_TRUE;
4319 }
4320 }
4321 }
4322 catch(std::bad_alloc&)
4323 {
4324 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4325 }
4326
4327 return GL_FALSE;
4328}
4329
4330GLboolean __stdcall glIsEnabled(GLenum cap)
4331{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004332 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004333
4334 try
4335 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004336 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004337
4338 if (context)
4339 {
4340 switch (cap)
4341 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004342 case GL_CULL_FACE: return context->isCullFaceEnabled();
4343 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4344 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4345 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4346 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4347 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4348 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4349 case GL_BLEND: return context->isBlendEnabled();
4350 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004351 default:
4352 return error(GL_INVALID_ENUM, false);
4353 }
4354 }
4355 }
4356 catch(std::bad_alloc&)
4357 {
4358 return error(GL_OUT_OF_MEMORY, false);
4359 }
4360
4361 return false;
4362}
4363
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004364GLboolean __stdcall glIsFenceNV(GLuint fence)
4365{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004366 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004367
4368 try
4369 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004370 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004371
4372 if (context)
4373 {
4374 gl::Fence *fenceObject = context->getFence(fence);
4375
4376 if (fenceObject == NULL)
4377 {
4378 return GL_FALSE;
4379 }
4380
4381 return fenceObject->isFence();
4382 }
4383 }
4384 catch(std::bad_alloc&)
4385 {
4386 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4387 }
4388
4389 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004390}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004391
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004392GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
4393{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004394 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004395
4396 try
4397 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004398 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004399
4400 if (context && framebuffer)
4401 {
4402 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4403
4404 if (framebufferObject)
4405 {
4406 return GL_TRUE;
4407 }
4408 }
4409 }
4410 catch(std::bad_alloc&)
4411 {
4412 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4413 }
4414
4415 return GL_FALSE;
4416}
4417
4418GLboolean __stdcall glIsProgram(GLuint program)
4419{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004420 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004421
4422 try
4423 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004424 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004425
4426 if (context && program)
4427 {
4428 gl::Program *programObject = context->getProgram(program);
4429
4430 if (programObject)
4431 {
4432 return GL_TRUE;
4433 }
4434 }
4435 }
4436 catch(std::bad_alloc&)
4437 {
4438 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4439 }
4440
4441 return GL_FALSE;
4442}
4443
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00004444GLboolean __stdcall glIsQueryEXT(GLuint id)
4445{
4446 EVENT("(GLuint id = %d)", id);
4447
4448 try
4449 {
4450 if (id == 0)
4451 {
4452 return GL_FALSE;
4453 }
4454
4455 gl::Context *context = gl::getNonLostContext();
4456
4457 if (context)
4458 {
4459 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
4460
4461 if (queryObject)
4462 {
4463 return GL_TRUE;
4464 }
4465 }
4466 }
4467 catch(std::bad_alloc&)
4468 {
4469 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4470 }
4471
4472 return GL_FALSE;
4473}
4474
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004475GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
4476{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004477 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004478
4479 try
4480 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004481 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004482
4483 if (context && renderbuffer)
4484 {
4485 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4486
4487 if (renderbufferObject)
4488 {
4489 return GL_TRUE;
4490 }
4491 }
4492 }
4493 catch(std::bad_alloc&)
4494 {
4495 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4496 }
4497
4498 return GL_FALSE;
4499}
4500
4501GLboolean __stdcall glIsShader(GLuint shader)
4502{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004503 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004504
4505 try
4506 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004507 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004508
4509 if (context && shader)
4510 {
4511 gl::Shader *shaderObject = context->getShader(shader);
4512
4513 if (shaderObject)
4514 {
4515 return GL_TRUE;
4516 }
4517 }
4518 }
4519 catch(std::bad_alloc&)
4520 {
4521 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4522 }
4523
4524 return GL_FALSE;
4525}
4526
4527GLboolean __stdcall glIsTexture(GLuint texture)
4528{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004529 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004530
4531 try
4532 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004533 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004534
4535 if (context && texture)
4536 {
4537 gl::Texture *textureObject = context->getTexture(texture);
4538
4539 if (textureObject)
4540 {
4541 return GL_TRUE;
4542 }
4543 }
4544 }
4545 catch(std::bad_alloc&)
4546 {
4547 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4548 }
4549
4550 return GL_FALSE;
4551}
4552
4553void __stdcall glLineWidth(GLfloat width)
4554{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004555 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004556
4557 try
4558 {
4559 if (width <= 0.0f)
4560 {
4561 return error(GL_INVALID_VALUE);
4562 }
4563
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004564 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004565
4566 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004567 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004568 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004569 }
4570 }
4571 catch(std::bad_alloc&)
4572 {
4573 return error(GL_OUT_OF_MEMORY);
4574 }
4575}
4576
4577void __stdcall glLinkProgram(GLuint program)
4578{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004579 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004580
4581 try
4582 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004583 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004584
4585 if (context)
4586 {
4587 gl::Program *programObject = context->getProgram(program);
4588
4589 if (!programObject)
4590 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004591 if (context->getShader(program))
4592 {
4593 return error(GL_INVALID_OPERATION);
4594 }
4595 else
4596 {
4597 return error(GL_INVALID_VALUE);
4598 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004599 }
4600
4601 programObject->link();
4602 }
4603 }
4604 catch(std::bad_alloc&)
4605 {
4606 return error(GL_OUT_OF_MEMORY);
4607 }
4608}
4609
4610void __stdcall glPixelStorei(GLenum pname, GLint param)
4611{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004612 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004613
4614 try
4615 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004616 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004617
4618 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004619 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004620 switch (pname)
4621 {
4622 case GL_UNPACK_ALIGNMENT:
4623 if (param != 1 && param != 2 && param != 4 && param != 8)
4624 {
4625 return error(GL_INVALID_VALUE);
4626 }
4627
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004628 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004629 break;
4630
4631 case GL_PACK_ALIGNMENT:
4632 if (param != 1 && param != 2 && param != 4 && param != 8)
4633 {
4634 return error(GL_INVALID_VALUE);
4635 }
4636
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004637 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004638 break;
4639
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004640 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4641 context->setPackReverseRowOrder(param != 0);
4642 break;
4643
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004644 default:
4645 return error(GL_INVALID_ENUM);
4646 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004647 }
4648 }
4649 catch(std::bad_alloc&)
4650 {
4651 return error(GL_OUT_OF_MEMORY);
4652 }
4653}
4654
4655void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4656{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004657 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004658
4659 try
4660 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004661 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004662
4663 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004664 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004665 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004666 }
4667 }
4668 catch(std::bad_alloc&)
4669 {
4670 return error(GL_OUT_OF_MEMORY);
4671 }
4672}
4673
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004674void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4675 GLenum format, GLenum type, GLsizei bufSize,
4676 GLvoid *data)
4677{
4678 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4679 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4680 x, y, width, height, format, type, bufSize, data);
4681
4682 try
4683 {
4684 if (width < 0 || height < 0 || bufSize < 0)
4685 {
4686 return error(GL_INVALID_VALUE);
4687 }
4688
4689 if (!validReadFormatType(format, type))
4690 {
4691 return error(GL_INVALID_OPERATION);
4692 }
4693
4694 gl::Context *context = gl::getNonLostContext();
4695
4696 if (context)
4697 {
4698 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4699 }
4700 }
4701 catch(std::bad_alloc&)
4702 {
4703 return error(GL_OUT_OF_MEMORY);
4704 }
4705}
4706
4707void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4708 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004709{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004710 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004711 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004712 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004713
4714 try
4715 {
4716 if (width < 0 || height < 0)
4717 {
4718 return error(GL_INVALID_VALUE);
4719 }
4720
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004721 if (!validReadFormatType(format, type))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004722 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004723 return error(GL_INVALID_OPERATION);
4724 }
4725
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004726 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004727
4728 if (context)
4729 {
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004730 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004731 }
4732 }
4733 catch(std::bad_alloc&)
4734 {
4735 return error(GL_OUT_OF_MEMORY);
4736 }
4737}
4738
4739void __stdcall glReleaseShaderCompiler(void)
4740{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004741 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004742
4743 try
4744 {
4745 gl::Shader::releaseCompiler();
4746 }
4747 catch(std::bad_alloc&)
4748 {
4749 return error(GL_OUT_OF_MEMORY);
4750 }
4751}
4752
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004753void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004754{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004755 EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004756 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004757
4758 try
4759 {
4760 switch (target)
4761 {
4762 case GL_RENDERBUFFER:
4763 break;
4764 default:
4765 return error(GL_INVALID_ENUM);
4766 }
4767
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004768 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004769 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004770 return error(GL_INVALID_ENUM);
4771 }
4772
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004773 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004774 {
4775 return error(GL_INVALID_VALUE);
4776 }
4777
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004778 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004779
4780 if (context)
4781 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004782 if (width > context->getMaximumRenderbufferDimension() ||
4783 height > context->getMaximumRenderbufferDimension() ||
4784 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004785 {
4786 return error(GL_INVALID_VALUE);
4787 }
4788
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004789 GLuint handle = context->getRenderbufferHandle();
4790 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004791 {
4792 return error(GL_INVALID_OPERATION);
4793 }
4794
4795 switch (internalformat)
4796 {
4797 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004798 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004799 break;
4800 case GL_RGBA4:
4801 case GL_RGB5_A1:
4802 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004803 case GL_RGB8_OES:
4804 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004805 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004806 break;
4807 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004808 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004809 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004810 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004811 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004812 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004813 default:
4814 return error(GL_INVALID_ENUM);
4815 }
4816 }
4817 }
4818 catch(std::bad_alloc&)
4819 {
4820 return error(GL_OUT_OF_MEMORY);
4821 }
4822}
4823
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004824void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4825{
4826 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4827}
4828
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004829void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4830{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004831 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004832
4833 try
4834 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004835 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004836
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004837 if (context)
4838 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004839 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004840 }
4841 }
4842 catch(std::bad_alloc&)
4843 {
4844 return error(GL_OUT_OF_MEMORY);
4845 }
4846}
4847
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004848void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4849{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004850 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004851
4852 try
4853 {
4854 if (condition != GL_ALL_COMPLETED_NV)
4855 {
4856 return error(GL_INVALID_ENUM);
4857 }
4858
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004859 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004860
4861 if (context)
4862 {
4863 gl::Fence *fenceObject = context->getFence(fence);
4864
4865 if (fenceObject == NULL)
4866 {
4867 return error(GL_INVALID_OPERATION);
4868 }
4869
4870 fenceObject->setFence(condition);
4871 }
4872 }
4873 catch(std::bad_alloc&)
4874 {
4875 return error(GL_OUT_OF_MEMORY);
4876 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004877}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004878
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004879void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4880{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004881 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004882
4883 try
4884 {
4885 if (width < 0 || height < 0)
4886 {
4887 return error(GL_INVALID_VALUE);
4888 }
4889
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004890 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004891
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004892 if (context)
4893 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004894 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004895 }
4896 }
4897 catch(std::bad_alloc&)
4898 {
4899 return error(GL_OUT_OF_MEMORY);
4900 }
4901}
4902
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004903void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004904{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004905 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004906 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004907 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004908
4909 try
4910 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004911 // No binary shader formats are supported.
4912 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004913 }
4914 catch(std::bad_alloc&)
4915 {
4916 return error(GL_OUT_OF_MEMORY);
4917 }
4918}
4919
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004920void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004921{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004922 EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004923 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004924
4925 try
4926 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004927 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004928 {
4929 return error(GL_INVALID_VALUE);
4930 }
4931
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004932 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004933
4934 if (context)
4935 {
4936 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004937
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004938 if (!shaderObject)
4939 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004940 if (context->getProgram(shader))
4941 {
4942 return error(GL_INVALID_OPERATION);
4943 }
4944 else
4945 {
4946 return error(GL_INVALID_VALUE);
4947 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004948 }
4949
4950 shaderObject->setSource(count, string, length);
4951 }
4952 }
4953 catch(std::bad_alloc&)
4954 {
4955 return error(GL_OUT_OF_MEMORY);
4956 }
4957}
4958
4959void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4960{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004961 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004962}
4963
4964void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4965{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004966 EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004967
4968 try
4969 {
4970 switch (face)
4971 {
4972 case GL_FRONT:
4973 case GL_BACK:
4974 case GL_FRONT_AND_BACK:
4975 break;
4976 default:
4977 return error(GL_INVALID_ENUM);
4978 }
4979
4980 switch (func)
4981 {
4982 case GL_NEVER:
4983 case GL_ALWAYS:
4984 case GL_LESS:
4985 case GL_LEQUAL:
4986 case GL_EQUAL:
4987 case GL_GEQUAL:
4988 case GL_GREATER:
4989 case GL_NOTEQUAL:
4990 break;
4991 default:
4992 return error(GL_INVALID_ENUM);
4993 }
4994
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004995 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004996
4997 if (context)
4998 {
4999 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5000 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005001 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005002 }
5003
5004 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5005 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005006 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005007 }
5008 }
5009 }
5010 catch(std::bad_alloc&)
5011 {
5012 return error(GL_OUT_OF_MEMORY);
5013 }
5014}
5015
5016void __stdcall glStencilMask(GLuint mask)
5017{
5018 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
5019}
5020
5021void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
5022{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005023 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005024
5025 try
5026 {
5027 switch (face)
5028 {
5029 case GL_FRONT:
5030 case GL_BACK:
5031 case GL_FRONT_AND_BACK:
5032 break;
5033 default:
5034 return error(GL_INVALID_ENUM);
5035 }
5036
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005037 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005038
5039 if (context)
5040 {
5041 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5042 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005043 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005044 }
5045
5046 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5047 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005048 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005049 }
5050 }
5051 }
5052 catch(std::bad_alloc&)
5053 {
5054 return error(GL_OUT_OF_MEMORY);
5055 }
5056}
5057
5058void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
5059{
5060 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
5061}
5062
5063void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
5064{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005065 EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005066 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005067
5068 try
5069 {
5070 switch (face)
5071 {
5072 case GL_FRONT:
5073 case GL_BACK:
5074 case GL_FRONT_AND_BACK:
5075 break;
5076 default:
5077 return error(GL_INVALID_ENUM);
5078 }
5079
5080 switch (fail)
5081 {
5082 case GL_ZERO:
5083 case GL_KEEP:
5084 case GL_REPLACE:
5085 case GL_INCR:
5086 case GL_DECR:
5087 case GL_INVERT:
5088 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005089 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005090 break;
5091 default:
5092 return error(GL_INVALID_ENUM);
5093 }
5094
5095 switch (zfail)
5096 {
5097 case GL_ZERO:
5098 case GL_KEEP:
5099 case GL_REPLACE:
5100 case GL_INCR:
5101 case GL_DECR:
5102 case GL_INVERT:
5103 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005104 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005105 break;
5106 default:
5107 return error(GL_INVALID_ENUM);
5108 }
5109
5110 switch (zpass)
5111 {
5112 case GL_ZERO:
5113 case GL_KEEP:
5114 case GL_REPLACE:
5115 case GL_INCR:
5116 case GL_DECR:
5117 case GL_INVERT:
5118 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005119 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005120 break;
5121 default:
5122 return error(GL_INVALID_ENUM);
5123 }
5124
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005125 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005126
5127 if (context)
5128 {
5129 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5130 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005131 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005132 }
5133
5134 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5135 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005136 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005137 }
5138 }
5139 }
5140 catch(std::bad_alloc&)
5141 {
5142 return error(GL_OUT_OF_MEMORY);
5143 }
5144}
5145
daniel@transgaming.comfe208882010-09-01 15:47:57 +00005146GLboolean __stdcall glTestFenceNV(GLuint fence)
5147{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005148 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005149
5150 try
5151 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005152 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005153
5154 if (context)
5155 {
5156 gl::Fence *fenceObject = context->getFence(fence);
5157
5158 if (fenceObject == NULL)
5159 {
5160 return error(GL_INVALID_OPERATION, GL_TRUE);
5161 }
5162
5163 return fenceObject->testFence();
5164 }
5165 }
5166 catch(std::bad_alloc&)
5167 {
5168 error(GL_OUT_OF_MEMORY);
5169 }
5170
5171 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00005172}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005173
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005174void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
5175 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005176{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005177 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005178 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005179 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005180
5181 try
5182 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00005183 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005184 {
5185 return error(GL_INVALID_VALUE);
5186 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005187
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +00005188 if (internalformat != GLint(format))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005189 {
5190 return error(GL_INVALID_OPERATION);
5191 }
5192
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005193 // validate <type> by itself (used as secondary key below)
5194 switch (type)
5195 {
5196 case GL_UNSIGNED_BYTE:
5197 case GL_UNSIGNED_SHORT_5_6_5:
5198 case GL_UNSIGNED_SHORT_4_4_4_4:
5199 case GL_UNSIGNED_SHORT_5_5_5_1:
5200 case GL_UNSIGNED_SHORT:
5201 case GL_UNSIGNED_INT:
5202 case GL_UNSIGNED_INT_24_8_OES:
5203 case GL_HALF_FLOAT_OES:
5204 case GL_FLOAT:
5205 break;
5206 default:
5207 return error(GL_INVALID_ENUM);
5208 }
5209
5210 // validate <format> + <type> combinations
5211 // - invalid <format> -> sets INVALID_ENUM
5212 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005213 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005214 {
5215 case GL_ALPHA:
5216 case GL_LUMINANCE:
5217 case GL_LUMINANCE_ALPHA:
5218 switch (type)
5219 {
5220 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005221 case GL_FLOAT:
5222 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005223 break;
5224 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005225 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005226 }
5227 break;
5228 case GL_RGB:
5229 switch (type)
5230 {
5231 case GL_UNSIGNED_BYTE:
5232 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005233 case GL_FLOAT:
5234 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005235 break;
5236 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005237 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005238 }
5239 break;
5240 case GL_RGBA:
5241 switch (type)
5242 {
5243 case GL_UNSIGNED_BYTE:
5244 case GL_UNSIGNED_SHORT_4_4_4_4:
5245 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005246 case GL_FLOAT:
5247 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005248 break;
5249 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005250 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005251 }
5252 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005253 case GL_BGRA_EXT:
5254 switch (type)
5255 {
5256 case GL_UNSIGNED_BYTE:
5257 break;
5258 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005259 return error(GL_INVALID_OPERATION);
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005260 }
5261 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005262 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
5263 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00005264 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5265 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00005266 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005267 case GL_DEPTH_COMPONENT:
5268 switch (type)
5269 {
5270 case GL_UNSIGNED_SHORT:
5271 case GL_UNSIGNED_INT:
5272 break;
5273 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005274 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005275 }
5276 break;
5277 case GL_DEPTH_STENCIL_OES:
5278 switch (type)
5279 {
5280 case GL_UNSIGNED_INT_24_8_OES:
5281 break;
5282 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005283 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005284 }
5285 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005286 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005287 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005288 }
5289
5290 if (border != 0)
5291 {
5292 return error(GL_INVALID_VALUE);
5293 }
5294
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005295 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005296
5297 if (context)
5298 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00005299 if (level > context->getMaximumTextureLevel())
5300 {
5301 return error(GL_INVALID_VALUE);
5302 }
5303
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005304 switch (target)
5305 {
5306 case GL_TEXTURE_2D:
5307 if (width > (context->getMaximumTextureDimension() >> level) ||
5308 height > (context->getMaximumTextureDimension() >> level))
5309 {
5310 return error(GL_INVALID_VALUE);
5311 }
5312 break;
5313 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5314 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5315 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5316 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5317 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5318 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5319 if (width != height)
5320 {
5321 return error(GL_INVALID_VALUE);
5322 }
5323
5324 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
5325 height > (context->getMaximumCubeTextureDimension() >> level))
5326 {
5327 return error(GL_INVALID_VALUE);
5328 }
5329 break;
5330 default:
5331 return error(GL_INVALID_ENUM);
5332 }
5333
gman@chromium.org50c526d2011-08-10 05:19:44 +00005334 switch (format) {
5335 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5336 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5337 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00005338 {
5339 return error(GL_INVALID_OPERATION);
5340 }
5341 else
5342 {
5343 return error(GL_INVALID_ENUM);
5344 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00005345 break;
5346 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5347 if (context->supportsDXT3Textures())
5348 {
5349 return error(GL_INVALID_OPERATION);
5350 }
5351 else
5352 {
5353 return error(GL_INVALID_ENUM);
5354 }
5355 break;
5356 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5357 if (context->supportsDXT5Textures())
5358 {
5359 return error(GL_INVALID_OPERATION);
5360 }
5361 else
5362 {
5363 return error(GL_INVALID_ENUM);
5364 }
5365 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005366 case GL_DEPTH_COMPONENT:
5367 case GL_DEPTH_STENCIL_OES:
5368 if (!context->supportsDepthTextures())
5369 {
5370 return error(GL_INVALID_VALUE);
5371 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005372 if (target != GL_TEXTURE_2D)
5373 {
5374 return error(GL_INVALID_OPERATION);
5375 }
5376 // OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not
5377 if (pixels != NULL)
5378 {
5379 return error(GL_INVALID_OPERATION);
5380 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005381 break;
gman@chromium.org50c526d2011-08-10 05:19:44 +00005382 default:
5383 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005384 }
5385
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005386 if (type == GL_FLOAT)
5387 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005388 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005389 {
5390 return error(GL_INVALID_ENUM);
5391 }
5392 }
5393 else if (type == GL_HALF_FLOAT_OES)
5394 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005395 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005396 {
5397 return error(GL_INVALID_ENUM);
5398 }
5399 }
5400
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005401 if (target == GL_TEXTURE_2D)
5402 {
5403 gl::Texture2D *texture = context->getTexture2D();
5404
5405 if (!texture)
5406 {
5407 return error(GL_INVALID_OPERATION);
5408 }
5409
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005410 if (texture->isImmutable())
5411 {
5412 return error(GL_INVALID_OPERATION);
5413 }
5414
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005415 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005416 }
5417 else
5418 {
5419 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5420
5421 if (!texture)
5422 {
5423 return error(GL_INVALID_OPERATION);
5424 }
5425
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005426 if (texture->isImmutable())
5427 {
5428 return error(GL_INVALID_OPERATION);
5429 }
5430
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005431 switch (target)
5432 {
5433 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005434 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005435 break;
5436 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005437 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005438 break;
5439 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005440 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005441 break;
5442 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005443 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005444 break;
5445 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005446 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005447 break;
5448 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005449 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005450 break;
5451 default: UNREACHABLE();
5452 }
5453 }
5454 }
5455 }
5456 catch(std::bad_alloc&)
5457 {
5458 return error(GL_OUT_OF_MEMORY);
5459 }
5460}
5461
5462void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5463{
5464 glTexParameteri(target, pname, (GLint)param);
5465}
5466
5467void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5468{
5469 glTexParameteri(target, pname, (GLint)*params);
5470}
5471
5472void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
5473{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005474 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005475
5476 try
5477 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005478 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005479
5480 if (context)
5481 {
5482 gl::Texture *texture;
5483
5484 switch (target)
5485 {
5486 case GL_TEXTURE_2D:
5487 texture = context->getTexture2D();
5488 break;
5489 case GL_TEXTURE_CUBE_MAP:
5490 texture = context->getTextureCubeMap();
5491 break;
5492 default:
5493 return error(GL_INVALID_ENUM);
5494 }
5495
5496 switch (pname)
5497 {
5498 case GL_TEXTURE_WRAP_S:
5499 if (!texture->setWrapS((GLenum)param))
5500 {
5501 return error(GL_INVALID_ENUM);
5502 }
5503 break;
5504 case GL_TEXTURE_WRAP_T:
5505 if (!texture->setWrapT((GLenum)param))
5506 {
5507 return error(GL_INVALID_ENUM);
5508 }
5509 break;
5510 case GL_TEXTURE_MIN_FILTER:
5511 if (!texture->setMinFilter((GLenum)param))
5512 {
5513 return error(GL_INVALID_ENUM);
5514 }
5515 break;
5516 case GL_TEXTURE_MAG_FILTER:
5517 if (!texture->setMagFilter((GLenum)param))
5518 {
5519 return error(GL_INVALID_ENUM);
5520 }
5521 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00005522 case GL_TEXTURE_USAGE_ANGLE:
5523 if (!texture->setUsage((GLenum)param))
5524 {
5525 return error(GL_INVALID_ENUM);
5526 }
5527 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005528 default:
5529 return error(GL_INVALID_ENUM);
5530 }
5531 }
5532 }
5533 catch(std::bad_alloc&)
5534 {
5535 return error(GL_OUT_OF_MEMORY);
5536 }
5537}
5538
5539void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5540{
5541 glTexParameteri(target, pname, *params);
5542}
5543
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005544void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5545{
5546 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5547 target, levels, internalformat, width, height);
5548
5549 try
5550 {
5551 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5552 {
5553 return error(GL_INVALID_ENUM);
5554 }
5555
5556 if (width < 1 || height < 1 || levels < 1)
5557 {
5558 return error(GL_INVALID_VALUE);
5559 }
5560
5561 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5562 {
5563 return error(GL_INVALID_VALUE);
5564 }
5565
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005566 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005567 {
5568 return error(GL_INVALID_OPERATION);
5569 }
5570
5571 GLenum format = gl::ExtractFormat(internalformat);
5572 GLenum type = gl::ExtractType(internalformat);
5573
5574 if (format == GL_NONE || type == GL_NONE)
5575 {
5576 return error(GL_INVALID_ENUM);
5577 }
5578
5579 gl::Context *context = gl::getNonLostContext();
5580
5581 if (context)
5582 {
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005583 switch (target)
5584 {
5585 case GL_TEXTURE_2D:
5586 if (width > context->getMaximumTextureDimension() ||
5587 height > context->getMaximumTextureDimension())
5588 {
5589 return error(GL_INVALID_VALUE);
5590 }
5591 break;
5592 case GL_TEXTURE_CUBE_MAP:
5593 if (width > context->getMaximumCubeTextureDimension() ||
5594 height > context->getMaximumCubeTextureDimension())
5595 {
5596 return error(GL_INVALID_VALUE);
5597 }
5598 break;
5599 default:
5600 return error(GL_INVALID_ENUM);
5601 }
5602
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005603 if (levels != 1 && !context->supportsNonPower2Texture())
5604 {
5605 if (!gl::isPow2(width) || !gl::isPow2(height))
5606 {
5607 return error(GL_INVALID_OPERATION);
5608 }
5609 }
5610
daniel@transgaming.come1077362011-11-11 04:16:50 +00005611 switch (internalformat)
5612 {
5613 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5614 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5615 if (!context->supportsDXT1Textures())
5616 {
5617 return error(GL_INVALID_ENUM);
5618 }
5619 break;
5620 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5621 if (!context->supportsDXT3Textures())
5622 {
5623 return error(GL_INVALID_ENUM);
5624 }
5625 break;
5626 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5627 if (!context->supportsDXT5Textures())
5628 {
5629 return error(GL_INVALID_ENUM);
5630 }
5631 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005632 case GL_RGBA32F_EXT:
5633 case GL_RGB32F_EXT:
5634 case GL_ALPHA32F_EXT:
5635 case GL_LUMINANCE32F_EXT:
5636 case GL_LUMINANCE_ALPHA32F_EXT:
5637 if (!context->supportsFloat32Textures())
5638 {
5639 return error(GL_INVALID_ENUM);
5640 }
5641 break;
5642 case GL_RGBA16F_EXT:
5643 case GL_RGB16F_EXT:
5644 case GL_ALPHA16F_EXT:
5645 case GL_LUMINANCE16F_EXT:
5646 case GL_LUMINANCE_ALPHA16F_EXT:
5647 if (!context->supportsFloat16Textures())
5648 {
5649 return error(GL_INVALID_ENUM);
5650 }
5651 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005652 case GL_DEPTH_COMPONENT16:
5653 case GL_DEPTH_COMPONENT32_OES:
5654 case GL_DEPTH24_STENCIL8_OES:
5655 if (!context->supportsDepthTextures())
5656 {
5657 return error(GL_INVALID_ENUM);
5658 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005659 if (target != GL_TEXTURE_2D)
5660 {
5661 return error(GL_INVALID_OPERATION);
5662 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005663 break;
5664 default:
5665 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005666 }
5667
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005668 if (target == GL_TEXTURE_2D)
5669 {
5670 gl::Texture2D *texture = context->getTexture2D();
5671
5672 if (!texture || texture->id() == 0)
5673 {
5674 return error(GL_INVALID_OPERATION);
5675 }
5676
5677 if (texture->isImmutable())
5678 {
5679 return error(GL_INVALID_OPERATION);
5680 }
5681
5682 texture->storage(levels, internalformat, width, height);
5683 }
5684 else if (target == GL_TEXTURE_CUBE_MAP)
5685 {
5686 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5687
5688 if (!texture || texture->id() == 0)
5689 {
5690 return error(GL_INVALID_OPERATION);
5691 }
5692
5693 if (texture->isImmutable())
5694 {
5695 return error(GL_INVALID_OPERATION);
5696 }
5697
5698 texture->storage(levels, internalformat, width);
5699 }
5700 else UNREACHABLE();
5701 }
5702 }
5703 catch(std::bad_alloc&)
5704 {
5705 return error(GL_OUT_OF_MEMORY);
5706 }
5707}
5708
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005709void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5710 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005711{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005712 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005713 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005714 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005715 target, level, xoffset, yoffset, width, height, format, type, pixels);
5716
5717 try
5718 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00005719 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005720 {
5721 return error(GL_INVALID_ENUM);
5722 }
5723
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005724 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005725 {
5726 return error(GL_INVALID_VALUE);
5727 }
5728
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005729 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5730 {
5731 return error(GL_INVALID_VALUE);
5732 }
5733
daniel@transgaming.com8833dd22012-06-05 19:49:58 +00005734 if (!checkTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005735 {
daniel@transgaming.com8833dd22012-06-05 19:49:58 +00005736 return; // error is set by helper function
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005737 }
5738
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005739 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005740
5741 if (context)
5742 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005743 if (level > context->getMaximumTextureLevel())
5744 {
5745 return error(GL_INVALID_VALUE);
5746 }
5747
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005748 if (format == GL_FLOAT)
5749 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005750 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005751 {
5752 return error(GL_INVALID_ENUM);
5753 }
5754 }
5755 else if (format == GL_HALF_FLOAT_OES)
5756 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005757 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005758 {
5759 return error(GL_INVALID_ENUM);
5760 }
5761 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005762 else if (gl::IsDepthTexture(format))
5763 {
5764 if (!context->supportsDepthTextures())
5765 {
5766 return error(GL_INVALID_ENUM);
5767 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005768 if (target != GL_TEXTURE_2D)
5769 {
5770 return error(GL_INVALID_OPERATION);
5771 }
5772 // OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not
5773 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005774 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005775
daniel@transgaming.com1d2d3c42012-05-31 01:14:15 +00005776 if (width == 0 || height == 0 || pixels == NULL)
5777 {
5778 return;
5779 }
5780
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005781 if (target == GL_TEXTURE_2D)
5782 {
5783 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00005784 if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005785 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005786 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005787 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005788 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005789 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005790 {
5791 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00005792 if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005793 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005794 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005795 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005796 }
5797 else
5798 {
5799 UNREACHABLE();
5800 }
5801 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005802 }
5803 catch(std::bad_alloc&)
5804 {
5805 return error(GL_OUT_OF_MEMORY);
5806 }
5807}
5808
5809void __stdcall glUniform1f(GLint location, GLfloat x)
5810{
5811 glUniform1fv(location, 1, &x);
5812}
5813
5814void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5815{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005816 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005817
5818 try
5819 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005820 if (count < 0)
5821 {
5822 return error(GL_INVALID_VALUE);
5823 }
5824
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005825 if (location == -1)
5826 {
5827 return;
5828 }
5829
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005830 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005831
5832 if (context)
5833 {
5834 gl::Program *program = context->getCurrentProgram();
5835
5836 if (!program)
5837 {
5838 return error(GL_INVALID_OPERATION);
5839 }
5840
5841 if (!program->setUniform1fv(location, count, v))
5842 {
5843 return error(GL_INVALID_OPERATION);
5844 }
5845 }
5846 }
5847 catch(std::bad_alloc&)
5848 {
5849 return error(GL_OUT_OF_MEMORY);
5850 }
5851}
5852
5853void __stdcall glUniform1i(GLint location, GLint x)
5854{
5855 glUniform1iv(location, 1, &x);
5856}
5857
5858void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5859{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005860 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005861
5862 try
5863 {
5864 if (count < 0)
5865 {
5866 return error(GL_INVALID_VALUE);
5867 }
5868
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005869 if (location == -1)
5870 {
5871 return;
5872 }
5873
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005874 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005875
5876 if (context)
5877 {
5878 gl::Program *program = context->getCurrentProgram();
5879
5880 if (!program)
5881 {
5882 return error(GL_INVALID_OPERATION);
5883 }
5884
5885 if (!program->setUniform1iv(location, count, v))
5886 {
5887 return error(GL_INVALID_OPERATION);
5888 }
5889 }
5890 }
5891 catch(std::bad_alloc&)
5892 {
5893 return error(GL_OUT_OF_MEMORY);
5894 }
5895}
5896
5897void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5898{
5899 GLfloat xy[2] = {x, y};
5900
5901 glUniform2fv(location, 1, (GLfloat*)&xy);
5902}
5903
5904void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5905{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005906 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005907
5908 try
5909 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005910 if (count < 0)
5911 {
5912 return error(GL_INVALID_VALUE);
5913 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005914
5915 if (location == -1)
5916 {
5917 return;
5918 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005919
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005920 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005921
5922 if (context)
5923 {
5924 gl::Program *program = context->getCurrentProgram();
5925
5926 if (!program)
5927 {
5928 return error(GL_INVALID_OPERATION);
5929 }
5930
5931 if (!program->setUniform2fv(location, count, v))
5932 {
5933 return error(GL_INVALID_OPERATION);
5934 }
5935 }
5936 }
5937 catch(std::bad_alloc&)
5938 {
5939 return error(GL_OUT_OF_MEMORY);
5940 }
5941}
5942
5943void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5944{
5945 GLint xy[4] = {x, y};
5946
5947 glUniform2iv(location, 1, (GLint*)&xy);
5948}
5949
5950void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5951{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005952 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005953
5954 try
5955 {
5956 if (count < 0)
5957 {
5958 return error(GL_INVALID_VALUE);
5959 }
5960
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005961 if (location == -1)
5962 {
5963 return;
5964 }
5965
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005966 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005967
5968 if (context)
5969 {
5970 gl::Program *program = context->getCurrentProgram();
5971
5972 if (!program)
5973 {
5974 return error(GL_INVALID_OPERATION);
5975 }
5976
5977 if (!program->setUniform2iv(location, count, v))
5978 {
5979 return error(GL_INVALID_OPERATION);
5980 }
5981 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005982 }
5983 catch(std::bad_alloc&)
5984 {
5985 return error(GL_OUT_OF_MEMORY);
5986 }
5987}
5988
5989void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5990{
5991 GLfloat xyz[3] = {x, y, z};
5992
5993 glUniform3fv(location, 1, (GLfloat*)&xyz);
5994}
5995
5996void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5997{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005998 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005999
6000 try
6001 {
6002 if (count < 0)
6003 {
6004 return error(GL_INVALID_VALUE);
6005 }
6006
6007 if (location == -1)
6008 {
6009 return;
6010 }
6011
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006012 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006013
6014 if (context)
6015 {
6016 gl::Program *program = context->getCurrentProgram();
6017
6018 if (!program)
6019 {
6020 return error(GL_INVALID_OPERATION);
6021 }
6022
6023 if (!program->setUniform3fv(location, count, v))
6024 {
6025 return error(GL_INVALID_OPERATION);
6026 }
6027 }
6028 }
6029 catch(std::bad_alloc&)
6030 {
6031 return error(GL_OUT_OF_MEMORY);
6032 }
6033}
6034
6035void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
6036{
6037 GLint xyz[3] = {x, y, z};
6038
6039 glUniform3iv(location, 1, (GLint*)&xyz);
6040}
6041
6042void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
6043{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006044 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006045
6046 try
6047 {
6048 if (count < 0)
6049 {
6050 return error(GL_INVALID_VALUE);
6051 }
6052
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006053 if (location == -1)
6054 {
6055 return;
6056 }
6057
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006058 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006059
6060 if (context)
6061 {
6062 gl::Program *program = context->getCurrentProgram();
6063
6064 if (!program)
6065 {
6066 return error(GL_INVALID_OPERATION);
6067 }
6068
6069 if (!program->setUniform3iv(location, count, v))
6070 {
6071 return error(GL_INVALID_OPERATION);
6072 }
6073 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006074 }
6075 catch(std::bad_alloc&)
6076 {
6077 return error(GL_OUT_OF_MEMORY);
6078 }
6079}
6080
6081void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6082{
6083 GLfloat xyzw[4] = {x, y, z, w};
6084
6085 glUniform4fv(location, 1, (GLfloat*)&xyzw);
6086}
6087
6088void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
6089{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006090 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006091
6092 try
6093 {
6094 if (count < 0)
6095 {
6096 return error(GL_INVALID_VALUE);
6097 }
6098
6099 if (location == -1)
6100 {
6101 return;
6102 }
6103
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006104 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006105
6106 if (context)
6107 {
6108 gl::Program *program = context->getCurrentProgram();
6109
6110 if (!program)
6111 {
6112 return error(GL_INVALID_OPERATION);
6113 }
6114
6115 if (!program->setUniform4fv(location, count, v))
6116 {
6117 return error(GL_INVALID_OPERATION);
6118 }
6119 }
6120 }
6121 catch(std::bad_alloc&)
6122 {
6123 return error(GL_OUT_OF_MEMORY);
6124 }
6125}
6126
6127void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
6128{
6129 GLint xyzw[4] = {x, y, z, w};
6130
6131 glUniform4iv(location, 1, (GLint*)&xyzw);
6132}
6133
6134void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
6135{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006136 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006137
6138 try
6139 {
6140 if (count < 0)
6141 {
6142 return error(GL_INVALID_VALUE);
6143 }
6144
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006145 if (location == -1)
6146 {
6147 return;
6148 }
6149
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006150 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006151
6152 if (context)
6153 {
6154 gl::Program *program = context->getCurrentProgram();
6155
6156 if (!program)
6157 {
6158 return error(GL_INVALID_OPERATION);
6159 }
6160
6161 if (!program->setUniform4iv(location, count, v))
6162 {
6163 return error(GL_INVALID_OPERATION);
6164 }
6165 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006166 }
6167 catch(std::bad_alloc&)
6168 {
6169 return error(GL_OUT_OF_MEMORY);
6170 }
6171}
6172
6173void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6174{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006175 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006176 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006177
6178 try
6179 {
6180 if (count < 0 || transpose != GL_FALSE)
6181 {
6182 return error(GL_INVALID_VALUE);
6183 }
6184
6185 if (location == -1)
6186 {
6187 return;
6188 }
6189
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006190 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006191
6192 if (context)
6193 {
6194 gl::Program *program = context->getCurrentProgram();
6195
6196 if (!program)
6197 {
6198 return error(GL_INVALID_OPERATION);
6199 }
6200
6201 if (!program->setUniformMatrix2fv(location, count, value))
6202 {
6203 return error(GL_INVALID_OPERATION);
6204 }
6205 }
6206 }
6207 catch(std::bad_alloc&)
6208 {
6209 return error(GL_OUT_OF_MEMORY);
6210 }
6211}
6212
6213void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6214{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006215 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006216 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006217
6218 try
6219 {
6220 if (count < 0 || transpose != GL_FALSE)
6221 {
6222 return error(GL_INVALID_VALUE);
6223 }
6224
6225 if (location == -1)
6226 {
6227 return;
6228 }
6229
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006230 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006231
6232 if (context)
6233 {
6234 gl::Program *program = context->getCurrentProgram();
6235
6236 if (!program)
6237 {
6238 return error(GL_INVALID_OPERATION);
6239 }
6240
6241 if (!program->setUniformMatrix3fv(location, count, value))
6242 {
6243 return error(GL_INVALID_OPERATION);
6244 }
6245 }
6246 }
6247 catch(std::bad_alloc&)
6248 {
6249 return error(GL_OUT_OF_MEMORY);
6250 }
6251}
6252
6253void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6254{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006255 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006256 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006257
6258 try
6259 {
6260 if (count < 0 || transpose != GL_FALSE)
6261 {
6262 return error(GL_INVALID_VALUE);
6263 }
6264
6265 if (location == -1)
6266 {
6267 return;
6268 }
6269
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006270 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006271
6272 if (context)
6273 {
6274 gl::Program *program = context->getCurrentProgram();
6275
6276 if (!program)
6277 {
6278 return error(GL_INVALID_OPERATION);
6279 }
6280
6281 if (!program->setUniformMatrix4fv(location, count, value))
6282 {
6283 return error(GL_INVALID_OPERATION);
6284 }
6285 }
6286 }
6287 catch(std::bad_alloc&)
6288 {
6289 return error(GL_OUT_OF_MEMORY);
6290 }
6291}
6292
6293void __stdcall glUseProgram(GLuint program)
6294{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006295 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006296
6297 try
6298 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006299 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006300
6301 if (context)
6302 {
6303 gl::Program *programObject = context->getProgram(program);
6304
daniel@transgaming.comc8478202010-04-13 19:53:35 +00006305 if (!programObject && program != 0)
6306 {
6307 if (context->getShader(program))
6308 {
6309 return error(GL_INVALID_OPERATION);
6310 }
6311 else
6312 {
6313 return error(GL_INVALID_VALUE);
6314 }
6315 }
6316
6317 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006318 {
6319 return error(GL_INVALID_OPERATION);
6320 }
6321
6322 context->useProgram(program);
6323 }
6324 }
6325 catch(std::bad_alloc&)
6326 {
6327 return error(GL_OUT_OF_MEMORY);
6328 }
6329}
6330
6331void __stdcall glValidateProgram(GLuint program)
6332{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006333 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006334
6335 try
6336 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006337 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006338
6339 if (context)
6340 {
6341 gl::Program *programObject = context->getProgram(program);
6342
6343 if (!programObject)
6344 {
6345 if (context->getShader(program))
6346 {
6347 return error(GL_INVALID_OPERATION);
6348 }
6349 else
6350 {
6351 return error(GL_INVALID_VALUE);
6352 }
6353 }
6354
6355 programObject->validate();
6356 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006357 }
6358 catch(std::bad_alloc&)
6359 {
6360 return error(GL_OUT_OF_MEMORY);
6361 }
6362}
6363
6364void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
6365{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006366 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006367
6368 try
6369 {
6370 if (index >= gl::MAX_VERTEX_ATTRIBS)
6371 {
6372 return error(GL_INVALID_VALUE);
6373 }
6374
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006375 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006376
6377 if (context)
6378 {
6379 GLfloat vals[4] = { x, 0, 0, 1 };
6380 context->setVertexAttrib(index, vals);
6381 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006382 }
6383 catch(std::bad_alloc&)
6384 {
6385 return error(GL_OUT_OF_MEMORY);
6386 }
6387}
6388
6389void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
6390{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006391 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006392
6393 try
6394 {
6395 if (index >= gl::MAX_VERTEX_ATTRIBS)
6396 {
6397 return error(GL_INVALID_VALUE);
6398 }
6399
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006400 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006401
6402 if (context)
6403 {
6404 GLfloat vals[4] = { values[0], 0, 0, 1 };
6405 context->setVertexAttrib(index, vals);
6406 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006407 }
6408 catch(std::bad_alloc&)
6409 {
6410 return error(GL_OUT_OF_MEMORY);
6411 }
6412}
6413
6414void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6415{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006416 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006417
6418 try
6419 {
6420 if (index >= gl::MAX_VERTEX_ATTRIBS)
6421 {
6422 return error(GL_INVALID_VALUE);
6423 }
6424
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006425 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006426
6427 if (context)
6428 {
6429 GLfloat vals[4] = { x, y, 0, 1 };
6430 context->setVertexAttrib(index, vals);
6431 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006432 }
6433 catch(std::bad_alloc&)
6434 {
6435 return error(GL_OUT_OF_MEMORY);
6436 }
6437}
6438
6439void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
6440{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006441 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006442
6443 try
6444 {
6445 if (index >= gl::MAX_VERTEX_ATTRIBS)
6446 {
6447 return error(GL_INVALID_VALUE);
6448 }
6449
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006450 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006451
6452 if (context)
6453 {
6454 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6455 context->setVertexAttrib(index, vals);
6456 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006457 }
6458 catch(std::bad_alloc&)
6459 {
6460 return error(GL_OUT_OF_MEMORY);
6461 }
6462}
6463
6464void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6465{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006466 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006467
6468 try
6469 {
6470 if (index >= gl::MAX_VERTEX_ATTRIBS)
6471 {
6472 return error(GL_INVALID_VALUE);
6473 }
6474
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006475 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006476
6477 if (context)
6478 {
6479 GLfloat vals[4] = { x, y, z, 1 };
6480 context->setVertexAttrib(index, vals);
6481 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006482 }
6483 catch(std::bad_alloc&)
6484 {
6485 return error(GL_OUT_OF_MEMORY);
6486 }
6487}
6488
6489void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
6490{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006491 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006492
6493 try
6494 {
6495 if (index >= gl::MAX_VERTEX_ATTRIBS)
6496 {
6497 return error(GL_INVALID_VALUE);
6498 }
6499
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006500 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006501
6502 if (context)
6503 {
6504 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6505 context->setVertexAttrib(index, vals);
6506 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006507 }
6508 catch(std::bad_alloc&)
6509 {
6510 return error(GL_OUT_OF_MEMORY);
6511 }
6512}
6513
6514void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6515{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006516 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006517
6518 try
6519 {
6520 if (index >= gl::MAX_VERTEX_ATTRIBS)
6521 {
6522 return error(GL_INVALID_VALUE);
6523 }
6524
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006525 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006526
6527 if (context)
6528 {
6529 GLfloat vals[4] = { x, y, z, w };
6530 context->setVertexAttrib(index, vals);
6531 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006532 }
6533 catch(std::bad_alloc&)
6534 {
6535 return error(GL_OUT_OF_MEMORY);
6536 }
6537}
6538
6539void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
6540{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006541 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006542
6543 try
6544 {
6545 if (index >= gl::MAX_VERTEX_ATTRIBS)
6546 {
6547 return error(GL_INVALID_VALUE);
6548 }
6549
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006550 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006551
6552 if (context)
6553 {
6554 context->setVertexAttrib(index, values);
6555 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006556 }
6557 catch(std::bad_alloc&)
6558 {
6559 return error(GL_OUT_OF_MEMORY);
6560 }
6561}
6562
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00006563void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
6564{
6565 EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
6566
6567 try
6568 {
6569 if (index >= gl::MAX_VERTEX_ATTRIBS)
6570 {
6571 return error(GL_INVALID_VALUE);
6572 }
6573
6574 gl::Context *context = gl::getNonLostContext();
6575
6576 if (context)
6577 {
6578 context->setVertexAttribDivisor(index, divisor);
6579 }
6580 }
6581 catch(std::bad_alloc&)
6582 {
6583 return error(GL_OUT_OF_MEMORY);
6584 }
6585}
6586
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006587void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006588{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006589 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006590 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006591 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006592
6593 try
6594 {
6595 if (index >= gl::MAX_VERTEX_ATTRIBS)
6596 {
6597 return error(GL_INVALID_VALUE);
6598 }
6599
6600 if (size < 1 || size > 4)
6601 {
6602 return error(GL_INVALID_VALUE);
6603 }
6604
6605 switch (type)
6606 {
6607 case GL_BYTE:
6608 case GL_UNSIGNED_BYTE:
6609 case GL_SHORT:
6610 case GL_UNSIGNED_SHORT:
6611 case GL_FIXED:
6612 case GL_FLOAT:
6613 break;
6614 default:
6615 return error(GL_INVALID_ENUM);
6616 }
6617
6618 if (stride < 0)
6619 {
6620 return error(GL_INVALID_VALUE);
6621 }
6622
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006623 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006624
6625 if (context)
6626 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006627 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006628 }
6629 }
6630 catch(std::bad_alloc&)
6631 {
6632 return error(GL_OUT_OF_MEMORY);
6633 }
6634}
6635
6636void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6637{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006638 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006639
6640 try
6641 {
6642 if (width < 0 || height < 0)
6643 {
6644 return error(GL_INVALID_VALUE);
6645 }
6646
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006647 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006648
6649 if (context)
6650 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006651 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006652 }
6653 }
6654 catch(std::bad_alloc&)
6655 {
6656 return error(GL_OUT_OF_MEMORY);
6657 }
6658}
6659
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006660void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6661 GLbitfield mask, GLenum filter)
6662{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006663 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006664 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6665 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6666 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6667
6668 try
6669 {
6670 switch (filter)
6671 {
6672 case GL_NEAREST:
6673 break;
6674 default:
6675 return error(GL_INVALID_ENUM);
6676 }
6677
6678 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6679 {
6680 return error(GL_INVALID_VALUE);
6681 }
6682
6683 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6684 {
6685 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6686 return error(GL_INVALID_OPERATION);
6687 }
6688
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006689 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006690
6691 if (context)
6692 {
6693 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6694 {
6695 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6696 return error(GL_INVALID_OPERATION);
6697 }
6698
6699 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6700 }
6701 }
6702 catch(std::bad_alloc&)
6703 {
6704 return error(GL_OUT_OF_MEMORY);
6705 }
6706}
6707
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006708void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6709 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006710{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006711 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006712 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006713 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006714 target, level, internalformat, width, height, depth, border, format, type, pixels);
6715
6716 try
6717 {
6718 UNIMPLEMENTED(); // FIXME
6719 }
6720 catch(std::bad_alloc&)
6721 {
6722 return error(GL_OUT_OF_MEMORY);
6723 }
6724}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006725
6726__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6727{
6728 struct Extension
6729 {
6730 const char *name;
6731 __eglMustCastToProperFunctionPointerType address;
6732 };
6733
6734 static const Extension glExtensions[] =
6735 {
6736 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006737 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006738 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006739 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6740 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6741 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6742 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6743 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6744 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6745 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006746 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006747 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006748 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6749 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6750 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6751 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00006752 {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT},
6753 {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT},
6754 {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT},
6755 {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT},
6756 {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
6757 {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
6758 {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
daniel@transgaming.comdce02fd2012-01-27 15:39:51 +00006759 {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE},
6760 {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE},
6761 {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006762 };
6763
6764 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6765 {
6766 if (strcmp(procname, glExtensions[ext].name) == 0)
6767 {
6768 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6769 }
6770 }
6771
6772 return NULL;
6773}
6774
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006775// Non-public functions used by EGL
6776
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006777bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006778{
6779 EVENT("(egl::Surface* surface = 0x%0.8p)",
6780 surface);
6781
6782 try
6783 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006784 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006785
6786 if (context)
6787 {
6788 gl::Texture2D *textureObject = context->getTexture2D();
6789
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006790 if (textureObject->isImmutable())
6791 {
6792 return false;
6793 }
6794
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006795 if (textureObject)
6796 {
6797 textureObject->bindTexImage(surface);
6798 }
6799 }
6800 }
6801 catch(std::bad_alloc&)
6802 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006803 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006804 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006805
6806 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006807}
6808
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006809}