blob: fba16d44b63d67ce60c397c6459223d9b5d9fe8f [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
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00002940 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
2941 if (!programBinary)
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002942 {
2943 return error(GL_INVALID_OPERATION, -1);
2944 }
2945
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00002946 return programBinary->getAttributeLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002947 }
2948 }
2949 catch(std::bad_alloc&)
2950 {
2951 return error(GL_OUT_OF_MEMORY, -1);
2952 }
2953
2954 return -1;
2955}
2956
2957void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2958{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002959 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002960
2961 try
2962 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002963 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002964
2965 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002966 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002967 if (!(context->getBooleanv(pname, params)))
2968 {
2969 GLenum nativeType;
2970 unsigned int numParams = 0;
2971 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2972 return error(GL_INVALID_ENUM);
2973
2974 if (numParams == 0)
2975 return; // it is known that the pname is valid, but there are no parameters to return
2976
2977 if (nativeType == GL_FLOAT)
2978 {
2979 GLfloat *floatParams = NULL;
2980 floatParams = new GLfloat[numParams];
2981
2982 context->getFloatv(pname, floatParams);
2983
2984 for (unsigned int i = 0; i < numParams; ++i)
2985 {
2986 if (floatParams[i] == 0.0f)
2987 params[i] = GL_FALSE;
2988 else
2989 params[i] = GL_TRUE;
2990 }
2991
2992 delete [] floatParams;
2993 }
2994 else if (nativeType == GL_INT)
2995 {
2996 GLint *intParams = NULL;
2997 intParams = new GLint[numParams];
2998
2999 context->getIntegerv(pname, intParams);
3000
3001 for (unsigned int i = 0; i < numParams; ++i)
3002 {
3003 if (intParams[i] == 0)
3004 params[i] = GL_FALSE;
3005 else
3006 params[i] = GL_TRUE;
3007 }
3008
3009 delete [] intParams;
3010 }
3011 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003012 }
3013 }
3014 catch(std::bad_alloc&)
3015 {
3016 return error(GL_OUT_OF_MEMORY);
3017 }
3018}
3019
3020void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
3021{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003022 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 +00003023
3024 try
3025 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003026 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00003027
3028 if (context)
3029 {
3030 gl::Buffer *buffer;
3031
3032 switch (target)
3033 {
3034 case GL_ARRAY_BUFFER:
3035 buffer = context->getArrayBuffer();
3036 break;
3037 case GL_ELEMENT_ARRAY_BUFFER:
3038 buffer = context->getElementArrayBuffer();
3039 break;
3040 default: return error(GL_INVALID_ENUM);
3041 }
3042
3043 if (!buffer)
3044 {
3045 // A null buffer means that "0" is bound to the requested buffer target
3046 return error(GL_INVALID_OPERATION);
3047 }
3048
3049 switch (pname)
3050 {
3051 case GL_BUFFER_USAGE:
3052 *params = buffer->usage();
3053 break;
3054 case GL_BUFFER_SIZE:
3055 *params = buffer->size();
3056 break;
3057 default: return error(GL_INVALID_ENUM);
3058 }
3059 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003060 }
3061 catch(std::bad_alloc&)
3062 {
3063 return error(GL_OUT_OF_MEMORY);
3064 }
3065}
3066
3067GLenum __stdcall glGetError(void)
3068{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003069 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003070
3071 gl::Context *context = gl::getContext();
3072
3073 if (context)
3074 {
daniel@transgaming.com82b28912011-12-12 21:01:35 +00003075 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003076 }
3077
3078 return GL_NO_ERROR;
3079}
3080
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003081void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
3082{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003083 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003084
3085 try
3086 {
3087
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003088 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003089
3090 if (context)
3091 {
3092 gl::Fence *fenceObject = context->getFence(fence);
3093
3094 if (fenceObject == NULL)
3095 {
3096 return error(GL_INVALID_OPERATION);
3097 }
3098
3099 fenceObject->getFenceiv(pname, params);
3100 }
3101 }
3102 catch(std::bad_alloc&)
3103 {
3104 return error(GL_OUT_OF_MEMORY);
3105 }
3106}
3107
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003108void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
3109{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003110 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003111
3112 try
3113 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003114 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003115
3116 if (context)
3117 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003118 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003119 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003120 GLenum nativeType;
3121 unsigned int numParams = 0;
3122 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3123 return error(GL_INVALID_ENUM);
3124
3125 if (numParams == 0)
3126 return; // it is known that the pname is valid, but that there are no parameters to return.
3127
3128 if (nativeType == GL_BOOL)
3129 {
3130 GLboolean *boolParams = NULL;
3131 boolParams = new GLboolean[numParams];
3132
3133 context->getBooleanv(pname, boolParams);
3134
3135 for (unsigned int i = 0; i < numParams; ++i)
3136 {
3137 if (boolParams[i] == GL_FALSE)
3138 params[i] = 0.0f;
3139 else
3140 params[i] = 1.0f;
3141 }
3142
3143 delete [] boolParams;
3144 }
3145 else if (nativeType == GL_INT)
3146 {
3147 GLint *intParams = NULL;
3148 intParams = new GLint[numParams];
3149
3150 context->getIntegerv(pname, intParams);
3151
3152 for (unsigned int i = 0; i < numParams; ++i)
3153 {
3154 params[i] = (GLfloat)intParams[i];
3155 }
3156
3157 delete [] intParams;
3158 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003159 }
3160 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003161 }
3162 catch(std::bad_alloc&)
3163 {
3164 return error(GL_OUT_OF_MEMORY);
3165 }
3166}
3167
3168void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
3169{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003170 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 +00003171 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003172
3173 try
3174 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003175 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003176
3177 if (context)
3178 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003179 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003180 {
3181 return error(GL_INVALID_ENUM);
3182 }
3183
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003184 gl::Framebuffer *framebuffer = NULL;
3185 if (target == GL_READ_FRAMEBUFFER_ANGLE)
3186 {
3187 if(context->getReadFramebufferHandle() == 0)
3188 {
3189 return error(GL_INVALID_OPERATION);
3190 }
3191
3192 framebuffer = context->getReadFramebuffer();
3193 }
3194 else
3195 {
3196 if (context->getDrawFramebufferHandle() == 0)
3197 {
3198 return error(GL_INVALID_OPERATION);
3199 }
3200
3201 framebuffer = context->getDrawFramebuffer();
3202 }
3203
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003204 GLenum attachmentType;
3205 GLuint attachmentHandle;
3206 switch (attachment)
3207 {
3208 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003209 attachmentType = framebuffer->getColorbufferType();
3210 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003211 break;
3212 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003213 attachmentType = framebuffer->getDepthbufferType();
3214 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003215 break;
3216 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003217 attachmentType = framebuffer->getStencilbufferType();
3218 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003219 break;
3220 default: return error(GL_INVALID_ENUM);
3221 }
3222
3223 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00003224 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003225 {
3226 attachmentObjectType = attachmentType;
3227 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +00003228 else if (gl::IsInternalTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003229 {
3230 attachmentObjectType = GL_TEXTURE;
3231 }
apatrick@chromium.orga1d80592012-01-25 21:52:10 +00003232 else
3233 {
3234 UNREACHABLE();
3235 return;
3236 }
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003237
3238 switch (pname)
3239 {
3240 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3241 *params = attachmentObjectType;
3242 break;
3243 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3244 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
3245 {
3246 *params = attachmentHandle;
3247 }
3248 else
3249 {
3250 return error(GL_INVALID_ENUM);
3251 }
3252 break;
3253 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3254 if (attachmentObjectType == GL_TEXTURE)
3255 {
3256 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
3257 }
3258 else
3259 {
3260 return error(GL_INVALID_ENUM);
3261 }
3262 break;
3263 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3264 if (attachmentObjectType == GL_TEXTURE)
3265 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00003266 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003267 {
3268 *params = attachmentType;
3269 }
3270 else
3271 {
3272 *params = 0;
3273 }
3274 }
3275 else
3276 {
3277 return error(GL_INVALID_ENUM);
3278 }
3279 break;
3280 default:
3281 return error(GL_INVALID_ENUM);
3282 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003283 }
3284 }
3285 catch(std::bad_alloc&)
3286 {
3287 return error(GL_OUT_OF_MEMORY);
3288 }
3289}
3290
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00003291GLenum __stdcall glGetGraphicsResetStatusEXT(void)
3292{
3293 EVENT("()");
3294
3295 try
3296 {
3297 gl::Context *context = gl::getContext();
3298
3299 if (context)
3300 {
3301 return context->getResetStatus();
3302 }
3303
3304 return GL_NO_ERROR;
3305 }
3306 catch(std::bad_alloc&)
3307 {
3308 return GL_OUT_OF_MEMORY;
3309 }
3310}
3311
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003312void __stdcall glGetIntegerv(GLenum pname, GLint* params)
3313{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003314 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003315
3316 try
3317 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003318 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003319
3320 if (context)
3321 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003322 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003323 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003324 GLenum nativeType;
3325 unsigned int numParams = 0;
3326 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3327 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003328
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003329 if (numParams == 0)
3330 return; // it is known that pname is valid, but there are no parameters to return
3331
3332 if (nativeType == GL_BOOL)
3333 {
3334 GLboolean *boolParams = NULL;
3335 boolParams = new GLboolean[numParams];
3336
3337 context->getBooleanv(pname, boolParams);
3338
3339 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003340 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003341 if (boolParams[i] == GL_FALSE)
3342 params[i] = 0;
3343 else
3344 params[i] = 1;
3345 }
3346
3347 delete [] boolParams;
3348 }
3349 else if (nativeType == GL_FLOAT)
3350 {
3351 GLfloat *floatParams = NULL;
3352 floatParams = new GLfloat[numParams];
3353
3354 context->getFloatv(pname, floatParams);
3355
3356 for (unsigned int i = 0; i < numParams; ++i)
3357 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00003358 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 +00003359 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003360 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003361 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003362 else
3363 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 +00003364 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003365
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003366 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003367 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003368 }
3369 }
3370 }
3371 catch(std::bad_alloc&)
3372 {
3373 return error(GL_OUT_OF_MEMORY);
3374 }
3375}
3376
3377void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3378{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003379 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003380
3381 try
3382 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003383 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003384
3385 if (context)
3386 {
3387 gl::Program *programObject = context->getProgram(program);
3388
3389 if (!programObject)
3390 {
3391 return error(GL_INVALID_VALUE);
3392 }
3393
3394 switch (pname)
3395 {
3396 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003397 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003398 return;
3399 case GL_LINK_STATUS:
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003400 *params = programObject->getProgramBinary() != NULL;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003401 return;
3402 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003403 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003404 return;
3405 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003406 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003407 return;
3408 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003409 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003410 return;
3411 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003412 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003413 return;
3414 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003415 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003416 return;
3417 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003418 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003419 return;
3420 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003421 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003422 return;
3423 default:
3424 return error(GL_INVALID_ENUM);
3425 }
3426 }
3427 }
3428 catch(std::bad_alloc&)
3429 {
3430 return error(GL_OUT_OF_MEMORY);
3431 }
3432}
3433
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003434void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003435{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003436 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 +00003437 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003438
3439 try
3440 {
3441 if (bufsize < 0)
3442 {
3443 return error(GL_INVALID_VALUE);
3444 }
3445
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003446 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003447
3448 if (context)
3449 {
3450 gl::Program *programObject = context->getProgram(program);
3451
3452 if (!programObject)
3453 {
3454 return error(GL_INVALID_VALUE);
3455 }
3456
3457 programObject->getInfoLog(bufsize, length, infolog);
3458 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003459 }
3460 catch(std::bad_alloc&)
3461 {
3462 return error(GL_OUT_OF_MEMORY);
3463 }
3464}
3465
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003466void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3467{
3468 EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
3469
3470 try
3471 {
3472 switch (pname)
3473 {
3474 case GL_CURRENT_QUERY_EXT:
3475 break;
3476 default:
3477 return error(GL_INVALID_ENUM);
3478 }
3479
3480 gl::Context *context = gl::getNonLostContext();
3481
3482 if (context)
3483 {
3484 params[0] = context->getActiveQuery(target);
3485 }
3486 }
3487 catch(std::bad_alloc&)
3488 {
3489 return error(GL_OUT_OF_MEMORY);
3490 }
3491}
3492
3493void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
3494{
3495 EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
3496
3497 try
3498 {
3499 switch (pname)
3500 {
3501 case GL_QUERY_RESULT_EXT:
3502 case GL_QUERY_RESULT_AVAILABLE_EXT:
3503 break;
3504 default:
3505 return error(GL_INVALID_ENUM);
3506 }
3507 gl::Context *context = gl::getNonLostContext();
3508
3509 if (context)
3510 {
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003511 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
3512
3513 if (!queryObject)
3514 {
3515 return error(GL_INVALID_OPERATION);
3516 }
3517
3518 if (context->getActiveQuery(queryObject->getType()) == id)
3519 {
3520 return error(GL_INVALID_OPERATION);
3521 }
3522
3523 switch(pname)
3524 {
3525 case GL_QUERY_RESULT_EXT:
3526 params[0] = queryObject->getResult();
3527 break;
3528 case GL_QUERY_RESULT_AVAILABLE_EXT:
3529 params[0] = queryObject->isResultAvailable();
3530 break;
3531 default:
3532 ASSERT(false);
3533 }
3534 }
3535 }
3536 catch(std::bad_alloc&)
3537 {
3538 return error(GL_OUT_OF_MEMORY);
3539 }
3540}
3541
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003542void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3543{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003544 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 +00003545
3546 try
3547 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003548 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003549
3550 if (context)
3551 {
3552 if (target != GL_RENDERBUFFER)
3553 {
3554 return error(GL_INVALID_ENUM);
3555 }
3556
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003557 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003558 {
3559 return error(GL_INVALID_OPERATION);
3560 }
3561
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003562 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003563
3564 switch (pname)
3565 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003566 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3567 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3568 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3569 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3570 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3571 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3572 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3573 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3574 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003575 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003576 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003577 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003578 *params = renderbuffer->getSamples();
3579 }
3580 else
3581 {
3582 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003583 }
3584 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003585 default:
3586 return error(GL_INVALID_ENUM);
3587 }
3588 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003589 }
3590 catch(std::bad_alloc&)
3591 {
3592 return error(GL_OUT_OF_MEMORY);
3593 }
3594}
3595
3596void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3597{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003598 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003599
3600 try
3601 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003602 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003603
3604 if (context)
3605 {
3606 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003607
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003608 if (!shaderObject)
3609 {
3610 return error(GL_INVALID_VALUE);
3611 }
3612
3613 switch (pname)
3614 {
3615 case GL_SHADER_TYPE:
3616 *params = shaderObject->getType();
3617 return;
3618 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003619 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003620 return;
3621 case GL_COMPILE_STATUS:
3622 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3623 return;
3624 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003625 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003626 return;
3627 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003628 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003629 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003630 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3631 *params = shaderObject->getTranslatedSourceLength();
3632 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003633 default:
3634 return error(GL_INVALID_ENUM);
3635 }
3636 }
3637 }
3638 catch(std::bad_alloc&)
3639 {
3640 return error(GL_OUT_OF_MEMORY);
3641 }
3642}
3643
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003644void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003645{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003646 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 +00003647 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003648
3649 try
3650 {
3651 if (bufsize < 0)
3652 {
3653 return error(GL_INVALID_VALUE);
3654 }
3655
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003656 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003657
3658 if (context)
3659 {
3660 gl::Shader *shaderObject = context->getShader(shader);
3661
3662 if (!shaderObject)
3663 {
3664 return error(GL_INVALID_VALUE);
3665 }
3666
3667 shaderObject->getInfoLog(bufsize, length, infolog);
3668 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003669 }
3670 catch(std::bad_alloc&)
3671 {
3672 return error(GL_OUT_OF_MEMORY);
3673 }
3674}
3675
3676void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3677{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003678 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 +00003679 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003680
3681 try
3682 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003683 switch (shadertype)
3684 {
3685 case GL_VERTEX_SHADER:
3686 case GL_FRAGMENT_SHADER:
3687 break;
3688 default:
3689 return error(GL_INVALID_ENUM);
3690 }
3691
3692 switch (precisiontype)
3693 {
3694 case GL_LOW_FLOAT:
3695 case GL_MEDIUM_FLOAT:
3696 case GL_HIGH_FLOAT:
3697 // Assume IEEE 754 precision
3698 range[0] = 127;
3699 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003700 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003701 break;
3702 case GL_LOW_INT:
3703 case GL_MEDIUM_INT:
3704 case GL_HIGH_INT:
3705 // Some (most) hardware only supports single-precision floating-point numbers,
3706 // which can accurately represent integers up to +/-16777216
3707 range[0] = 24;
3708 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003709 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003710 break;
3711 default:
3712 return error(GL_INVALID_ENUM);
3713 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003714 }
3715 catch(std::bad_alloc&)
3716 {
3717 return error(GL_OUT_OF_MEMORY);
3718 }
3719}
3720
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003721void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003722{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003723 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 +00003724 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003725
3726 try
3727 {
3728 if (bufsize < 0)
3729 {
3730 return error(GL_INVALID_VALUE);
3731 }
3732
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003733 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003734
3735 if (context)
3736 {
3737 gl::Shader *shaderObject = context->getShader(shader);
3738
3739 if (!shaderObject)
3740 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003741 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003742 }
3743
3744 shaderObject->getSource(bufsize, length, source);
3745 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003746 }
3747 catch(std::bad_alloc&)
3748 {
3749 return error(GL_OUT_OF_MEMORY);
3750 }
3751}
3752
zmo@google.coma574f782011-10-03 21:45:23 +00003753void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3754{
3755 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3756 shader, bufsize, length, source);
3757
3758 try
3759 {
3760 if (bufsize < 0)
3761 {
3762 return error(GL_INVALID_VALUE);
3763 }
3764
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003765 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003766
3767 if (context)
3768 {
3769 gl::Shader *shaderObject = context->getShader(shader);
3770
3771 if (!shaderObject)
3772 {
3773 return error(GL_INVALID_OPERATION);
3774 }
3775
3776 shaderObject->getTranslatedSource(bufsize, length, source);
3777 }
3778 }
3779 catch(std::bad_alloc&)
3780 {
3781 return error(GL_OUT_OF_MEMORY);
3782 }
3783}
3784
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003785const GLubyte* __stdcall glGetString(GLenum name)
3786{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003787 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003788
3789 try
3790 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003791 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003792
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003793 switch (name)
3794 {
3795 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003796 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003797 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003798 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003799 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003800 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003801 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003802 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003803 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003804 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003805 default:
3806 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3807 }
3808 }
3809 catch(std::bad_alloc&)
3810 {
3811 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3812 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003813}
3814
3815void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3816{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003817 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 +00003818
3819 try
3820 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003821 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003822
3823 if (context)
3824 {
3825 gl::Texture *texture;
3826
3827 switch (target)
3828 {
3829 case GL_TEXTURE_2D:
3830 texture = context->getTexture2D();
3831 break;
3832 case GL_TEXTURE_CUBE_MAP:
3833 texture = context->getTextureCubeMap();
3834 break;
3835 default:
3836 return error(GL_INVALID_ENUM);
3837 }
3838
3839 switch (pname)
3840 {
3841 case GL_TEXTURE_MAG_FILTER:
3842 *params = (GLfloat)texture->getMagFilter();
3843 break;
3844 case GL_TEXTURE_MIN_FILTER:
3845 *params = (GLfloat)texture->getMinFilter();
3846 break;
3847 case GL_TEXTURE_WRAP_S:
3848 *params = (GLfloat)texture->getWrapS();
3849 break;
3850 case GL_TEXTURE_WRAP_T:
3851 *params = (GLfloat)texture->getWrapT();
3852 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003853 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3854 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3855 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003856 case GL_TEXTURE_USAGE_ANGLE:
3857 *params = (GLfloat)texture->getUsage();
3858 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003859 default:
3860 return error(GL_INVALID_ENUM);
3861 }
3862 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003863 }
3864 catch(std::bad_alloc&)
3865 {
3866 return error(GL_OUT_OF_MEMORY);
3867 }
3868}
3869
3870void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3871{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003872 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 +00003873
3874 try
3875 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003876 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003877
3878 if (context)
3879 {
3880 gl::Texture *texture;
3881
3882 switch (target)
3883 {
3884 case GL_TEXTURE_2D:
3885 texture = context->getTexture2D();
3886 break;
3887 case GL_TEXTURE_CUBE_MAP:
3888 texture = context->getTextureCubeMap();
3889 break;
3890 default:
3891 return error(GL_INVALID_ENUM);
3892 }
3893
3894 switch (pname)
3895 {
3896 case GL_TEXTURE_MAG_FILTER:
3897 *params = texture->getMagFilter();
3898 break;
3899 case GL_TEXTURE_MIN_FILTER:
3900 *params = texture->getMinFilter();
3901 break;
3902 case GL_TEXTURE_WRAP_S:
3903 *params = texture->getWrapS();
3904 break;
3905 case GL_TEXTURE_WRAP_T:
3906 *params = texture->getWrapT();
3907 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003908 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3909 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3910 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003911 case GL_TEXTURE_USAGE_ANGLE:
3912 *params = texture->getUsage();
3913 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003914 default:
3915 return error(GL_INVALID_ENUM);
3916 }
3917 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003918 }
3919 catch(std::bad_alloc&)
3920 {
3921 return error(GL_OUT_OF_MEMORY);
3922 }
3923}
3924
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003925void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3926{
3927 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3928 program, location, bufSize, params);
3929
3930 try
3931 {
3932 if (bufSize < 0)
3933 {
3934 return error(GL_INVALID_VALUE);
3935 }
3936
3937 gl::Context *context = gl::getNonLostContext();
3938
3939 if (context)
3940 {
3941 if (program == 0)
3942 {
3943 return error(GL_INVALID_VALUE);
3944 }
3945
3946 gl::Program *programObject = context->getProgram(program);
3947
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003948 if (!programObject)
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003949 {
3950 return error(GL_INVALID_OPERATION);
3951 }
3952
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003953 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
3954 if (!programBinary)
3955 {
3956 return error(GL_INVALID_OPERATION);
3957 }
3958
3959 if (!programBinary->getUniformfv(location, &bufSize, params))
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003960 {
3961 return error(GL_INVALID_OPERATION);
3962 }
3963 }
3964 }
3965 catch(std::bad_alloc&)
3966 {
3967 return error(GL_OUT_OF_MEMORY);
3968 }
3969}
3970
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003971void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3972{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003973 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003974
3975 try
3976 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003977 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003978
3979 if (context)
3980 {
3981 if (program == 0)
3982 {
3983 return error(GL_INVALID_VALUE);
3984 }
3985
3986 gl::Program *programObject = context->getProgram(program);
3987
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003988 if (!programObject)
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003989 {
3990 return error(GL_INVALID_OPERATION);
3991 }
3992
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003993 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
3994 if (!programBinary)
3995 {
3996 return error(GL_INVALID_OPERATION);
3997 }
3998
3999 if (!programBinary->getUniformfv(location, NULL, params))
daniel@transgaming.com9a849122011-11-12 03:18:00 +00004000 {
4001 return error(GL_INVALID_OPERATION);
4002 }
4003 }
4004 }
4005 catch(std::bad_alloc&)
4006 {
4007 return error(GL_OUT_OF_MEMORY);
4008 }
4009}
4010
4011void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
4012{
4013 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
4014 program, location, bufSize, params);
4015
4016 try
4017 {
4018 if (bufSize < 0)
4019 {
4020 return error(GL_INVALID_VALUE);
4021 }
4022
4023 gl::Context *context = gl::getNonLostContext();
4024
4025 if (context)
4026 {
4027 if (program == 0)
4028 {
4029 return error(GL_INVALID_VALUE);
4030 }
4031
4032 gl::Program *programObject = context->getProgram(program);
4033
daniel@transgaming.com9a849122011-11-12 03:18:00 +00004034 if (!programObject)
4035 {
4036 return error(GL_INVALID_OPERATION);
4037 }
4038
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004039 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4040 if (!programBinary)
4041 {
4042 return error(GL_INVALID_OPERATION);
4043 }
4044
4045 if (!programBinary->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004046 {
4047 return error(GL_INVALID_OPERATION);
4048 }
4049 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004050 }
4051 catch(std::bad_alloc&)
4052 {
4053 return error(GL_OUT_OF_MEMORY);
4054 }
4055}
4056
4057void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
4058{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004059 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004060
4061 try
4062 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004063 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004064
4065 if (context)
4066 {
4067 if (program == 0)
4068 {
4069 return error(GL_INVALID_VALUE);
4070 }
4071
4072 gl::Program *programObject = context->getProgram(program);
4073
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004074 if (!programObject)
4075 {
4076 return error(GL_INVALID_OPERATION);
4077 }
4078
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004079 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4080 if (!programBinary)
4081 {
4082 return error(GL_INVALID_OPERATION);
4083 }
4084
4085 if (!programBinary->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004086 {
4087 return error(GL_INVALID_OPERATION);
4088 }
4089 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004090 }
4091 catch(std::bad_alloc&)
4092 {
4093 return error(GL_OUT_OF_MEMORY);
4094 }
4095}
4096
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004097int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004098{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004099 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004100
4101 try
4102 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004103 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004104
4105 if (strstr(name, "gl_") == name)
4106 {
4107 return -1;
4108 }
4109
4110 if (context)
4111 {
4112 gl::Program *programObject = context->getProgram(program);
4113
4114 if (!programObject)
4115 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00004116 if (context->getShader(program))
4117 {
4118 return error(GL_INVALID_OPERATION, -1);
4119 }
4120 else
4121 {
4122 return error(GL_INVALID_VALUE, -1);
4123 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004124 }
4125
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004126 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4127 if (!programBinary)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004128 {
4129 return error(GL_INVALID_OPERATION, -1);
4130 }
4131
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004132 return programBinary->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004133 }
4134 }
4135 catch(std::bad_alloc&)
4136 {
4137 return error(GL_OUT_OF_MEMORY, -1);
4138 }
4139
4140 return -1;
4141}
4142
4143void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
4144{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004145 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004146
4147 try
4148 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004149 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004150
daniel@transgaming.come0078962010-04-15 20:45:08 +00004151 if (context)
4152 {
4153 if (index >= gl::MAX_VERTEX_ATTRIBS)
4154 {
4155 return error(GL_INVALID_VALUE);
4156 }
4157
daniel@transgaming.com83921382011-01-08 05:46:00 +00004158 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004159
daniel@transgaming.come0078962010-04-15 20:45:08 +00004160 switch (pname)
4161 {
4162 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004163 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004164 break;
4165 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004166 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004167 break;
4168 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004169 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004170 break;
4171 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004172 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004173 break;
4174 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004175 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004176 break;
4177 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004178 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004179 break;
4180 case GL_CURRENT_VERTEX_ATTRIB:
4181 for (int i = 0; i < 4; ++i)
4182 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004183 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004184 }
4185 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004186 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4187 *params = (GLfloat)attribState.mDivisor;
4188 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004189 default: return error(GL_INVALID_ENUM);
4190 }
4191 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004192 }
4193 catch(std::bad_alloc&)
4194 {
4195 return error(GL_OUT_OF_MEMORY);
4196 }
4197}
4198
4199void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
4200{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004201 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004202
4203 try
4204 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004205 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004206
daniel@transgaming.come0078962010-04-15 20:45:08 +00004207 if (context)
4208 {
4209 if (index >= gl::MAX_VERTEX_ATTRIBS)
4210 {
4211 return error(GL_INVALID_VALUE);
4212 }
4213
daniel@transgaming.com83921382011-01-08 05:46:00 +00004214 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004215
daniel@transgaming.come0078962010-04-15 20:45:08 +00004216 switch (pname)
4217 {
4218 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004219 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004220 break;
4221 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004222 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004223 break;
4224 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004225 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004226 break;
4227 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004228 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004229 break;
4230 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004231 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004232 break;
4233 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004234 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004235 break;
4236 case GL_CURRENT_VERTEX_ATTRIB:
4237 for (int i = 0; i < 4; ++i)
4238 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004239 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004240 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4241 }
4242 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004243 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4244 *params = (GLint)attribState.mDivisor;
4245 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004246 default: return error(GL_INVALID_ENUM);
4247 }
4248 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004249 }
4250 catch(std::bad_alloc&)
4251 {
4252 return error(GL_OUT_OF_MEMORY);
4253 }
4254}
4255
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004256void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004257{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004258 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004259
4260 try
4261 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004262 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004263
daniel@transgaming.come0078962010-04-15 20:45:08 +00004264 if (context)
4265 {
4266 if (index >= gl::MAX_VERTEX_ATTRIBS)
4267 {
4268 return error(GL_INVALID_VALUE);
4269 }
4270
4271 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4272 {
4273 return error(GL_INVALID_ENUM);
4274 }
4275
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004276 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00004277 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004278 }
4279 catch(std::bad_alloc&)
4280 {
4281 return error(GL_OUT_OF_MEMORY);
4282 }
4283}
4284
4285void __stdcall glHint(GLenum target, GLenum mode)
4286{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004287 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004288
4289 try
4290 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004291 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004292 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004293 case GL_FASTEST:
4294 case GL_NICEST:
4295 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004296 break;
4297 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004298 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004299 }
4300
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004301 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004302 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004303 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004304 case GL_GENERATE_MIPMAP_HINT:
4305 if (context) context->setGenerateMipmapHint(mode);
4306 break;
4307 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4308 if (context) context->setFragmentShaderDerivativeHint(mode);
4309 break;
4310 default:
4311 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004312 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004313 }
4314 catch(std::bad_alloc&)
4315 {
4316 return error(GL_OUT_OF_MEMORY);
4317 }
4318}
4319
4320GLboolean __stdcall glIsBuffer(GLuint buffer)
4321{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004322 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004323
4324 try
4325 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004326 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004327
4328 if (context && buffer)
4329 {
4330 gl::Buffer *bufferObject = context->getBuffer(buffer);
4331
4332 if (bufferObject)
4333 {
4334 return GL_TRUE;
4335 }
4336 }
4337 }
4338 catch(std::bad_alloc&)
4339 {
4340 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4341 }
4342
4343 return GL_FALSE;
4344}
4345
4346GLboolean __stdcall glIsEnabled(GLenum cap)
4347{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004348 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004349
4350 try
4351 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004352 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004353
4354 if (context)
4355 {
4356 switch (cap)
4357 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004358 case GL_CULL_FACE: return context->isCullFaceEnabled();
4359 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4360 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4361 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4362 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4363 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4364 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4365 case GL_BLEND: return context->isBlendEnabled();
4366 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004367 default:
4368 return error(GL_INVALID_ENUM, false);
4369 }
4370 }
4371 }
4372 catch(std::bad_alloc&)
4373 {
4374 return error(GL_OUT_OF_MEMORY, false);
4375 }
4376
4377 return false;
4378}
4379
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004380GLboolean __stdcall glIsFenceNV(GLuint fence)
4381{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004382 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004383
4384 try
4385 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004386 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004387
4388 if (context)
4389 {
4390 gl::Fence *fenceObject = context->getFence(fence);
4391
4392 if (fenceObject == NULL)
4393 {
4394 return GL_FALSE;
4395 }
4396
4397 return fenceObject->isFence();
4398 }
4399 }
4400 catch(std::bad_alloc&)
4401 {
4402 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4403 }
4404
4405 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004406}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004407
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004408GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
4409{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004410 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004411
4412 try
4413 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004414 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004415
4416 if (context && framebuffer)
4417 {
4418 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4419
4420 if (framebufferObject)
4421 {
4422 return GL_TRUE;
4423 }
4424 }
4425 }
4426 catch(std::bad_alloc&)
4427 {
4428 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4429 }
4430
4431 return GL_FALSE;
4432}
4433
4434GLboolean __stdcall glIsProgram(GLuint program)
4435{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004436 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004437
4438 try
4439 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004440 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004441
4442 if (context && program)
4443 {
4444 gl::Program *programObject = context->getProgram(program);
4445
4446 if (programObject)
4447 {
4448 return GL_TRUE;
4449 }
4450 }
4451 }
4452 catch(std::bad_alloc&)
4453 {
4454 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4455 }
4456
4457 return GL_FALSE;
4458}
4459
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00004460GLboolean __stdcall glIsQueryEXT(GLuint id)
4461{
4462 EVENT("(GLuint id = %d)", id);
4463
4464 try
4465 {
4466 if (id == 0)
4467 {
4468 return GL_FALSE;
4469 }
4470
4471 gl::Context *context = gl::getNonLostContext();
4472
4473 if (context)
4474 {
4475 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
4476
4477 if (queryObject)
4478 {
4479 return GL_TRUE;
4480 }
4481 }
4482 }
4483 catch(std::bad_alloc&)
4484 {
4485 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4486 }
4487
4488 return GL_FALSE;
4489}
4490
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004491GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
4492{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004493 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004494
4495 try
4496 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004497 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004498
4499 if (context && renderbuffer)
4500 {
4501 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4502
4503 if (renderbufferObject)
4504 {
4505 return GL_TRUE;
4506 }
4507 }
4508 }
4509 catch(std::bad_alloc&)
4510 {
4511 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4512 }
4513
4514 return GL_FALSE;
4515}
4516
4517GLboolean __stdcall glIsShader(GLuint shader)
4518{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004519 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004520
4521 try
4522 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004523 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004524
4525 if (context && shader)
4526 {
4527 gl::Shader *shaderObject = context->getShader(shader);
4528
4529 if (shaderObject)
4530 {
4531 return GL_TRUE;
4532 }
4533 }
4534 }
4535 catch(std::bad_alloc&)
4536 {
4537 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4538 }
4539
4540 return GL_FALSE;
4541}
4542
4543GLboolean __stdcall glIsTexture(GLuint texture)
4544{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004545 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004546
4547 try
4548 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004549 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004550
4551 if (context && texture)
4552 {
4553 gl::Texture *textureObject = context->getTexture(texture);
4554
4555 if (textureObject)
4556 {
4557 return GL_TRUE;
4558 }
4559 }
4560 }
4561 catch(std::bad_alloc&)
4562 {
4563 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4564 }
4565
4566 return GL_FALSE;
4567}
4568
4569void __stdcall glLineWidth(GLfloat width)
4570{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004571 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004572
4573 try
4574 {
4575 if (width <= 0.0f)
4576 {
4577 return error(GL_INVALID_VALUE);
4578 }
4579
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004580 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004581
4582 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004583 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004584 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004585 }
4586 }
4587 catch(std::bad_alloc&)
4588 {
4589 return error(GL_OUT_OF_MEMORY);
4590 }
4591}
4592
4593void __stdcall glLinkProgram(GLuint program)
4594{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004595 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004596
4597 try
4598 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004599 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004600
4601 if (context)
4602 {
4603 gl::Program *programObject = context->getProgram(program);
4604
4605 if (!programObject)
4606 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004607 if (context->getShader(program))
4608 {
4609 return error(GL_INVALID_OPERATION);
4610 }
4611 else
4612 {
4613 return error(GL_INVALID_VALUE);
4614 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004615 }
4616
4617 programObject->link();
4618 }
4619 }
4620 catch(std::bad_alloc&)
4621 {
4622 return error(GL_OUT_OF_MEMORY);
4623 }
4624}
4625
4626void __stdcall glPixelStorei(GLenum pname, GLint param)
4627{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004628 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004629
4630 try
4631 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004632 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004633
4634 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004635 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004636 switch (pname)
4637 {
4638 case GL_UNPACK_ALIGNMENT:
4639 if (param != 1 && param != 2 && param != 4 && param != 8)
4640 {
4641 return error(GL_INVALID_VALUE);
4642 }
4643
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004644 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004645 break;
4646
4647 case GL_PACK_ALIGNMENT:
4648 if (param != 1 && param != 2 && param != 4 && param != 8)
4649 {
4650 return error(GL_INVALID_VALUE);
4651 }
4652
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004653 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004654 break;
4655
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004656 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4657 context->setPackReverseRowOrder(param != 0);
4658 break;
4659
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004660 default:
4661 return error(GL_INVALID_ENUM);
4662 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004663 }
4664 }
4665 catch(std::bad_alloc&)
4666 {
4667 return error(GL_OUT_OF_MEMORY);
4668 }
4669}
4670
4671void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4672{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004673 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004674
4675 try
4676 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004677 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004678
4679 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004680 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004681 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004682 }
4683 }
4684 catch(std::bad_alloc&)
4685 {
4686 return error(GL_OUT_OF_MEMORY);
4687 }
4688}
4689
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004690void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4691 GLenum format, GLenum type, GLsizei bufSize,
4692 GLvoid *data)
4693{
4694 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4695 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4696 x, y, width, height, format, type, bufSize, data);
4697
4698 try
4699 {
4700 if (width < 0 || height < 0 || bufSize < 0)
4701 {
4702 return error(GL_INVALID_VALUE);
4703 }
4704
4705 if (!validReadFormatType(format, type))
4706 {
4707 return error(GL_INVALID_OPERATION);
4708 }
4709
4710 gl::Context *context = gl::getNonLostContext();
4711
4712 if (context)
4713 {
4714 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4715 }
4716 }
4717 catch(std::bad_alloc&)
4718 {
4719 return error(GL_OUT_OF_MEMORY);
4720 }
4721}
4722
4723void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4724 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004725{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004726 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004727 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004728 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004729
4730 try
4731 {
4732 if (width < 0 || height < 0)
4733 {
4734 return error(GL_INVALID_VALUE);
4735 }
4736
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004737 if (!validReadFormatType(format, type))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004738 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004739 return error(GL_INVALID_OPERATION);
4740 }
4741
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004742 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004743
4744 if (context)
4745 {
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004746 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004747 }
4748 }
4749 catch(std::bad_alloc&)
4750 {
4751 return error(GL_OUT_OF_MEMORY);
4752 }
4753}
4754
4755void __stdcall glReleaseShaderCompiler(void)
4756{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004757 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004758
4759 try
4760 {
4761 gl::Shader::releaseCompiler();
4762 }
4763 catch(std::bad_alloc&)
4764 {
4765 return error(GL_OUT_OF_MEMORY);
4766 }
4767}
4768
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004769void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004770{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004771 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 +00004772 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004773
4774 try
4775 {
4776 switch (target)
4777 {
4778 case GL_RENDERBUFFER:
4779 break;
4780 default:
4781 return error(GL_INVALID_ENUM);
4782 }
4783
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004784 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004785 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004786 return error(GL_INVALID_ENUM);
4787 }
4788
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004789 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004790 {
4791 return error(GL_INVALID_VALUE);
4792 }
4793
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004794 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004795
4796 if (context)
4797 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004798 if (width > context->getMaximumRenderbufferDimension() ||
4799 height > context->getMaximumRenderbufferDimension() ||
4800 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004801 {
4802 return error(GL_INVALID_VALUE);
4803 }
4804
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004805 GLuint handle = context->getRenderbufferHandle();
4806 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004807 {
4808 return error(GL_INVALID_OPERATION);
4809 }
4810
4811 switch (internalformat)
4812 {
4813 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004814 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004815 break;
4816 case GL_RGBA4:
4817 case GL_RGB5_A1:
4818 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004819 case GL_RGB8_OES:
4820 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004821 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004822 break;
4823 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004824 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004825 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004826 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004827 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004828 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004829 default:
4830 return error(GL_INVALID_ENUM);
4831 }
4832 }
4833 }
4834 catch(std::bad_alloc&)
4835 {
4836 return error(GL_OUT_OF_MEMORY);
4837 }
4838}
4839
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004840void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4841{
4842 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4843}
4844
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004845void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4846{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004847 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004848
4849 try
4850 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004851 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004852
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004853 if (context)
4854 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004855 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004856 }
4857 }
4858 catch(std::bad_alloc&)
4859 {
4860 return error(GL_OUT_OF_MEMORY);
4861 }
4862}
4863
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004864void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4865{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004866 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004867
4868 try
4869 {
4870 if (condition != GL_ALL_COMPLETED_NV)
4871 {
4872 return error(GL_INVALID_ENUM);
4873 }
4874
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004875 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004876
4877 if (context)
4878 {
4879 gl::Fence *fenceObject = context->getFence(fence);
4880
4881 if (fenceObject == NULL)
4882 {
4883 return error(GL_INVALID_OPERATION);
4884 }
4885
4886 fenceObject->setFence(condition);
4887 }
4888 }
4889 catch(std::bad_alloc&)
4890 {
4891 return error(GL_OUT_OF_MEMORY);
4892 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004893}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004894
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004895void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4896{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004897 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 +00004898
4899 try
4900 {
4901 if (width < 0 || height < 0)
4902 {
4903 return error(GL_INVALID_VALUE);
4904 }
4905
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004906 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004907
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004908 if (context)
4909 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004910 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004911 }
4912 }
4913 catch(std::bad_alloc&)
4914 {
4915 return error(GL_OUT_OF_MEMORY);
4916 }
4917}
4918
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004919void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004920{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004921 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004922 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004923 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004924
4925 try
4926 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004927 // No binary shader formats are supported.
4928 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004929 }
4930 catch(std::bad_alloc&)
4931 {
4932 return error(GL_OUT_OF_MEMORY);
4933 }
4934}
4935
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004936void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004937{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004938 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 +00004939 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004940
4941 try
4942 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004943 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004944 {
4945 return error(GL_INVALID_VALUE);
4946 }
4947
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004948 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004949
4950 if (context)
4951 {
4952 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004953
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004954 if (!shaderObject)
4955 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004956 if (context->getProgram(shader))
4957 {
4958 return error(GL_INVALID_OPERATION);
4959 }
4960 else
4961 {
4962 return error(GL_INVALID_VALUE);
4963 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004964 }
4965
4966 shaderObject->setSource(count, string, length);
4967 }
4968 }
4969 catch(std::bad_alloc&)
4970 {
4971 return error(GL_OUT_OF_MEMORY);
4972 }
4973}
4974
4975void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4976{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004977 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004978}
4979
4980void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4981{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004982 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 +00004983
4984 try
4985 {
4986 switch (face)
4987 {
4988 case GL_FRONT:
4989 case GL_BACK:
4990 case GL_FRONT_AND_BACK:
4991 break;
4992 default:
4993 return error(GL_INVALID_ENUM);
4994 }
4995
4996 switch (func)
4997 {
4998 case GL_NEVER:
4999 case GL_ALWAYS:
5000 case GL_LESS:
5001 case GL_LEQUAL:
5002 case GL_EQUAL:
5003 case GL_GEQUAL:
5004 case GL_GREATER:
5005 case GL_NOTEQUAL:
5006 break;
5007 default:
5008 return error(GL_INVALID_ENUM);
5009 }
5010
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005011 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005012
5013 if (context)
5014 {
5015 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5016 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005017 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005018 }
5019
5020 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5021 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005022 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005023 }
5024 }
5025 }
5026 catch(std::bad_alloc&)
5027 {
5028 return error(GL_OUT_OF_MEMORY);
5029 }
5030}
5031
5032void __stdcall glStencilMask(GLuint mask)
5033{
5034 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
5035}
5036
5037void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
5038{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005039 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005040
5041 try
5042 {
5043 switch (face)
5044 {
5045 case GL_FRONT:
5046 case GL_BACK:
5047 case GL_FRONT_AND_BACK:
5048 break;
5049 default:
5050 return error(GL_INVALID_ENUM);
5051 }
5052
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005053 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005054
5055 if (context)
5056 {
5057 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5058 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005059 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005060 }
5061
5062 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5063 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005064 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005065 }
5066 }
5067 }
5068 catch(std::bad_alloc&)
5069 {
5070 return error(GL_OUT_OF_MEMORY);
5071 }
5072}
5073
5074void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
5075{
5076 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
5077}
5078
5079void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
5080{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005081 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 +00005082 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005083
5084 try
5085 {
5086 switch (face)
5087 {
5088 case GL_FRONT:
5089 case GL_BACK:
5090 case GL_FRONT_AND_BACK:
5091 break;
5092 default:
5093 return error(GL_INVALID_ENUM);
5094 }
5095
5096 switch (fail)
5097 {
5098 case GL_ZERO:
5099 case GL_KEEP:
5100 case GL_REPLACE:
5101 case GL_INCR:
5102 case GL_DECR:
5103 case GL_INVERT:
5104 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005105 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005106 break;
5107 default:
5108 return error(GL_INVALID_ENUM);
5109 }
5110
5111 switch (zfail)
5112 {
5113 case GL_ZERO:
5114 case GL_KEEP:
5115 case GL_REPLACE:
5116 case GL_INCR:
5117 case GL_DECR:
5118 case GL_INVERT:
5119 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005120 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005121 break;
5122 default:
5123 return error(GL_INVALID_ENUM);
5124 }
5125
5126 switch (zpass)
5127 {
5128 case GL_ZERO:
5129 case GL_KEEP:
5130 case GL_REPLACE:
5131 case GL_INCR:
5132 case GL_DECR:
5133 case GL_INVERT:
5134 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005135 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005136 break;
5137 default:
5138 return error(GL_INVALID_ENUM);
5139 }
5140
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005141 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005142
5143 if (context)
5144 {
5145 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5146 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005147 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005148 }
5149
5150 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5151 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005152 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005153 }
5154 }
5155 }
5156 catch(std::bad_alloc&)
5157 {
5158 return error(GL_OUT_OF_MEMORY);
5159 }
5160}
5161
daniel@transgaming.comfe208882010-09-01 15:47:57 +00005162GLboolean __stdcall glTestFenceNV(GLuint fence)
5163{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005164 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005165
5166 try
5167 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005168 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005169
5170 if (context)
5171 {
5172 gl::Fence *fenceObject = context->getFence(fence);
5173
5174 if (fenceObject == NULL)
5175 {
5176 return error(GL_INVALID_OPERATION, GL_TRUE);
5177 }
5178
5179 return fenceObject->testFence();
5180 }
5181 }
5182 catch(std::bad_alloc&)
5183 {
5184 error(GL_OUT_OF_MEMORY);
5185 }
5186
5187 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00005188}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005189
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005190void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
5191 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005192{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005193 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 +00005194 "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 +00005195 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005196
5197 try
5198 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00005199 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005200 {
5201 return error(GL_INVALID_VALUE);
5202 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005203
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +00005204 if (internalformat != GLint(format))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005205 {
5206 return error(GL_INVALID_OPERATION);
5207 }
5208
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005209 // validate <type> by itself (used as secondary key below)
5210 switch (type)
5211 {
5212 case GL_UNSIGNED_BYTE:
5213 case GL_UNSIGNED_SHORT_5_6_5:
5214 case GL_UNSIGNED_SHORT_4_4_4_4:
5215 case GL_UNSIGNED_SHORT_5_5_5_1:
5216 case GL_UNSIGNED_SHORT:
5217 case GL_UNSIGNED_INT:
5218 case GL_UNSIGNED_INT_24_8_OES:
5219 case GL_HALF_FLOAT_OES:
5220 case GL_FLOAT:
5221 break;
5222 default:
5223 return error(GL_INVALID_ENUM);
5224 }
5225
5226 // validate <format> + <type> combinations
5227 // - invalid <format> -> sets INVALID_ENUM
5228 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005229 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005230 {
5231 case GL_ALPHA:
5232 case GL_LUMINANCE:
5233 case GL_LUMINANCE_ALPHA:
5234 switch (type)
5235 {
5236 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005237 case GL_FLOAT:
5238 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005239 break;
5240 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005241 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005242 }
5243 break;
5244 case GL_RGB:
5245 switch (type)
5246 {
5247 case GL_UNSIGNED_BYTE:
5248 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005249 case GL_FLOAT:
5250 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005251 break;
5252 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005253 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005254 }
5255 break;
5256 case GL_RGBA:
5257 switch (type)
5258 {
5259 case GL_UNSIGNED_BYTE:
5260 case GL_UNSIGNED_SHORT_4_4_4_4:
5261 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005262 case GL_FLOAT:
5263 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005264 break;
5265 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005266 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005267 }
5268 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005269 case GL_BGRA_EXT:
5270 switch (type)
5271 {
5272 case GL_UNSIGNED_BYTE:
5273 break;
5274 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005275 return error(GL_INVALID_OPERATION);
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005276 }
5277 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005278 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
5279 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00005280 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5281 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00005282 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005283 case GL_DEPTH_COMPONENT:
5284 switch (type)
5285 {
5286 case GL_UNSIGNED_SHORT:
5287 case GL_UNSIGNED_INT:
5288 break;
5289 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005290 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005291 }
5292 break;
5293 case GL_DEPTH_STENCIL_OES:
5294 switch (type)
5295 {
5296 case GL_UNSIGNED_INT_24_8_OES:
5297 break;
5298 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005299 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005300 }
5301 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005302 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005303 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005304 }
5305
5306 if (border != 0)
5307 {
5308 return error(GL_INVALID_VALUE);
5309 }
5310
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005311 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005312
5313 if (context)
5314 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00005315 if (level > context->getMaximumTextureLevel())
5316 {
5317 return error(GL_INVALID_VALUE);
5318 }
5319
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005320 switch (target)
5321 {
5322 case GL_TEXTURE_2D:
5323 if (width > (context->getMaximumTextureDimension() >> level) ||
5324 height > (context->getMaximumTextureDimension() >> level))
5325 {
5326 return error(GL_INVALID_VALUE);
5327 }
5328 break;
5329 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5330 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5331 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5332 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5333 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5334 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5335 if (width != height)
5336 {
5337 return error(GL_INVALID_VALUE);
5338 }
5339
5340 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
5341 height > (context->getMaximumCubeTextureDimension() >> level))
5342 {
5343 return error(GL_INVALID_VALUE);
5344 }
5345 break;
5346 default:
5347 return error(GL_INVALID_ENUM);
5348 }
5349
gman@chromium.org50c526d2011-08-10 05:19:44 +00005350 switch (format) {
5351 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5352 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5353 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00005354 {
5355 return error(GL_INVALID_OPERATION);
5356 }
5357 else
5358 {
5359 return error(GL_INVALID_ENUM);
5360 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00005361 break;
5362 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5363 if (context->supportsDXT3Textures())
5364 {
5365 return error(GL_INVALID_OPERATION);
5366 }
5367 else
5368 {
5369 return error(GL_INVALID_ENUM);
5370 }
5371 break;
5372 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5373 if (context->supportsDXT5Textures())
5374 {
5375 return error(GL_INVALID_OPERATION);
5376 }
5377 else
5378 {
5379 return error(GL_INVALID_ENUM);
5380 }
5381 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005382 case GL_DEPTH_COMPONENT:
5383 case GL_DEPTH_STENCIL_OES:
5384 if (!context->supportsDepthTextures())
5385 {
5386 return error(GL_INVALID_VALUE);
5387 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005388 if (target != GL_TEXTURE_2D)
5389 {
5390 return error(GL_INVALID_OPERATION);
5391 }
daniel@transgaming.com797924b2012-06-05 19:50:01 +00005392 // OES_depth_texture supports loading depth data and multiple levels,
5393 // but ANGLE_depth_texture does not
5394 if (pixels != NULL || level != 0)
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005395 {
5396 return error(GL_INVALID_OPERATION);
5397 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005398 break;
gman@chromium.org50c526d2011-08-10 05:19:44 +00005399 default:
5400 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005401 }
5402
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005403 if (type == GL_FLOAT)
5404 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005405 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005406 {
5407 return error(GL_INVALID_ENUM);
5408 }
5409 }
5410 else if (type == GL_HALF_FLOAT_OES)
5411 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005412 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005413 {
5414 return error(GL_INVALID_ENUM);
5415 }
5416 }
5417
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005418 if (target == GL_TEXTURE_2D)
5419 {
5420 gl::Texture2D *texture = context->getTexture2D();
5421
5422 if (!texture)
5423 {
5424 return error(GL_INVALID_OPERATION);
5425 }
5426
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005427 if (texture->isImmutable())
5428 {
5429 return error(GL_INVALID_OPERATION);
5430 }
5431
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005432 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005433 }
5434 else
5435 {
5436 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5437
5438 if (!texture)
5439 {
5440 return error(GL_INVALID_OPERATION);
5441 }
5442
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005443 if (texture->isImmutable())
5444 {
5445 return error(GL_INVALID_OPERATION);
5446 }
5447
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005448 switch (target)
5449 {
5450 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005451 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005452 break;
5453 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005454 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005455 break;
5456 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005457 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005458 break;
5459 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005460 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005461 break;
5462 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005463 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005464 break;
5465 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005466 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005467 break;
5468 default: UNREACHABLE();
5469 }
5470 }
5471 }
5472 }
5473 catch(std::bad_alloc&)
5474 {
5475 return error(GL_OUT_OF_MEMORY);
5476 }
5477}
5478
5479void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5480{
5481 glTexParameteri(target, pname, (GLint)param);
5482}
5483
5484void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5485{
5486 glTexParameteri(target, pname, (GLint)*params);
5487}
5488
5489void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
5490{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005491 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005492
5493 try
5494 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005495 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005496
5497 if (context)
5498 {
5499 gl::Texture *texture;
5500
5501 switch (target)
5502 {
5503 case GL_TEXTURE_2D:
5504 texture = context->getTexture2D();
5505 break;
5506 case GL_TEXTURE_CUBE_MAP:
5507 texture = context->getTextureCubeMap();
5508 break;
5509 default:
5510 return error(GL_INVALID_ENUM);
5511 }
5512
5513 switch (pname)
5514 {
5515 case GL_TEXTURE_WRAP_S:
5516 if (!texture->setWrapS((GLenum)param))
5517 {
5518 return error(GL_INVALID_ENUM);
5519 }
5520 break;
5521 case GL_TEXTURE_WRAP_T:
5522 if (!texture->setWrapT((GLenum)param))
5523 {
5524 return error(GL_INVALID_ENUM);
5525 }
5526 break;
5527 case GL_TEXTURE_MIN_FILTER:
5528 if (!texture->setMinFilter((GLenum)param))
5529 {
5530 return error(GL_INVALID_ENUM);
5531 }
5532 break;
5533 case GL_TEXTURE_MAG_FILTER:
5534 if (!texture->setMagFilter((GLenum)param))
5535 {
5536 return error(GL_INVALID_ENUM);
5537 }
5538 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00005539 case GL_TEXTURE_USAGE_ANGLE:
5540 if (!texture->setUsage((GLenum)param))
5541 {
5542 return error(GL_INVALID_ENUM);
5543 }
5544 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005545 default:
5546 return error(GL_INVALID_ENUM);
5547 }
5548 }
5549 }
5550 catch(std::bad_alloc&)
5551 {
5552 return error(GL_OUT_OF_MEMORY);
5553 }
5554}
5555
5556void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5557{
5558 glTexParameteri(target, pname, *params);
5559}
5560
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005561void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5562{
5563 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5564 target, levels, internalformat, width, height);
5565
5566 try
5567 {
5568 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5569 {
5570 return error(GL_INVALID_ENUM);
5571 }
5572
5573 if (width < 1 || height < 1 || levels < 1)
5574 {
5575 return error(GL_INVALID_VALUE);
5576 }
5577
5578 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5579 {
5580 return error(GL_INVALID_VALUE);
5581 }
5582
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005583 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005584 {
5585 return error(GL_INVALID_OPERATION);
5586 }
5587
5588 GLenum format = gl::ExtractFormat(internalformat);
5589 GLenum type = gl::ExtractType(internalformat);
5590
5591 if (format == GL_NONE || type == GL_NONE)
5592 {
5593 return error(GL_INVALID_ENUM);
5594 }
5595
5596 gl::Context *context = gl::getNonLostContext();
5597
5598 if (context)
5599 {
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005600 switch (target)
5601 {
5602 case GL_TEXTURE_2D:
5603 if (width > context->getMaximumTextureDimension() ||
5604 height > context->getMaximumTextureDimension())
5605 {
5606 return error(GL_INVALID_VALUE);
5607 }
5608 break;
5609 case GL_TEXTURE_CUBE_MAP:
5610 if (width > context->getMaximumCubeTextureDimension() ||
5611 height > context->getMaximumCubeTextureDimension())
5612 {
5613 return error(GL_INVALID_VALUE);
5614 }
5615 break;
5616 default:
5617 return error(GL_INVALID_ENUM);
5618 }
5619
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005620 if (levels != 1 && !context->supportsNonPower2Texture())
5621 {
5622 if (!gl::isPow2(width) || !gl::isPow2(height))
5623 {
5624 return error(GL_INVALID_OPERATION);
5625 }
5626 }
5627
daniel@transgaming.come1077362011-11-11 04:16:50 +00005628 switch (internalformat)
5629 {
5630 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5631 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5632 if (!context->supportsDXT1Textures())
5633 {
5634 return error(GL_INVALID_ENUM);
5635 }
5636 break;
5637 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5638 if (!context->supportsDXT3Textures())
5639 {
5640 return error(GL_INVALID_ENUM);
5641 }
5642 break;
5643 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5644 if (!context->supportsDXT5Textures())
5645 {
5646 return error(GL_INVALID_ENUM);
5647 }
5648 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005649 case GL_RGBA32F_EXT:
5650 case GL_RGB32F_EXT:
5651 case GL_ALPHA32F_EXT:
5652 case GL_LUMINANCE32F_EXT:
5653 case GL_LUMINANCE_ALPHA32F_EXT:
5654 if (!context->supportsFloat32Textures())
5655 {
5656 return error(GL_INVALID_ENUM);
5657 }
5658 break;
5659 case GL_RGBA16F_EXT:
5660 case GL_RGB16F_EXT:
5661 case GL_ALPHA16F_EXT:
5662 case GL_LUMINANCE16F_EXT:
5663 case GL_LUMINANCE_ALPHA16F_EXT:
5664 if (!context->supportsFloat16Textures())
5665 {
5666 return error(GL_INVALID_ENUM);
5667 }
5668 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005669 case GL_DEPTH_COMPONENT16:
5670 case GL_DEPTH_COMPONENT32_OES:
5671 case GL_DEPTH24_STENCIL8_OES:
5672 if (!context->supportsDepthTextures())
5673 {
5674 return error(GL_INVALID_ENUM);
5675 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005676 if (target != GL_TEXTURE_2D)
5677 {
5678 return error(GL_INVALID_OPERATION);
5679 }
daniel@transgaming.com797924b2012-06-05 19:50:01 +00005680 // ANGLE_depth_texture only supports 1-level textures
5681 if (levels != 1)
5682 {
5683 return error(GL_INVALID_OPERATION);
5684 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005685 break;
5686 default:
5687 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005688 }
5689
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005690 if (target == GL_TEXTURE_2D)
5691 {
5692 gl::Texture2D *texture = context->getTexture2D();
5693
5694 if (!texture || texture->id() == 0)
5695 {
5696 return error(GL_INVALID_OPERATION);
5697 }
5698
5699 if (texture->isImmutable())
5700 {
5701 return error(GL_INVALID_OPERATION);
5702 }
5703
5704 texture->storage(levels, internalformat, width, height);
5705 }
5706 else if (target == GL_TEXTURE_CUBE_MAP)
5707 {
5708 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5709
5710 if (!texture || texture->id() == 0)
5711 {
5712 return error(GL_INVALID_OPERATION);
5713 }
5714
5715 if (texture->isImmutable())
5716 {
5717 return error(GL_INVALID_OPERATION);
5718 }
5719
5720 texture->storage(levels, internalformat, width);
5721 }
5722 else UNREACHABLE();
5723 }
5724 }
5725 catch(std::bad_alloc&)
5726 {
5727 return error(GL_OUT_OF_MEMORY);
5728 }
5729}
5730
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005731void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5732 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005733{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005734 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005735 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005736 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005737 target, level, xoffset, yoffset, width, height, format, type, pixels);
5738
5739 try
5740 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00005741 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005742 {
5743 return error(GL_INVALID_ENUM);
5744 }
5745
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005746 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005747 {
5748 return error(GL_INVALID_VALUE);
5749 }
5750
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005751 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5752 {
5753 return error(GL_INVALID_VALUE);
5754 }
5755
daniel@transgaming.com8833dd22012-06-05 19:49:58 +00005756 if (!checkTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005757 {
daniel@transgaming.com8833dd22012-06-05 19:49:58 +00005758 return; // error is set by helper function
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005759 }
5760
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005761 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005762
5763 if (context)
5764 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005765 if (level > context->getMaximumTextureLevel())
5766 {
5767 return error(GL_INVALID_VALUE);
5768 }
5769
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005770 if (format == GL_FLOAT)
5771 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005772 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005773 {
5774 return error(GL_INVALID_ENUM);
5775 }
5776 }
5777 else if (format == GL_HALF_FLOAT_OES)
5778 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005779 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005780 {
5781 return error(GL_INVALID_ENUM);
5782 }
5783 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005784 else if (gl::IsDepthTexture(format))
5785 {
5786 if (!context->supportsDepthTextures())
5787 {
5788 return error(GL_INVALID_ENUM);
5789 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005790 if (target != GL_TEXTURE_2D)
5791 {
5792 return error(GL_INVALID_OPERATION);
5793 }
5794 // OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not
5795 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005796 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005797
daniel@transgaming.com1d2d3c42012-05-31 01:14:15 +00005798 if (width == 0 || height == 0 || pixels == NULL)
5799 {
5800 return;
5801 }
5802
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005803 if (target == GL_TEXTURE_2D)
5804 {
5805 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00005806 if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005807 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005808 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005809 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005810 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005811 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005812 {
5813 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00005814 if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005815 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005816 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005817 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005818 }
5819 else
5820 {
5821 UNREACHABLE();
5822 }
5823 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005824 }
5825 catch(std::bad_alloc&)
5826 {
5827 return error(GL_OUT_OF_MEMORY);
5828 }
5829}
5830
5831void __stdcall glUniform1f(GLint location, GLfloat x)
5832{
5833 glUniform1fv(location, 1, &x);
5834}
5835
5836void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5837{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005838 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005839
5840 try
5841 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005842 if (count < 0)
5843 {
5844 return error(GL_INVALID_VALUE);
5845 }
5846
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005847 if (location == -1)
5848 {
5849 return;
5850 }
5851
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005852 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005853
5854 if (context)
5855 {
5856 gl::Program *program = context->getCurrentProgram();
5857
5858 if (!program)
5859 {
5860 return error(GL_INVALID_OPERATION);
5861 }
5862
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00005863 gl::ProgramBinary *programBinary = program->getProgramBinary();
5864 if (!programBinary)
5865 {
5866 return error(GL_INVALID_OPERATION);
5867 }
5868
5869 if (!programBinary->setUniform1fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005870 {
5871 return error(GL_INVALID_OPERATION);
5872 }
5873 }
5874 }
5875 catch(std::bad_alloc&)
5876 {
5877 return error(GL_OUT_OF_MEMORY);
5878 }
5879}
5880
5881void __stdcall glUniform1i(GLint location, GLint x)
5882{
5883 glUniform1iv(location, 1, &x);
5884}
5885
5886void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5887{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005888 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005889
5890 try
5891 {
5892 if (count < 0)
5893 {
5894 return error(GL_INVALID_VALUE);
5895 }
5896
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005897 if (location == -1)
5898 {
5899 return;
5900 }
5901
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005902 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005903
5904 if (context)
5905 {
5906 gl::Program *program = context->getCurrentProgram();
5907
5908 if (!program)
5909 {
5910 return error(GL_INVALID_OPERATION);
5911 }
5912
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00005913 gl::ProgramBinary *programBinary = program->getProgramBinary();
5914 if (!programBinary)
5915 {
5916 return error(GL_INVALID_OPERATION);
5917 }
5918
5919 if (!programBinary->setUniform1iv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005920 {
5921 return error(GL_INVALID_OPERATION);
5922 }
5923 }
5924 }
5925 catch(std::bad_alloc&)
5926 {
5927 return error(GL_OUT_OF_MEMORY);
5928 }
5929}
5930
5931void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5932{
5933 GLfloat xy[2] = {x, y};
5934
5935 glUniform2fv(location, 1, (GLfloat*)&xy);
5936}
5937
5938void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5939{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005940 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005941
5942 try
5943 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005944 if (count < 0)
5945 {
5946 return error(GL_INVALID_VALUE);
5947 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005948
5949 if (location == -1)
5950 {
5951 return;
5952 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005953
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005954 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005955
5956 if (context)
5957 {
5958 gl::Program *program = context->getCurrentProgram();
5959
5960 if (!program)
5961 {
5962 return error(GL_INVALID_OPERATION);
5963 }
5964
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00005965 gl::ProgramBinary *programBinary = program->getProgramBinary();
5966 if (!programBinary)
5967 {
5968 return error(GL_INVALID_OPERATION);
5969 }
5970
5971 if (!programBinary->setUniform2fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005972 {
5973 return error(GL_INVALID_OPERATION);
5974 }
5975 }
5976 }
5977 catch(std::bad_alloc&)
5978 {
5979 return error(GL_OUT_OF_MEMORY);
5980 }
5981}
5982
5983void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5984{
5985 GLint xy[4] = {x, y};
5986
5987 glUniform2iv(location, 1, (GLint*)&xy);
5988}
5989
5990void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5991{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005992 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005993
5994 try
5995 {
5996 if (count < 0)
5997 {
5998 return error(GL_INVALID_VALUE);
5999 }
6000
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006001 if (location == -1)
6002 {
6003 return;
6004 }
6005
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006006 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006007
6008 if (context)
6009 {
6010 gl::Program *program = context->getCurrentProgram();
6011
6012 if (!program)
6013 {
6014 return error(GL_INVALID_OPERATION);
6015 }
6016
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006017 gl::ProgramBinary *programBinary = program->getProgramBinary();
6018 if (!programBinary)
6019 {
6020 return error(GL_INVALID_OPERATION);
6021 }
6022
6023 if (!programBinary->setUniform2iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006024 {
6025 return error(GL_INVALID_OPERATION);
6026 }
6027 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006028 }
6029 catch(std::bad_alloc&)
6030 {
6031 return error(GL_OUT_OF_MEMORY);
6032 }
6033}
6034
6035void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
6036{
6037 GLfloat xyz[3] = {x, y, z};
6038
6039 glUniform3fv(location, 1, (GLfloat*)&xyz);
6040}
6041
6042void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
6043{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006044 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* 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
6053 if (location == -1)
6054 {
6055 return;
6056 }
6057
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006058 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006059
6060 if (context)
6061 {
6062 gl::Program *program = context->getCurrentProgram();
6063
6064 if (!program)
6065 {
6066 return error(GL_INVALID_OPERATION);
6067 }
6068
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006069 gl::ProgramBinary *programBinary = program->getProgramBinary();
6070 if (!programBinary)
6071 {
6072 return error(GL_INVALID_OPERATION);
6073 }
6074
6075 if (!programBinary->setUniform3fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006076 {
6077 return error(GL_INVALID_OPERATION);
6078 }
6079 }
6080 }
6081 catch(std::bad_alloc&)
6082 {
6083 return error(GL_OUT_OF_MEMORY);
6084 }
6085}
6086
6087void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
6088{
6089 GLint xyz[3] = {x, y, z};
6090
6091 glUniform3iv(location, 1, (GLint*)&xyz);
6092}
6093
6094void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
6095{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006096 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006097
6098 try
6099 {
6100 if (count < 0)
6101 {
6102 return error(GL_INVALID_VALUE);
6103 }
6104
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006105 if (location == -1)
6106 {
6107 return;
6108 }
6109
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006110 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006111
6112 if (context)
6113 {
6114 gl::Program *program = context->getCurrentProgram();
6115
6116 if (!program)
6117 {
6118 return error(GL_INVALID_OPERATION);
6119 }
6120
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006121 gl::ProgramBinary *programBinary = program->getProgramBinary();
6122 if (!programBinary)
6123 {
6124 return error(GL_INVALID_OPERATION);
6125 }
6126
6127 if (!programBinary->setUniform3iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006128 {
6129 return error(GL_INVALID_OPERATION);
6130 }
6131 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006132 }
6133 catch(std::bad_alloc&)
6134 {
6135 return error(GL_OUT_OF_MEMORY);
6136 }
6137}
6138
6139void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6140{
6141 GLfloat xyzw[4] = {x, y, z, w};
6142
6143 glUniform4fv(location, 1, (GLfloat*)&xyzw);
6144}
6145
6146void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
6147{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006148 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006149
6150 try
6151 {
6152 if (count < 0)
6153 {
6154 return error(GL_INVALID_VALUE);
6155 }
6156
6157 if (location == -1)
6158 {
6159 return;
6160 }
6161
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006162 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006163
6164 if (context)
6165 {
6166 gl::Program *program = context->getCurrentProgram();
6167
6168 if (!program)
6169 {
6170 return error(GL_INVALID_OPERATION);
6171 }
6172
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006173 gl::ProgramBinary *programBinary = program->getProgramBinary();
6174 if (!programBinary)
6175 {
6176 return error(GL_INVALID_OPERATION);
6177 }
6178
6179 if (!programBinary->setUniform4fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006180 {
6181 return error(GL_INVALID_OPERATION);
6182 }
6183 }
6184 }
6185 catch(std::bad_alloc&)
6186 {
6187 return error(GL_OUT_OF_MEMORY);
6188 }
6189}
6190
6191void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
6192{
6193 GLint xyzw[4] = {x, y, z, w};
6194
6195 glUniform4iv(location, 1, (GLint*)&xyzw);
6196}
6197
6198void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
6199{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006200 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006201
6202 try
6203 {
6204 if (count < 0)
6205 {
6206 return error(GL_INVALID_VALUE);
6207 }
6208
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006209 if (location == -1)
6210 {
6211 return;
6212 }
6213
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006214 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006215
6216 if (context)
6217 {
6218 gl::Program *program = context->getCurrentProgram();
6219
6220 if (!program)
6221 {
6222 return error(GL_INVALID_OPERATION);
6223 }
6224
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006225 gl::ProgramBinary *programBinary = program->getProgramBinary();
6226 if (!programBinary)
6227 {
6228 return error(GL_INVALID_OPERATION);
6229 }
6230
6231 if (!programBinary->setUniform4iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006232 {
6233 return error(GL_INVALID_OPERATION);
6234 }
6235 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006236 }
6237 catch(std::bad_alloc&)
6238 {
6239 return error(GL_OUT_OF_MEMORY);
6240 }
6241}
6242
6243void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6244{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006245 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006246 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006247
6248 try
6249 {
6250 if (count < 0 || transpose != GL_FALSE)
6251 {
6252 return error(GL_INVALID_VALUE);
6253 }
6254
6255 if (location == -1)
6256 {
6257 return;
6258 }
6259
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006260 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006261
6262 if (context)
6263 {
6264 gl::Program *program = context->getCurrentProgram();
6265
6266 if (!program)
6267 {
6268 return error(GL_INVALID_OPERATION);
6269 }
6270
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006271 gl::ProgramBinary *programBinary = program->getProgramBinary();
6272 if (!programBinary)
6273 {
6274 return error(GL_INVALID_OPERATION);
6275 }
6276
6277 if (!programBinary->setUniformMatrix2fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006278 {
6279 return error(GL_INVALID_OPERATION);
6280 }
6281 }
6282 }
6283 catch(std::bad_alloc&)
6284 {
6285 return error(GL_OUT_OF_MEMORY);
6286 }
6287}
6288
6289void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6290{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006291 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006292 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006293
6294 try
6295 {
6296 if (count < 0 || transpose != GL_FALSE)
6297 {
6298 return error(GL_INVALID_VALUE);
6299 }
6300
6301 if (location == -1)
6302 {
6303 return;
6304 }
6305
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006306 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006307
6308 if (context)
6309 {
6310 gl::Program *program = context->getCurrentProgram();
6311
6312 if (!program)
6313 {
6314 return error(GL_INVALID_OPERATION);
6315 }
6316
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006317 gl::ProgramBinary *programBinary = program->getProgramBinary();
6318 if (!programBinary)
6319 {
6320 return error(GL_INVALID_OPERATION);
6321 }
6322
6323 if (!programBinary->setUniformMatrix3fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006324 {
6325 return error(GL_INVALID_OPERATION);
6326 }
6327 }
6328 }
6329 catch(std::bad_alloc&)
6330 {
6331 return error(GL_OUT_OF_MEMORY);
6332 }
6333}
6334
6335void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6336{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006337 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006338 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006339
6340 try
6341 {
6342 if (count < 0 || transpose != GL_FALSE)
6343 {
6344 return error(GL_INVALID_VALUE);
6345 }
6346
6347 if (location == -1)
6348 {
6349 return;
6350 }
6351
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006352 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006353
6354 if (context)
6355 {
6356 gl::Program *program = context->getCurrentProgram();
6357
6358 if (!program)
6359 {
6360 return error(GL_INVALID_OPERATION);
6361 }
6362
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006363 gl::ProgramBinary *programBinary = program->getProgramBinary();
6364 if (!programBinary)
6365 {
6366 return error(GL_INVALID_OPERATION);
6367 }
6368
6369 if (!programBinary->setUniformMatrix4fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006370 {
6371 return error(GL_INVALID_OPERATION);
6372 }
6373 }
6374 }
6375 catch(std::bad_alloc&)
6376 {
6377 return error(GL_OUT_OF_MEMORY);
6378 }
6379}
6380
6381void __stdcall glUseProgram(GLuint program)
6382{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006383 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006384
6385 try
6386 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006387 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006388
6389 if (context)
6390 {
6391 gl::Program *programObject = context->getProgram(program);
6392
daniel@transgaming.comc8478202010-04-13 19:53:35 +00006393 if (!programObject && program != 0)
6394 {
6395 if (context->getShader(program))
6396 {
6397 return error(GL_INVALID_OPERATION);
6398 }
6399 else
6400 {
6401 return error(GL_INVALID_VALUE);
6402 }
6403 }
6404
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006405 if (program != 0 && !programObject->getProgramBinary())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006406 {
6407 return error(GL_INVALID_OPERATION);
6408 }
6409
6410 context->useProgram(program);
6411 }
6412 }
6413 catch(std::bad_alloc&)
6414 {
6415 return error(GL_OUT_OF_MEMORY);
6416 }
6417}
6418
6419void __stdcall glValidateProgram(GLuint program)
6420{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006421 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006422
6423 try
6424 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006425 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006426
6427 if (context)
6428 {
6429 gl::Program *programObject = context->getProgram(program);
6430
6431 if (!programObject)
6432 {
6433 if (context->getShader(program))
6434 {
6435 return error(GL_INVALID_OPERATION);
6436 }
6437 else
6438 {
6439 return error(GL_INVALID_VALUE);
6440 }
6441 }
6442
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006443 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
6444 if (!programBinary)
6445 {
6446 return;
6447 }
6448
6449 programBinary->validate();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006450 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006451 }
6452 catch(std::bad_alloc&)
6453 {
6454 return error(GL_OUT_OF_MEMORY);
6455 }
6456}
6457
6458void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
6459{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006460 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006461
6462 try
6463 {
6464 if (index >= gl::MAX_VERTEX_ATTRIBS)
6465 {
6466 return error(GL_INVALID_VALUE);
6467 }
6468
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006469 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006470
6471 if (context)
6472 {
6473 GLfloat vals[4] = { x, 0, 0, 1 };
6474 context->setVertexAttrib(index, vals);
6475 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006476 }
6477 catch(std::bad_alloc&)
6478 {
6479 return error(GL_OUT_OF_MEMORY);
6480 }
6481}
6482
6483void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
6484{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006485 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006486
6487 try
6488 {
6489 if (index >= gl::MAX_VERTEX_ATTRIBS)
6490 {
6491 return error(GL_INVALID_VALUE);
6492 }
6493
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006494 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006495
6496 if (context)
6497 {
6498 GLfloat vals[4] = { values[0], 0, 0, 1 };
6499 context->setVertexAttrib(index, vals);
6500 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006501 }
6502 catch(std::bad_alloc&)
6503 {
6504 return error(GL_OUT_OF_MEMORY);
6505 }
6506}
6507
6508void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6509{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006510 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006511
6512 try
6513 {
6514 if (index >= gl::MAX_VERTEX_ATTRIBS)
6515 {
6516 return error(GL_INVALID_VALUE);
6517 }
6518
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006519 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006520
6521 if (context)
6522 {
6523 GLfloat vals[4] = { x, y, 0, 1 };
6524 context->setVertexAttrib(index, vals);
6525 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006526 }
6527 catch(std::bad_alloc&)
6528 {
6529 return error(GL_OUT_OF_MEMORY);
6530 }
6531}
6532
6533void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
6534{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006535 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006536
6537 try
6538 {
6539 if (index >= gl::MAX_VERTEX_ATTRIBS)
6540 {
6541 return error(GL_INVALID_VALUE);
6542 }
6543
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006544 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006545
6546 if (context)
6547 {
6548 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6549 context->setVertexAttrib(index, vals);
6550 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006551 }
6552 catch(std::bad_alloc&)
6553 {
6554 return error(GL_OUT_OF_MEMORY);
6555 }
6556}
6557
6558void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6559{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006560 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 +00006561
6562 try
6563 {
6564 if (index >= gl::MAX_VERTEX_ATTRIBS)
6565 {
6566 return error(GL_INVALID_VALUE);
6567 }
6568
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006569 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006570
6571 if (context)
6572 {
6573 GLfloat vals[4] = { x, y, z, 1 };
6574 context->setVertexAttrib(index, vals);
6575 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006576 }
6577 catch(std::bad_alloc&)
6578 {
6579 return error(GL_OUT_OF_MEMORY);
6580 }
6581}
6582
6583void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
6584{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006585 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006586
6587 try
6588 {
6589 if (index >= gl::MAX_VERTEX_ATTRIBS)
6590 {
6591 return error(GL_INVALID_VALUE);
6592 }
6593
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006594 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006595
6596 if (context)
6597 {
6598 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6599 context->setVertexAttrib(index, vals);
6600 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006601 }
6602 catch(std::bad_alloc&)
6603 {
6604 return error(GL_OUT_OF_MEMORY);
6605 }
6606}
6607
6608void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6609{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006610 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 +00006611
6612 try
6613 {
6614 if (index >= gl::MAX_VERTEX_ATTRIBS)
6615 {
6616 return error(GL_INVALID_VALUE);
6617 }
6618
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006619 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006620
6621 if (context)
6622 {
6623 GLfloat vals[4] = { x, y, z, w };
6624 context->setVertexAttrib(index, vals);
6625 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006626 }
6627 catch(std::bad_alloc&)
6628 {
6629 return error(GL_OUT_OF_MEMORY);
6630 }
6631}
6632
6633void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
6634{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006635 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006636
6637 try
6638 {
6639 if (index >= gl::MAX_VERTEX_ATTRIBS)
6640 {
6641 return error(GL_INVALID_VALUE);
6642 }
6643
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006644 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006645
6646 if (context)
6647 {
6648 context->setVertexAttrib(index, values);
6649 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006650 }
6651 catch(std::bad_alloc&)
6652 {
6653 return error(GL_OUT_OF_MEMORY);
6654 }
6655}
6656
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00006657void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
6658{
6659 EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
6660
6661 try
6662 {
6663 if (index >= gl::MAX_VERTEX_ATTRIBS)
6664 {
6665 return error(GL_INVALID_VALUE);
6666 }
6667
6668 gl::Context *context = gl::getNonLostContext();
6669
6670 if (context)
6671 {
6672 context->setVertexAttribDivisor(index, divisor);
6673 }
6674 }
6675 catch(std::bad_alloc&)
6676 {
6677 return error(GL_OUT_OF_MEMORY);
6678 }
6679}
6680
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006681void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006682{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006683 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006684 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006685 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006686
6687 try
6688 {
6689 if (index >= gl::MAX_VERTEX_ATTRIBS)
6690 {
6691 return error(GL_INVALID_VALUE);
6692 }
6693
6694 if (size < 1 || size > 4)
6695 {
6696 return error(GL_INVALID_VALUE);
6697 }
6698
6699 switch (type)
6700 {
6701 case GL_BYTE:
6702 case GL_UNSIGNED_BYTE:
6703 case GL_SHORT:
6704 case GL_UNSIGNED_SHORT:
6705 case GL_FIXED:
6706 case GL_FLOAT:
6707 break;
6708 default:
6709 return error(GL_INVALID_ENUM);
6710 }
6711
6712 if (stride < 0)
6713 {
6714 return error(GL_INVALID_VALUE);
6715 }
6716
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006717 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006718
6719 if (context)
6720 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006721 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006722 }
6723 }
6724 catch(std::bad_alloc&)
6725 {
6726 return error(GL_OUT_OF_MEMORY);
6727 }
6728}
6729
6730void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6731{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006732 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 +00006733
6734 try
6735 {
6736 if (width < 0 || height < 0)
6737 {
6738 return error(GL_INVALID_VALUE);
6739 }
6740
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006741 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006742
6743 if (context)
6744 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006745 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006746 }
6747 }
6748 catch(std::bad_alloc&)
6749 {
6750 return error(GL_OUT_OF_MEMORY);
6751 }
6752}
6753
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006754void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6755 GLbitfield mask, GLenum filter)
6756{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006757 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006758 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6759 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6760 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6761
6762 try
6763 {
6764 switch (filter)
6765 {
6766 case GL_NEAREST:
6767 break;
6768 default:
6769 return error(GL_INVALID_ENUM);
6770 }
6771
6772 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6773 {
6774 return error(GL_INVALID_VALUE);
6775 }
6776
6777 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6778 {
6779 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6780 return error(GL_INVALID_OPERATION);
6781 }
6782
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006783 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006784
6785 if (context)
6786 {
6787 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6788 {
6789 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6790 return error(GL_INVALID_OPERATION);
6791 }
6792
6793 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6794 }
6795 }
6796 catch(std::bad_alloc&)
6797 {
6798 return error(GL_OUT_OF_MEMORY);
6799 }
6800}
6801
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006802void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6803 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006804{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006805 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006806 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006807 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006808 target, level, internalformat, width, height, depth, border, format, type, pixels);
6809
6810 try
6811 {
6812 UNIMPLEMENTED(); // FIXME
6813 }
6814 catch(std::bad_alloc&)
6815 {
6816 return error(GL_OUT_OF_MEMORY);
6817 }
6818}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006819
6820__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6821{
6822 struct Extension
6823 {
6824 const char *name;
6825 __eglMustCastToProperFunctionPointerType address;
6826 };
6827
6828 static const Extension glExtensions[] =
6829 {
6830 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006831 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006832 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006833 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6834 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6835 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6836 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6837 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6838 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6839 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006840 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006841 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006842 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6843 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6844 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6845 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00006846 {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT},
6847 {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT},
6848 {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT},
6849 {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT},
6850 {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
6851 {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
6852 {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
daniel@transgaming.comdce02fd2012-01-27 15:39:51 +00006853 {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE},
6854 {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE},
6855 {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006856 };
6857
6858 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6859 {
6860 if (strcmp(procname, glExtensions[ext].name) == 0)
6861 {
6862 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6863 }
6864 }
6865
6866 return NULL;
6867}
6868
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006869// Non-public functions used by EGL
6870
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006871bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006872{
6873 EVENT("(egl::Surface* surface = 0x%0.8p)",
6874 surface);
6875
6876 try
6877 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006878 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006879
6880 if (context)
6881 {
6882 gl::Texture2D *textureObject = context->getTexture2D();
6883
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006884 if (textureObject->isImmutable())
6885 {
6886 return false;
6887 }
6888
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006889 if (textureObject)
6890 {
6891 textureObject->bindTexImage(surface);
6892 }
6893 }
6894 }
6895 catch(std::bad_alloc&)
6896 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006897 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006898 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006899
6900 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006901}
6902
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006903}