blob: 294c6863bfbe21b14047964a73c0c051c7158fae [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"
apatrick@chromium.orgea09f9b2012-06-08 00:45:32 +000027#include "libGLESv2/ProgramBinary.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000028#include "libGLESv2/Renderbuffer.h"
29#include "libGLESv2/Shader.h"
30#include "libGLESv2/Texture.h"
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000031#include "libGLESv2/Query.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000032
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +000033bool validImageSize(GLint level, GLsizei width, GLsizei height)
34{
35 if (level < 0 || width < 0 || height < 0)
36 {
37 return false;
38 }
39
40 if (gl::getContext() && gl::getContext()->supportsNonPower2Texture())
41 {
42 return true;
43 }
44
45 if (level == 0)
46 {
47 return true;
48 }
49
50 if (gl::isPow2(width) && gl::isPow2(height))
51 {
52 return true;
53 }
54
55 return false;
56}
57
daniel@transgaming.com8833dd22012-06-05 19:49:58 +000058// Verify that format/type are one of the combinations from table 3.4.
59bool checkTextureFormatType(GLenum format, GLenum type)
60{
61 // validate <format> by itself (used as secondary key below)
62 switch (format)
63 {
64 case GL_RGBA:
65 case GL_BGRA_EXT:
66 case GL_RGB:
67 case GL_ALPHA:
68 case GL_LUMINANCE:
69 case GL_LUMINANCE_ALPHA:
70 case GL_DEPTH_COMPONENT:
71 case GL_DEPTH_STENCIL_OES:
72 break;
73 default:
74 return error(GL_INVALID_ENUM, false);
75 }
76
77 // invalid <type> -> sets INVALID_ENUM
78 // invalid <format>+<type> combination -> sets INVALID_OPERATION
79 switch (type)
80 {
81 case GL_UNSIGNED_BYTE:
82 switch (format)
83 {
84 case GL_RGBA:
85 case GL_BGRA_EXT:
86 case GL_RGB:
87 case GL_ALPHA:
88 case GL_LUMINANCE:
89 case GL_LUMINANCE_ALPHA:
90 return true;
91 default:
92 return error(GL_INVALID_OPERATION, false);
93 }
94
95 case GL_FLOAT:
96 case GL_HALF_FLOAT_OES:
97 switch (format)
98 {
99 case GL_RGBA:
100 case GL_RGB:
101 case GL_ALPHA:
102 case GL_LUMINANCE:
103 case GL_LUMINANCE_ALPHA:
104 return true;
105 default:
106 return error(GL_INVALID_OPERATION, false);
107 }
108
109 case GL_UNSIGNED_SHORT_4_4_4_4:
110 case GL_UNSIGNED_SHORT_5_5_5_1:
111 switch (format)
112 {
113 case GL_RGBA:
114 return true;
115 default:
116 return error(GL_INVALID_OPERATION, false);
117 }
118
119 case GL_UNSIGNED_SHORT_5_6_5:
120 switch (format)
121 {
122 case GL_RGB:
123 return true;
124 default:
125 return error(GL_INVALID_OPERATION, false);
126 }
127
128 case GL_UNSIGNED_SHORT:
129 case GL_UNSIGNED_INT:
130 switch (format)
131 {
132 case GL_DEPTH_COMPONENT:
133 return true;
134 default:
135 return error(GL_INVALID_OPERATION, false);
136 }
137
138 case GL_UNSIGNED_INT_24_8_OES:
139 switch (format)
140 {
141 case GL_DEPTH_STENCIL_OES:
142 return true;
143 default:
144 return error(GL_INVALID_OPERATION, false);
145 }
146
147 default:
148 return error(GL_INVALID_ENUM, false);
149 }
150}
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000151bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
152 GLint xoffset, GLint yoffset, GLint level, GLenum format,
153 gl::Texture2D *texture)
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000154{
155 if (!texture)
156 {
157 return error(GL_INVALID_OPERATION, false);
158 }
159
daniel@transgaming.com92f49922012-05-09 15:49:19 +0000160 if (compressed != texture->isCompressed(level))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000161 {
162 return error(GL_INVALID_OPERATION, false);
163 }
164
daniel@transgaming.com92f49922012-05-09 15:49:19 +0000165 if (format != GL_NONE && format != texture->getInternalFormat(level))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000166 {
167 return error(GL_INVALID_OPERATION, false);
168 }
169
170 if (compressed)
171 {
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000172 if ((width % 4 != 0 && width != texture->getWidth(0)) ||
173 (height % 4 != 0 && height != texture->getHeight(0)))
174 {
175 return error(GL_INVALID_OPERATION, false);
176 }
177 }
178
179 if (xoffset + width > texture->getWidth(level) ||
180 yoffset + height > texture->getHeight(level))
181 {
182 return error(GL_INVALID_VALUE, false);
183 }
184
185 return true;
186}
187
188bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000189 GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format,
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000190 gl::TextureCubeMap *texture)
191{
192 if (!texture)
193 {
194 return error(GL_INVALID_OPERATION, false);
195 }
196
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000197 if (compressed != texture->isCompressed(target, level))
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000198 {
199 return error(GL_INVALID_OPERATION, false);
200 }
201
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000202 if (format != GL_NONE && format != texture->getInternalFormat(target, level))
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000203 {
204 return error(GL_INVALID_OPERATION, false);
205 }
206
207 if (compressed)
208 {
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000209 if ((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
210 (height % 4 != 0 && height != texture->getHeight(target, 0)))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000211 {
212 return error(GL_INVALID_OPERATION, false);
213 }
214 }
215
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000216 if (xoffset + width > texture->getWidth(target, level) ||
217 yoffset + height > texture->getHeight(target, level))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000218 {
219 return error(GL_INVALID_VALUE, false);
220 }
221
222 return true;
223}
224
daniel@transgaming.comb7915a52011-11-12 03:14:20 +0000225// check for combinations of format and type that are valid for ReadPixels
226bool validReadFormatType(GLenum format, GLenum type)
227{
228 switch (format)
229 {
230 case GL_RGBA:
231 switch (type)
232 {
233 case GL_UNSIGNED_BYTE:
234 break;
235 default:
236 return false;
237 }
238 break;
239 case GL_BGRA_EXT:
240 switch (type)
241 {
242 case GL_UNSIGNED_BYTE:
243 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
244 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
245 break;
246 default:
247 return false;
248 }
249 break;
250 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
251 switch (type)
252 {
253 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
254 break;
255 default:
256 return false;
257 }
258 break;
259 default:
260 return false;
261 }
262 return true;
263}
264
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000265extern "C"
266{
267
268void __stdcall glActiveTexture(GLenum texture)
269{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000270 EVENT("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000271
272 try
273 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000274 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000275
276 if (context)
277 {
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +0000278 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
279 {
280 return error(GL_INVALID_ENUM);
281 }
282
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000283 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000284 }
285 }
286 catch(std::bad_alloc&)
287 {
288 return error(GL_OUT_OF_MEMORY);
289 }
290}
291
292void __stdcall glAttachShader(GLuint program, GLuint shader)
293{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000294 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000295
296 try
297 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000298 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000299
300 if (context)
301 {
302 gl::Program *programObject = context->getProgram(program);
303 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000304
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000305 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000306 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000307 if (context->getShader(program))
308 {
309 return error(GL_INVALID_OPERATION);
310 }
311 else
312 {
313 return error(GL_INVALID_VALUE);
314 }
315 }
316
317 if (!shaderObject)
318 {
319 if (context->getProgram(shader))
320 {
321 return error(GL_INVALID_OPERATION);
322 }
323 else
324 {
325 return error(GL_INVALID_VALUE);
326 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000327 }
328
329 if (!programObject->attachShader(shaderObject))
330 {
331 return error(GL_INVALID_OPERATION);
332 }
333 }
334 }
335 catch(std::bad_alloc&)
336 {
337 return error(GL_OUT_OF_MEMORY);
338 }
339}
340
daniel@transgaming.com86bdb822012-01-20 18:24:39 +0000341void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
342{
343 EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
344
345 try
346 {
347 switch (target)
348 {
349 case GL_ANY_SAMPLES_PASSED_EXT:
350 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
351 break;
352 default:
353 return error(GL_INVALID_ENUM);
354 }
355
356 if (id == 0)
357 {
358 return error(GL_INVALID_OPERATION);
359 }
360
361 gl::Context *context = gl::getNonLostContext();
362
363 if (context)
364 {
365 context->beginQuery(target, id);
366 }
367 }
368 catch(std::bad_alloc&)
369 {
370 return error(GL_OUT_OF_MEMORY);
371 }
372}
373
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000374void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000375{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000376 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000377
378 try
379 {
380 if (index >= gl::MAX_VERTEX_ATTRIBS)
381 {
382 return error(GL_INVALID_VALUE);
383 }
384
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000385 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000386
387 if (context)
388 {
389 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000390
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000391 if (!programObject)
392 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000393 if (context->getShader(program))
394 {
395 return error(GL_INVALID_OPERATION);
396 }
397 else
398 {
399 return error(GL_INVALID_VALUE);
400 }
401 }
402
403 if (strncmp(name, "gl_", 3) == 0)
404 {
405 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000406 }
407
408 programObject->bindAttributeLocation(index, name);
409 }
410 }
411 catch(std::bad_alloc&)
412 {
413 return error(GL_OUT_OF_MEMORY);
414 }
415}
416
417void __stdcall glBindBuffer(GLenum target, GLuint buffer)
418{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000419 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000420
421 try
422 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000423 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000424
425 if (context)
426 {
427 switch (target)
428 {
429 case GL_ARRAY_BUFFER:
430 context->bindArrayBuffer(buffer);
431 return;
432 case GL_ELEMENT_ARRAY_BUFFER:
433 context->bindElementArrayBuffer(buffer);
434 return;
435 default:
436 return error(GL_INVALID_ENUM);
437 }
438 }
439 }
440 catch(std::bad_alloc&)
441 {
442 return error(GL_OUT_OF_MEMORY);
443 }
444}
445
446void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
447{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000448 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000449
450 try
451 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000452 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000453 {
454 return error(GL_INVALID_ENUM);
455 }
456
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000457 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000458
459 if (context)
460 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000461 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
462 {
463 context->bindReadFramebuffer(framebuffer);
464 }
465
466 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
467 {
468 context->bindDrawFramebuffer(framebuffer);
469 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000470 }
471 }
472 catch(std::bad_alloc&)
473 {
474 return error(GL_OUT_OF_MEMORY);
475 }
476}
477
478void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
479{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000480 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000481
482 try
483 {
484 if (target != GL_RENDERBUFFER)
485 {
486 return error(GL_INVALID_ENUM);
487 }
488
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000489 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000490
491 if (context)
492 {
493 context->bindRenderbuffer(renderbuffer);
494 }
495 }
496 catch(std::bad_alloc&)
497 {
498 return error(GL_OUT_OF_MEMORY);
499 }
500}
501
502void __stdcall glBindTexture(GLenum target, GLuint texture)
503{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000504 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000505
506 try
507 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000508 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000509
510 if (context)
511 {
512 gl::Texture *textureObject = context->getTexture(texture);
513
514 if (textureObject && textureObject->getTarget() != target && texture != 0)
515 {
516 return error(GL_INVALID_OPERATION);
517 }
518
519 switch (target)
520 {
521 case GL_TEXTURE_2D:
522 context->bindTexture2D(texture);
523 return;
524 case GL_TEXTURE_CUBE_MAP:
525 context->bindTextureCubeMap(texture);
526 return;
527 default:
528 return error(GL_INVALID_ENUM);
529 }
530 }
531 }
532 catch(std::bad_alloc&)
533 {
534 return error(GL_OUT_OF_MEMORY);
535 }
536}
537
538void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
539{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000540 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000541 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000542
543 try
544 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000545 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000546
547 if (context)
548 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000549 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000550 }
551 }
552 catch(std::bad_alloc&)
553 {
554 return error(GL_OUT_OF_MEMORY);
555 }
556}
557
558void __stdcall glBlendEquation(GLenum mode)
559{
560 glBlendEquationSeparate(mode, mode);
561}
562
563void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
564{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000565 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000566
567 try
568 {
569 switch (modeRGB)
570 {
571 case GL_FUNC_ADD:
572 case GL_FUNC_SUBTRACT:
573 case GL_FUNC_REVERSE_SUBTRACT:
574 break;
575 default:
576 return error(GL_INVALID_ENUM);
577 }
578
579 switch (modeAlpha)
580 {
581 case GL_FUNC_ADD:
582 case GL_FUNC_SUBTRACT:
583 case GL_FUNC_REVERSE_SUBTRACT:
584 break;
585 default:
586 return error(GL_INVALID_ENUM);
587 }
588
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000589 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000590
591 if (context)
592 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000593 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000594 }
595 }
596 catch(std::bad_alloc&)
597 {
598 return error(GL_OUT_OF_MEMORY);
599 }
600}
601
602void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
603{
604 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
605}
606
607void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
608{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000609 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 +0000610 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000611
612 try
613 {
614 switch (srcRGB)
615 {
616 case GL_ZERO:
617 case GL_ONE:
618 case GL_SRC_COLOR:
619 case GL_ONE_MINUS_SRC_COLOR:
620 case GL_DST_COLOR:
621 case GL_ONE_MINUS_DST_COLOR:
622 case GL_SRC_ALPHA:
623 case GL_ONE_MINUS_SRC_ALPHA:
624 case GL_DST_ALPHA:
625 case GL_ONE_MINUS_DST_ALPHA:
626 case GL_CONSTANT_COLOR:
627 case GL_ONE_MINUS_CONSTANT_COLOR:
628 case GL_CONSTANT_ALPHA:
629 case GL_ONE_MINUS_CONSTANT_ALPHA:
630 case GL_SRC_ALPHA_SATURATE:
631 break;
632 default:
633 return error(GL_INVALID_ENUM);
634 }
635
636 switch (dstRGB)
637 {
638 case GL_ZERO:
639 case GL_ONE:
640 case GL_SRC_COLOR:
641 case GL_ONE_MINUS_SRC_COLOR:
642 case GL_DST_COLOR:
643 case GL_ONE_MINUS_DST_COLOR:
644 case GL_SRC_ALPHA:
645 case GL_ONE_MINUS_SRC_ALPHA:
646 case GL_DST_ALPHA:
647 case GL_ONE_MINUS_DST_ALPHA:
648 case GL_CONSTANT_COLOR:
649 case GL_ONE_MINUS_CONSTANT_COLOR:
650 case GL_CONSTANT_ALPHA:
651 case GL_ONE_MINUS_CONSTANT_ALPHA:
652 break;
653 default:
654 return error(GL_INVALID_ENUM);
655 }
656
657 switch (srcAlpha)
658 {
659 case GL_ZERO:
660 case GL_ONE:
661 case GL_SRC_COLOR:
662 case GL_ONE_MINUS_SRC_COLOR:
663 case GL_DST_COLOR:
664 case GL_ONE_MINUS_DST_COLOR:
665 case GL_SRC_ALPHA:
666 case GL_ONE_MINUS_SRC_ALPHA:
667 case GL_DST_ALPHA:
668 case GL_ONE_MINUS_DST_ALPHA:
669 case GL_CONSTANT_COLOR:
670 case GL_ONE_MINUS_CONSTANT_COLOR:
671 case GL_CONSTANT_ALPHA:
672 case GL_ONE_MINUS_CONSTANT_ALPHA:
673 case GL_SRC_ALPHA_SATURATE:
674 break;
675 default:
676 return error(GL_INVALID_ENUM);
677 }
678
679 switch (dstAlpha)
680 {
681 case GL_ZERO:
682 case GL_ONE:
683 case GL_SRC_COLOR:
684 case GL_ONE_MINUS_SRC_COLOR:
685 case GL_DST_COLOR:
686 case GL_ONE_MINUS_DST_COLOR:
687 case GL_SRC_ALPHA:
688 case GL_ONE_MINUS_SRC_ALPHA:
689 case GL_DST_ALPHA:
690 case GL_ONE_MINUS_DST_ALPHA:
691 case GL_CONSTANT_COLOR:
692 case GL_ONE_MINUS_CONSTANT_COLOR:
693 case GL_CONSTANT_ALPHA:
694 case GL_ONE_MINUS_CONSTANT_ALPHA:
695 break;
696 default:
697 return error(GL_INVALID_ENUM);
698 }
699
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000700 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
701 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
702
703 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
704 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
705
706 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000707 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000708 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
709 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000710 }
711
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000712 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000713
714 if (context)
715 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000716 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000717 }
718 }
719 catch(std::bad_alloc&)
720 {
721 return error(GL_OUT_OF_MEMORY);
722 }
723}
724
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000725void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000726{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000727 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 +0000728 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000729
730 try
731 {
732 if (size < 0)
733 {
734 return error(GL_INVALID_VALUE);
735 }
736
737 switch (usage)
738 {
739 case GL_STREAM_DRAW:
740 case GL_STATIC_DRAW:
741 case GL_DYNAMIC_DRAW:
742 break;
743 default:
744 return error(GL_INVALID_ENUM);
745 }
746
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000747 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748
749 if (context)
750 {
751 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000752
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000753 switch (target)
754 {
755 case GL_ARRAY_BUFFER:
756 buffer = context->getArrayBuffer();
757 break;
758 case GL_ELEMENT_ARRAY_BUFFER:
759 buffer = context->getElementArrayBuffer();
760 break;
761 default:
762 return error(GL_INVALID_ENUM);
763 }
764
765 if (!buffer)
766 {
767 return error(GL_INVALID_OPERATION);
768 }
769
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000770 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000771 }
772 }
773 catch(std::bad_alloc&)
774 {
775 return error(GL_OUT_OF_MEMORY);
776 }
777}
778
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000779void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000780{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000781 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 +0000782 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000783
784 try
785 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000786 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000787 {
788 return error(GL_INVALID_VALUE);
789 }
790
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000791 if (data == NULL)
792 {
793 return;
794 }
795
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000796 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000797
798 if (context)
799 {
800 gl::Buffer *buffer;
801
802 switch (target)
803 {
804 case GL_ARRAY_BUFFER:
805 buffer = context->getArrayBuffer();
806 break;
807 case GL_ELEMENT_ARRAY_BUFFER:
808 buffer = context->getElementArrayBuffer();
809 break;
810 default:
811 return error(GL_INVALID_ENUM);
812 }
813
814 if (!buffer)
815 {
816 return error(GL_INVALID_OPERATION);
817 }
818
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000819 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000820 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000821 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000822 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000823
824 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000825 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000826 }
827 catch(std::bad_alloc&)
828 {
829 return error(GL_OUT_OF_MEMORY);
830 }
831}
832
833GLenum __stdcall glCheckFramebufferStatus(GLenum target)
834{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000835 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000836
837 try
838 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000839 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000840 {
841 return error(GL_INVALID_ENUM, 0);
842 }
843
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000844 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000845
846 if (context)
847 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000848 gl::Framebuffer *framebuffer = NULL;
849 if (target == GL_READ_FRAMEBUFFER_ANGLE)
850 {
851 framebuffer = context->getReadFramebuffer();
852 }
853 else
854 {
855 framebuffer = context->getDrawFramebuffer();
856 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000857
858 return framebuffer->completeness();
859 }
860 }
861 catch(std::bad_alloc&)
862 {
863 return error(GL_OUT_OF_MEMORY, 0);
864 }
865
866 return 0;
867}
868
869void __stdcall glClear(GLbitfield mask)
870{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000871 EVENT("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000872
873 try
874 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000875 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000876
877 if (context)
878 {
879 context->clear(mask);
880 }
881 }
882 catch(std::bad_alloc&)
883 {
884 return error(GL_OUT_OF_MEMORY);
885 }
886}
887
888void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
889{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000890 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000891 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000892
893 try
894 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000895 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000896
897 if (context)
898 {
899 context->setClearColor(red, green, blue, alpha);
900 }
901 }
902 catch(std::bad_alloc&)
903 {
904 return error(GL_OUT_OF_MEMORY);
905 }
906}
907
908void __stdcall glClearDepthf(GLclampf depth)
909{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000910 EVENT("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000911
912 try
913 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000914 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000915
916 if (context)
917 {
918 context->setClearDepth(depth);
919 }
920 }
921 catch(std::bad_alloc&)
922 {
923 return error(GL_OUT_OF_MEMORY);
924 }
925}
926
927void __stdcall glClearStencil(GLint s)
928{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000929 EVENT("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000930
931 try
932 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000933 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000934
935 if (context)
936 {
937 context->setClearStencil(s);
938 }
939 }
940 catch(std::bad_alloc&)
941 {
942 return error(GL_OUT_OF_MEMORY);
943 }
944}
945
946void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
947{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000948 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000949 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000950
951 try
952 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000953 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000954
955 if (context)
956 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000957 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000958 }
959 }
960 catch(std::bad_alloc&)
961 {
962 return error(GL_OUT_OF_MEMORY);
963 }
964}
965
966void __stdcall glCompileShader(GLuint shader)
967{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000968 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000969
970 try
971 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000972 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000973
974 if (context)
975 {
976 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000977
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000978 if (!shaderObject)
979 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000980 if (context->getProgram(shader))
981 {
982 return error(GL_INVALID_OPERATION);
983 }
984 else
985 {
986 return error(GL_INVALID_VALUE);
987 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000988 }
989
990 shaderObject->compile();
991 }
992 }
993 catch(std::bad_alloc&)
994 {
995 return error(GL_OUT_OF_MEMORY);
996 }
997}
998
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000999void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
1000 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001001{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001002 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001003 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001004 target, level, internalformat, width, height, border, imageSize, data);
1005
1006 try
1007 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001008 if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001009 {
1010 return error(GL_INVALID_VALUE);
1011 }
1012
daniel@transgaming.com01868132010-08-24 19:21:17 +00001013 switch (internalformat)
1014 {
1015 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1016 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001017 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1018 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001019 break;
1020 default:
1021 return error(GL_INVALID_ENUM);
1022 }
1023
1024 if (border != 0)
1025 {
1026 return error(GL_INVALID_VALUE);
1027 }
1028
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001029 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001030
1031 if (context)
1032 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001033 if (level > context->getMaximumTextureLevel())
1034 {
1035 return error(GL_INVALID_VALUE);
1036 }
1037
1038 switch (target)
1039 {
1040 case GL_TEXTURE_2D:
1041 if (width > (context->getMaximumTextureDimension() >> level) ||
1042 height > (context->getMaximumTextureDimension() >> level))
1043 {
1044 return error(GL_INVALID_VALUE);
1045 }
1046 break;
1047 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1048 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1049 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1050 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1051 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1052 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1053 if (width != height)
1054 {
1055 return error(GL_INVALID_VALUE);
1056 }
1057
1058 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1059 height > (context->getMaximumCubeTextureDimension() >> level))
1060 {
1061 return error(GL_INVALID_VALUE);
1062 }
1063 break;
1064 default:
1065 return error(GL_INVALID_ENUM);
1066 }
1067
gman@chromium.org50c526d2011-08-10 05:19:44 +00001068 switch (internalformat) {
1069 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1070 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1071 if (!context->supportsDXT1Textures())
1072 {
1073 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1074 }
1075 break;
1076 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1077 if (!context->supportsDXT3Textures())
1078 {
1079 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1080 }
1081 break;
1082 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1083 if (!context->supportsDXT5Textures())
1084 {
1085 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1086 }
1087 break;
1088 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001089 }
1090
1091 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
1092 {
1093 return error(GL_INVALID_VALUE);
1094 }
1095
1096 if (target == GL_TEXTURE_2D)
1097 {
1098 gl::Texture2D *texture = context->getTexture2D();
1099
1100 if (!texture)
1101 {
1102 return error(GL_INVALID_OPERATION);
1103 }
1104
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001105 if (texture->isImmutable())
1106 {
1107 return error(GL_INVALID_OPERATION);
1108 }
1109
daniel@transgaming.com01868132010-08-24 19:21:17 +00001110 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
1111 }
1112 else
1113 {
1114 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1115
1116 if (!texture)
1117 {
1118 return error(GL_INVALID_OPERATION);
1119 }
1120
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001121 if (texture->isImmutable())
1122 {
1123 return error(GL_INVALID_OPERATION);
1124 }
1125
daniel@transgaming.com01868132010-08-24 19:21:17 +00001126 switch (target)
1127 {
1128 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1129 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1130 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1131 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1132 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1133 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1134 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
1135 break;
1136 default: UNREACHABLE();
1137 }
1138 }
1139 }
1140
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001141 }
1142 catch(std::bad_alloc&)
1143 {
1144 return error(GL_OUT_OF_MEMORY);
1145 }
1146}
1147
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001148void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
1149 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001150{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001151 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001152 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001153 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001154 target, level, xoffset, yoffset, width, height, format, imageSize, data);
1155
1156 try
1157 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00001158 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +00001159 {
1160 return error(GL_INVALID_ENUM);
1161 }
1162
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001163 if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001164 {
1165 return error(GL_INVALID_VALUE);
1166 }
1167
daniel@transgaming.com01868132010-08-24 19:21:17 +00001168 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001169 {
daniel@transgaming.com01868132010-08-24 19:21:17 +00001170 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1171 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001172 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1173 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001174 break;
1175 default:
1176 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +00001177 }
1178
daniel@transgaming.com01868132010-08-24 19:21:17 +00001179 if (width == 0 || height == 0 || data == NULL)
1180 {
1181 return;
1182 }
1183
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001184 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001185
1186 if (context)
1187 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001188 if (level > context->getMaximumTextureLevel())
1189 {
1190 return error(GL_INVALID_VALUE);
1191 }
1192
gman@chromium.org50c526d2011-08-10 05:19:44 +00001193 switch (format) {
1194 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1195 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1196 if (!context->supportsDXT1Textures())
1197 {
1198 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1199 }
1200 break;
1201 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1202 if (!context->supportsDXT3Textures())
1203 {
1204 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1205 }
1206 break;
1207 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1208 if (!context->supportsDXT5Textures())
1209 {
1210 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1211 }
1212 break;
1213 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001214 }
1215
1216 if (imageSize != gl::ComputeCompressedSize(width, height, format))
1217 {
1218 return error(GL_INVALID_VALUE);
1219 }
1220
1221 if (xoffset % 4 != 0 || yoffset % 4 != 0)
1222 {
1223 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 +00001224 // does not exist unless DXT textures are supported.
daniel@transgaming.com01868132010-08-24 19:21:17 +00001225 }
1226
1227 if (target == GL_TEXTURE_2D)
1228 {
1229 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001230 if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001231 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001232 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
daniel@transgaming.com01868132010-08-24 19:21:17 +00001233 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001234 }
1235 else if (gl::IsCubemapTextureTarget(target))
1236 {
1237 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00001238 if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, texture))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001239 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001240 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
daniel@transgaming.com01868132010-08-24 19:21:17 +00001241 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001242 }
1243 else
1244 {
1245 UNREACHABLE();
1246 }
1247 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001248 }
1249 catch(std::bad_alloc&)
1250 {
1251 return error(GL_OUT_OF_MEMORY);
1252 }
1253}
1254
1255void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1256{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001257 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001258 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001259 target, level, internalformat, x, y, width, height, border);
1260
1261 try
1262 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001263 if (!validImageSize(level, width, height))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001264 {
1265 return error(GL_INVALID_VALUE);
1266 }
1267
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001268 if (border != 0)
1269 {
1270 return error(GL_INVALID_VALUE);
1271 }
1272
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001273 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001274
1275 if (context)
1276 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00001277 if (level > context->getMaximumTextureLevel())
1278 {
1279 return error(GL_INVALID_VALUE);
1280 }
1281
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001282 switch (target)
1283 {
1284 case GL_TEXTURE_2D:
1285 if (width > (context->getMaximumTextureDimension() >> level) ||
1286 height > (context->getMaximumTextureDimension() >> level))
1287 {
1288 return error(GL_INVALID_VALUE);
1289 }
1290 break;
1291 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1292 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1293 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1294 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1295 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1296 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1297 if (width != height)
1298 {
1299 return error(GL_INVALID_VALUE);
1300 }
1301
1302 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1303 height > (context->getMaximumCubeTextureDimension() >> level))
1304 {
1305 return error(GL_INVALID_VALUE);
1306 }
1307 break;
1308 default:
1309 return error(GL_INVALID_ENUM);
1310 }
1311
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001312 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001313
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001314 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1315 {
1316 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1317 }
1318
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001319 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1320 {
1321 return error(GL_INVALID_OPERATION);
1322 }
1323
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001324 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001325 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001326
1327 // [OpenGL ES 2.0.24] table 3.9
1328 switch (internalformat)
1329 {
1330 case GL_ALPHA:
1331 if (colorbufferFormat != GL_ALPHA &&
1332 colorbufferFormat != GL_RGBA &&
1333 colorbufferFormat != GL_RGBA4 &&
1334 colorbufferFormat != GL_RGB5_A1 &&
1335 colorbufferFormat != GL_RGBA8_OES)
1336 {
1337 return error(GL_INVALID_OPERATION);
1338 }
1339 break;
1340 case GL_LUMINANCE:
1341 case GL_RGB:
1342 if (colorbufferFormat != GL_RGB &&
1343 colorbufferFormat != GL_RGB565 &&
1344 colorbufferFormat != GL_RGB8_OES &&
1345 colorbufferFormat != GL_RGBA &&
1346 colorbufferFormat != GL_RGBA4 &&
1347 colorbufferFormat != GL_RGB5_A1 &&
1348 colorbufferFormat != GL_RGBA8_OES)
1349 {
1350 return error(GL_INVALID_OPERATION);
1351 }
1352 break;
1353 case GL_LUMINANCE_ALPHA:
1354 case GL_RGBA:
1355 if (colorbufferFormat != GL_RGBA &&
1356 colorbufferFormat != GL_RGBA4 &&
1357 colorbufferFormat != GL_RGB5_A1 &&
1358 colorbufferFormat != GL_RGBA8_OES)
1359 {
1360 return error(GL_INVALID_OPERATION);
1361 }
1362 break;
1363 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1364 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001365 if (context->supportsDXT1Textures())
1366 {
1367 return error(GL_INVALID_OPERATION);
1368 }
1369 else
1370 {
1371 return error(GL_INVALID_ENUM);
1372 }
1373 break;
1374 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1375 if (context->supportsDXT3Textures())
1376 {
1377 return error(GL_INVALID_OPERATION);
1378 }
1379 else
1380 {
1381 return error(GL_INVALID_ENUM);
1382 }
1383 break;
1384 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1385 if (context->supportsDXT5Textures())
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001386 {
1387 return error(GL_INVALID_OPERATION);
1388 }
1389 else
1390 {
1391 return error(GL_INVALID_ENUM);
1392 }
1393 break;
daniel@transgaming.com0c854682012-05-31 01:14:11 +00001394 case GL_DEPTH_COMPONENT:
1395 case GL_DEPTH_COMPONENT16:
1396 case GL_DEPTH_COMPONENT32_OES:
1397 case GL_DEPTH_STENCIL_OES:
1398 case GL_DEPTH24_STENCIL8_OES:
1399 if (context->supportsDepthTextures())
1400 {
1401 return error(GL_INVALID_OPERATION);
1402 }
1403 else
1404 {
1405 return error(GL_INVALID_ENUM);
1406 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001407 default:
1408 return error(GL_INVALID_ENUM);
1409 }
1410
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001411 if (target == GL_TEXTURE_2D)
1412 {
1413 gl::Texture2D *texture = context->getTexture2D();
1414
1415 if (!texture)
1416 {
1417 return error(GL_INVALID_OPERATION);
1418 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001419
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001420 if (texture->isImmutable())
1421 {
1422 return error(GL_INVALID_OPERATION);
1423 }
1424
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001425 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001426 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001427 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001428 {
1429 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1430
1431 if (!texture)
1432 {
1433 return error(GL_INVALID_OPERATION);
1434 }
1435
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001436 if (texture->isImmutable())
1437 {
1438 return error(GL_INVALID_OPERATION);
1439 }
1440
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001441 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001442 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001443 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001444 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001445 }
1446 catch(std::bad_alloc&)
1447 {
1448 return error(GL_OUT_OF_MEMORY);
1449 }
1450}
1451
1452void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1453{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001454 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001455 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001456 target, level, xoffset, yoffset, x, y, width, height);
1457
1458 try
1459 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00001460 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001461 {
1462 return error(GL_INVALID_ENUM);
1463 }
1464
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001465 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001466 {
1467 return error(GL_INVALID_VALUE);
1468 }
1469
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001470 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1471 {
1472 return error(GL_INVALID_VALUE);
1473 }
1474
1475 if (width == 0 || height == 0)
1476 {
1477 return;
1478 }
1479
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001480 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001481
1482 if (context)
1483 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001484 if (level > context->getMaximumTextureLevel())
1485 {
1486 return error(GL_INVALID_VALUE);
1487 }
1488
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001489 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001490
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001491 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1492 {
1493 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1494 }
1495
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001496 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1497 {
1498 return error(GL_INVALID_OPERATION);
1499 }
1500
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001501 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001502 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001503 gl::Texture *texture = NULL;
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001504 GLenum textureFormat = GL_RGBA;
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001505
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001506 if (target == GL_TEXTURE_2D)
1507 {
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001508 gl::Texture2D *tex2d = context->getTexture2D();
1509
1510 if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, tex2d))
1511 {
1512 return; // error already registered by validateSubImageParams
1513 }
daniel@transgaming.com92f49922012-05-09 15:49:19 +00001514 textureFormat = tex2d->getInternalFormat(level);
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001515 texture = tex2d;
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001516 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001517 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001518 {
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001519 gl::TextureCubeMap *texcube = context->getTextureCubeMap();
1520
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00001521 if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, texcube))
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001522 {
1523 return; // error already registered by validateSubImageParams
1524 }
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00001525 textureFormat = texcube->getInternalFormat(target, level);
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001526 texture = texcube;
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001527 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001528 else UNREACHABLE();
1529
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001530 // [OpenGL ES 2.0.24] table 3.9
1531 switch (textureFormat)
1532 {
1533 case GL_ALPHA:
1534 if (colorbufferFormat != GL_ALPHA &&
1535 colorbufferFormat != GL_RGBA &&
1536 colorbufferFormat != GL_RGBA4 &&
1537 colorbufferFormat != GL_RGB5_A1 &&
1538 colorbufferFormat != GL_RGBA8_OES)
1539 {
1540 return error(GL_INVALID_OPERATION);
1541 }
1542 break;
1543 case GL_LUMINANCE:
1544 case GL_RGB:
1545 if (colorbufferFormat != GL_RGB &&
1546 colorbufferFormat != GL_RGB565 &&
1547 colorbufferFormat != GL_RGB8_OES &&
1548 colorbufferFormat != GL_RGBA &&
1549 colorbufferFormat != GL_RGBA4 &&
1550 colorbufferFormat != GL_RGB5_A1 &&
1551 colorbufferFormat != GL_RGBA8_OES)
1552 {
1553 return error(GL_INVALID_OPERATION);
1554 }
1555 break;
1556 case GL_LUMINANCE_ALPHA:
1557 case GL_RGBA:
1558 if (colorbufferFormat != GL_RGBA &&
1559 colorbufferFormat != GL_RGBA4 &&
1560 colorbufferFormat != GL_RGB5_A1 &&
1561 colorbufferFormat != GL_RGBA8_OES)
1562 {
1563 return error(GL_INVALID_OPERATION);
1564 }
1565 break;
1566 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1567 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001568 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1569 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001570 return error(GL_INVALID_OPERATION);
daniel@transgaming.com0c854682012-05-31 01:14:11 +00001571 case GL_DEPTH_COMPONENT:
1572 case GL_DEPTH_STENCIL_OES:
1573 return error(GL_INVALID_OPERATION);
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001574 default:
1575 return error(GL_INVALID_OPERATION);
1576 }
1577
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001578 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001579 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001580 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001581
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001582 catch(std::bad_alloc&)
1583 {
1584 return error(GL_OUT_OF_MEMORY);
1585 }
1586}
1587
1588GLuint __stdcall glCreateProgram(void)
1589{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001590 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001591
1592 try
1593 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001594 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001595
1596 if (context)
1597 {
1598 return context->createProgram();
1599 }
1600 }
1601 catch(std::bad_alloc&)
1602 {
1603 return error(GL_OUT_OF_MEMORY, 0);
1604 }
1605
1606 return 0;
1607}
1608
1609GLuint __stdcall glCreateShader(GLenum type)
1610{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001611 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001612
1613 try
1614 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001615 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001616
1617 if (context)
1618 {
1619 switch (type)
1620 {
1621 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001622 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001623 return context->createShader(type);
1624 default:
1625 return error(GL_INVALID_ENUM, 0);
1626 }
1627 }
1628 }
1629 catch(std::bad_alloc&)
1630 {
1631 return error(GL_OUT_OF_MEMORY, 0);
1632 }
1633
1634 return 0;
1635}
1636
1637void __stdcall glCullFace(GLenum mode)
1638{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001639 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001640
1641 try
1642 {
1643 switch (mode)
1644 {
1645 case GL_FRONT:
1646 case GL_BACK:
1647 case GL_FRONT_AND_BACK:
1648 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001649 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001650
1651 if (context)
1652 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001653 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001654 }
1655 }
1656 break;
1657 default:
1658 return error(GL_INVALID_ENUM);
1659 }
1660 }
1661 catch(std::bad_alloc&)
1662 {
1663 return error(GL_OUT_OF_MEMORY);
1664 }
1665}
1666
1667void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1668{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001669 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001670
1671 try
1672 {
1673 if (n < 0)
1674 {
1675 return error(GL_INVALID_VALUE);
1676 }
1677
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001678 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001679
1680 if (context)
1681 {
1682 for (int i = 0; i < n; i++)
1683 {
1684 context->deleteBuffer(buffers[i]);
1685 }
1686 }
1687 }
1688 catch(std::bad_alloc&)
1689 {
1690 return error(GL_OUT_OF_MEMORY);
1691 }
1692}
1693
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001694void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1695{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001696 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001697
1698 try
1699 {
1700 if (n < 0)
1701 {
1702 return error(GL_INVALID_VALUE);
1703 }
1704
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001705 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001706
1707 if (context)
1708 {
1709 for (int i = 0; i < n; i++)
1710 {
1711 context->deleteFence(fences[i]);
1712 }
1713 }
1714 }
1715 catch(std::bad_alloc&)
1716 {
1717 return error(GL_OUT_OF_MEMORY);
1718 }
1719}
1720
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001721void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1722{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001723 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001724
1725 try
1726 {
1727 if (n < 0)
1728 {
1729 return error(GL_INVALID_VALUE);
1730 }
1731
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001732 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001733
1734 if (context)
1735 {
1736 for (int i = 0; i < n; i++)
1737 {
1738 if (framebuffers[i] != 0)
1739 {
1740 context->deleteFramebuffer(framebuffers[i]);
1741 }
1742 }
1743 }
1744 }
1745 catch(std::bad_alloc&)
1746 {
1747 return error(GL_OUT_OF_MEMORY);
1748 }
1749}
1750
1751void __stdcall glDeleteProgram(GLuint program)
1752{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001753 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001754
1755 try
1756 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001757 if (program == 0)
1758 {
1759 return;
1760 }
1761
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001762 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001763
1764 if (context)
1765 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001766 if (!context->getProgram(program))
1767 {
1768 if(context->getShader(program))
1769 {
1770 return error(GL_INVALID_OPERATION);
1771 }
1772 else
1773 {
1774 return error(GL_INVALID_VALUE);
1775 }
1776 }
1777
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001778 context->deleteProgram(program);
1779 }
1780 }
1781 catch(std::bad_alloc&)
1782 {
1783 return error(GL_OUT_OF_MEMORY);
1784 }
1785}
1786
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00001787void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
1788{
1789 EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
1790
1791 try
1792 {
1793 if (n < 0)
1794 {
1795 return error(GL_INVALID_VALUE);
1796 }
1797
1798 gl::Context *context = gl::getNonLostContext();
1799
1800 if (context)
1801 {
1802 for (int i = 0; i < n; i++)
1803 {
1804 context->deleteQuery(ids[i]);
1805 }
1806 }
1807 }
1808 catch(std::bad_alloc&)
1809 {
1810 return error(GL_OUT_OF_MEMORY);
1811 }
1812}
1813
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001814void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1815{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001816 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001817
1818 try
1819 {
1820 if (n < 0)
1821 {
1822 return error(GL_INVALID_VALUE);
1823 }
1824
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001825 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001826
1827 if (context)
1828 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001829 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001830 {
1831 context->deleteRenderbuffer(renderbuffers[i]);
1832 }
1833 }
1834 }
1835 catch(std::bad_alloc&)
1836 {
1837 return error(GL_OUT_OF_MEMORY);
1838 }
1839}
1840
1841void __stdcall glDeleteShader(GLuint shader)
1842{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001843 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001844
1845 try
1846 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001847 if (shader == 0)
1848 {
1849 return;
1850 }
1851
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001852 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001853
1854 if (context)
1855 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001856 if (!context->getShader(shader))
1857 {
1858 if(context->getProgram(shader))
1859 {
1860 return error(GL_INVALID_OPERATION);
1861 }
1862 else
1863 {
1864 return error(GL_INVALID_VALUE);
1865 }
1866 }
1867
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001868 context->deleteShader(shader);
1869 }
1870 }
1871 catch(std::bad_alloc&)
1872 {
1873 return error(GL_OUT_OF_MEMORY);
1874 }
1875}
1876
1877void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1878{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001879 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001880
1881 try
1882 {
1883 if (n < 0)
1884 {
1885 return error(GL_INVALID_VALUE);
1886 }
1887
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001888 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001889
1890 if (context)
1891 {
1892 for (int i = 0; i < n; i++)
1893 {
1894 if (textures[i] != 0)
1895 {
1896 context->deleteTexture(textures[i]);
1897 }
1898 }
1899 }
1900 }
1901 catch(std::bad_alloc&)
1902 {
1903 return error(GL_OUT_OF_MEMORY);
1904 }
1905}
1906
1907void __stdcall glDepthFunc(GLenum func)
1908{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001909 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001910
1911 try
1912 {
1913 switch (func)
1914 {
1915 case GL_NEVER:
1916 case GL_ALWAYS:
1917 case GL_LESS:
1918 case GL_LEQUAL:
1919 case GL_EQUAL:
1920 case GL_GREATER:
1921 case GL_GEQUAL:
1922 case GL_NOTEQUAL:
1923 break;
1924 default:
1925 return error(GL_INVALID_ENUM);
1926 }
1927
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001928 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001929
1930 if (context)
1931 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001932 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001933 }
1934 }
1935 catch(std::bad_alloc&)
1936 {
1937 return error(GL_OUT_OF_MEMORY);
1938 }
1939}
1940
1941void __stdcall glDepthMask(GLboolean flag)
1942{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001943 EVENT("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001944
1945 try
1946 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001947 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001948
1949 if (context)
1950 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001951 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001952 }
1953 }
1954 catch(std::bad_alloc&)
1955 {
1956 return error(GL_OUT_OF_MEMORY);
1957 }
1958}
1959
1960void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1961{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001962 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001963
1964 try
1965 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001966 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001967
1968 if (context)
1969 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001970 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001971 }
1972 }
1973 catch(std::bad_alloc&)
1974 {
1975 return error(GL_OUT_OF_MEMORY);
1976 }
1977}
1978
1979void __stdcall glDetachShader(GLuint program, GLuint shader)
1980{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001981 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001982
1983 try
1984 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001985 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001986
1987 if (context)
1988 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001989
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001990 gl::Program *programObject = context->getProgram(program);
1991 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001992
1993 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001994 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001995 gl::Shader *shaderByProgramHandle;
1996 shaderByProgramHandle = context->getShader(program);
1997 if (!shaderByProgramHandle)
1998 {
1999 return error(GL_INVALID_VALUE);
2000 }
2001 else
2002 {
2003 return error(GL_INVALID_OPERATION);
2004 }
2005 }
2006
2007 if (!shaderObject)
2008 {
2009 gl::Program *programByShaderHandle = context->getProgram(shader);
2010 if (!programByShaderHandle)
2011 {
2012 return error(GL_INVALID_VALUE);
2013 }
2014 else
2015 {
2016 return error(GL_INVALID_OPERATION);
2017 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002018 }
2019
2020 if (!programObject->detachShader(shaderObject))
2021 {
2022 return error(GL_INVALID_OPERATION);
2023 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002024 }
2025 }
2026 catch(std::bad_alloc&)
2027 {
2028 return error(GL_OUT_OF_MEMORY);
2029 }
2030}
2031
2032void __stdcall glDisable(GLenum cap)
2033{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002034 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002035
2036 try
2037 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002038 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002039
2040 if (context)
2041 {
2042 switch (cap)
2043 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002044 case GL_CULL_FACE: context->setCullFace(false); break;
2045 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
2046 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
2047 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
2048 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
2049 case GL_STENCIL_TEST: context->setStencilTest(false); break;
2050 case GL_DEPTH_TEST: context->setDepthTest(false); break;
2051 case GL_BLEND: context->setBlend(false); break;
2052 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002053 default:
2054 return error(GL_INVALID_ENUM);
2055 }
2056 }
2057 }
2058 catch(std::bad_alloc&)
2059 {
2060 return error(GL_OUT_OF_MEMORY);
2061 }
2062}
2063
2064void __stdcall glDisableVertexAttribArray(GLuint index)
2065{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002066 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002067
2068 try
2069 {
2070 if (index >= gl::MAX_VERTEX_ATTRIBS)
2071 {
2072 return error(GL_INVALID_VALUE);
2073 }
2074
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002075 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002076
2077 if (context)
2078 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002079 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002080 }
2081 }
2082 catch(std::bad_alloc&)
2083 {
2084 return error(GL_OUT_OF_MEMORY);
2085 }
2086}
2087
2088void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
2089{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002090 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002091
2092 try
2093 {
2094 if (count < 0 || first < 0)
2095 {
2096 return error(GL_INVALID_VALUE);
2097 }
2098
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002099 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002100
2101 if (context)
2102 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002103 context->drawArrays(mode, first, count, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002104 }
2105 }
2106 catch(std::bad_alloc&)
2107 {
2108 return error(GL_OUT_OF_MEMORY);
2109 }
2110}
2111
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002112void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
2113{
2114 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
2115
2116 try
2117 {
2118 if (count < 0 || first < 0 || primcount < 0)
2119 {
2120 return error(GL_INVALID_VALUE);
2121 }
2122
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002123 if (primcount > 0)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002124 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002125 gl::Context *context = gl::getNonLostContext();
2126
2127 if (context)
2128 {
2129 context->drawArrays(mode, first, count, primcount);
2130 }
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002131 }
2132 }
2133 catch(std::bad_alloc&)
2134 {
2135 return error(GL_OUT_OF_MEMORY);
2136 }
2137}
2138
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002139void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002140{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002141 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 +00002142 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002143
2144 try
2145 {
2146 if (count < 0)
2147 {
2148 return error(GL_INVALID_VALUE);
2149 }
2150
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002151 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002152
2153 if (context)
2154 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002155 switch (type)
2156 {
2157 case GL_UNSIGNED_BYTE:
2158 case GL_UNSIGNED_SHORT:
2159 break;
2160 case GL_UNSIGNED_INT:
2161 if (!context->supports32bitIndices())
2162 {
2163 return error(GL_INVALID_ENUM);
2164 }
2165 break;
2166 default:
2167 return error(GL_INVALID_ENUM);
2168 }
2169
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002170 context->drawElements(mode, count, type, indices, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002171 }
2172 }
2173 catch(std::bad_alloc&)
2174 {
2175 return error(GL_OUT_OF_MEMORY);
2176 }
2177}
2178
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002179void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)
2180{
2181 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)",
2182 mode, count, type, indices, primcount);
2183
2184 try
2185 {
2186 if (count < 0 || primcount < 0)
2187 {
2188 return error(GL_INVALID_VALUE);
2189 }
2190
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002191 if (primcount > 0)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002192 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002193 gl::Context *context = gl::getNonLostContext();
2194
2195 if (context)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002196 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002197 switch (type)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002198 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002199 case GL_UNSIGNED_BYTE:
2200 case GL_UNSIGNED_SHORT:
2201 break;
2202 case GL_UNSIGNED_INT:
2203 if (!context->supports32bitIndices())
2204 {
2205 return error(GL_INVALID_ENUM);
2206 }
2207 break;
2208 default:
2209 return error(GL_INVALID_ENUM);
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002210 }
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002211
2212 context->drawElements(mode, count, type, indices, primcount);
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002213 }
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002214 }
2215 }
2216 catch(std::bad_alloc&)
2217 {
2218 return error(GL_OUT_OF_MEMORY);
2219 }
2220}
2221
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002222void __stdcall glEnable(GLenum cap)
2223{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002224 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002225
2226 try
2227 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002228 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002229
2230 if (context)
2231 {
2232 switch (cap)
2233 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002234 case GL_CULL_FACE: context->setCullFace(true); break;
2235 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
2236 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
2237 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
2238 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
2239 case GL_STENCIL_TEST: context->setStencilTest(true); break;
2240 case GL_DEPTH_TEST: context->setDepthTest(true); break;
2241 case GL_BLEND: context->setBlend(true); break;
2242 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002243 default:
2244 return error(GL_INVALID_ENUM);
2245 }
2246 }
2247 }
2248 catch(std::bad_alloc&)
2249 {
2250 return error(GL_OUT_OF_MEMORY);
2251 }
2252}
2253
2254void __stdcall glEnableVertexAttribArray(GLuint index)
2255{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002256 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002257
2258 try
2259 {
2260 if (index >= gl::MAX_VERTEX_ATTRIBS)
2261 {
2262 return error(GL_INVALID_VALUE);
2263 }
2264
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002265 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002266
2267 if (context)
2268 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002269 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002270 }
2271 }
2272 catch(std::bad_alloc&)
2273 {
2274 return error(GL_OUT_OF_MEMORY);
2275 }
2276}
2277
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00002278void __stdcall glEndQueryEXT(GLenum target)
2279{
2280 EVENT("GLenum target = 0x%X)", target);
2281
2282 try
2283 {
2284 switch (target)
2285 {
2286 case GL_ANY_SAMPLES_PASSED_EXT:
2287 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
2288 break;
2289 default:
2290 return error(GL_INVALID_ENUM);
2291 }
2292
2293 gl::Context *context = gl::getNonLostContext();
2294
2295 if (context)
2296 {
2297 context->endQuery(target);
2298 }
2299 }
2300 catch(std::bad_alloc&)
2301 {
2302 return error(GL_OUT_OF_MEMORY);
2303 }
2304}
2305
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002306void __stdcall glFinishFenceNV(GLuint fence)
2307{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002308 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002309
2310 try
2311 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002312 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002313
2314 if (context)
2315 {
2316 gl::Fence* fenceObject = context->getFence(fence);
2317
2318 if (fenceObject == NULL)
2319 {
2320 return error(GL_INVALID_OPERATION);
2321 }
2322
2323 fenceObject->finishFence();
2324 }
2325 }
2326 catch(std::bad_alloc&)
2327 {
2328 return error(GL_OUT_OF_MEMORY);
2329 }
2330}
2331
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002332void __stdcall glFinish(void)
2333{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002334 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002335
2336 try
2337 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002338 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002339
2340 if (context)
2341 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002342 context->sync(true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002343 }
2344 }
2345 catch(std::bad_alloc&)
2346 {
2347 return error(GL_OUT_OF_MEMORY);
2348 }
2349}
2350
2351void __stdcall glFlush(void)
2352{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002353 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002354
2355 try
2356 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002357 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002358
2359 if (context)
2360 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002361 context->sync(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002362 }
2363 }
2364 catch(std::bad_alloc&)
2365 {
2366 return error(GL_OUT_OF_MEMORY);
2367 }
2368}
2369
2370void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2371{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002372 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002373 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002374
2375 try
2376 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002377 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002378 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002379 {
2380 return error(GL_INVALID_ENUM);
2381 }
2382
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002383 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002384
2385 if (context)
2386 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002387 gl::Framebuffer *framebuffer = NULL;
2388 GLuint framebufferHandle = 0;
2389 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2390 {
2391 framebuffer = context->getReadFramebuffer();
2392 framebufferHandle = context->getReadFramebufferHandle();
2393 }
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002394 else
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002395 {
2396 framebuffer = context->getDrawFramebuffer();
2397 framebufferHandle = context->getDrawFramebufferHandle();
2398 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002399
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002400 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002401 {
2402 return error(GL_INVALID_OPERATION);
2403 }
2404
2405 switch (attachment)
2406 {
2407 case GL_COLOR_ATTACHMENT0:
2408 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2409 break;
2410 case GL_DEPTH_ATTACHMENT:
2411 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2412 break;
2413 case GL_STENCIL_ATTACHMENT:
2414 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2415 break;
2416 default:
2417 return error(GL_INVALID_ENUM);
2418 }
2419 }
2420 }
2421 catch(std::bad_alloc&)
2422 {
2423 return error(GL_OUT_OF_MEMORY);
2424 }
2425}
2426
2427void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2428{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002429 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002430 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002431
2432 try
2433 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002434 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002435 {
2436 return error(GL_INVALID_ENUM);
2437 }
2438
2439 switch (attachment)
2440 {
2441 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002442 case GL_DEPTH_ATTACHMENT:
2443 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002444 break;
2445 default:
2446 return error(GL_INVALID_ENUM);
2447 }
2448
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002449 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002450
2451 if (context)
2452 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002453 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002454 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002455 textarget = GL_NONE;
2456 }
2457 else
2458 {
2459 gl::Texture *tex = context->getTexture(texture);
2460
2461 if (tex == NULL)
2462 {
2463 return error(GL_INVALID_OPERATION);
2464 }
2465
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002466 switch (textarget)
2467 {
2468 case GL_TEXTURE_2D:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002469 {
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002470 if (tex->getTarget() != GL_TEXTURE_2D)
2471 {
2472 return error(GL_INVALID_OPERATION);
2473 }
2474 gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
daniel@transgaming.com92f49922012-05-09 15:49:19 +00002475 if (tex2d->isCompressed(0))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002476 {
2477 return error(GL_INVALID_OPERATION);
2478 }
2479 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002480 }
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002481
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002482 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002483 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002484 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002485 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002486 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002487 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002488 {
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002489 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2490 {
2491 return error(GL_INVALID_OPERATION);
2492 }
2493 gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00002494 if (texcube->isCompressed(textarget, level))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002495 {
2496 return error(GL_INVALID_OPERATION);
2497 }
2498 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002499 }
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002500
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002501 default:
2502 return error(GL_INVALID_ENUM);
2503 }
2504
2505 if (level != 0)
2506 {
2507 return error(GL_INVALID_VALUE);
2508 }
2509 }
2510
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002511 gl::Framebuffer *framebuffer = NULL;
2512 GLuint framebufferHandle = 0;
2513 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2514 {
2515 framebuffer = context->getReadFramebuffer();
2516 framebufferHandle = context->getReadFramebufferHandle();
2517 }
2518 else
2519 {
2520 framebuffer = context->getDrawFramebuffer();
2521 framebufferHandle = context->getDrawFramebufferHandle();
2522 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002523
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002524 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002525 {
2526 return error(GL_INVALID_OPERATION);
2527 }
2528
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002529 switch (attachment)
2530 {
2531 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2532 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2533 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2534 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002535 }
2536 }
2537 catch(std::bad_alloc&)
2538 {
2539 return error(GL_OUT_OF_MEMORY);
2540 }
2541}
2542
2543void __stdcall glFrontFace(GLenum mode)
2544{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002545 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002546
2547 try
2548 {
2549 switch (mode)
2550 {
2551 case GL_CW:
2552 case GL_CCW:
2553 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002554 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002555
2556 if (context)
2557 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002558 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002559 }
2560 }
2561 break;
2562 default:
2563 return error(GL_INVALID_ENUM);
2564 }
2565 }
2566 catch(std::bad_alloc&)
2567 {
2568 return error(GL_OUT_OF_MEMORY);
2569 }
2570}
2571
2572void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2573{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002574 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002575
2576 try
2577 {
2578 if (n < 0)
2579 {
2580 return error(GL_INVALID_VALUE);
2581 }
2582
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002583 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002584
2585 if (context)
2586 {
2587 for (int i = 0; i < n; i++)
2588 {
2589 buffers[i] = context->createBuffer();
2590 }
2591 }
2592 }
2593 catch(std::bad_alloc&)
2594 {
2595 return error(GL_OUT_OF_MEMORY);
2596 }
2597}
2598
2599void __stdcall glGenerateMipmap(GLenum target)
2600{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002601 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002602
2603 try
2604 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002605 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002606
2607 if (context)
2608 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002609 switch (target)
2610 {
2611 case GL_TEXTURE_2D:
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002612 {
2613 gl::Texture2D *tex2d = context->getTexture2D();
2614
daniel@transgaming.com92f49922012-05-09 15:49:19 +00002615 if (tex2d->isCompressed(0))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002616 {
2617 return error(GL_INVALID_OPERATION);
2618 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00002619 if (tex2d->isDepth(0))
2620 {
2621 return error(GL_INVALID_OPERATION);
2622 }
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002623
2624 tex2d->generateMipmaps();
2625 break;
2626 }
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002627
2628 case GL_TEXTURE_CUBE_MAP:
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002629 {
2630 gl::TextureCubeMap *texcube = context->getTextureCubeMap();
2631
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00002632 if (texcube->isCompressed(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002633 {
2634 return error(GL_INVALID_OPERATION);
2635 }
2636
2637 texcube->generateMipmaps();
2638 break;
2639 }
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002640
2641 default:
2642 return error(GL_INVALID_ENUM);
2643 }
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002644 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002645 }
2646 catch(std::bad_alloc&)
2647 {
2648 return error(GL_OUT_OF_MEMORY);
2649 }
2650}
2651
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002652void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2653{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002654 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002655
2656 try
2657 {
2658 if (n < 0)
2659 {
2660 return error(GL_INVALID_VALUE);
2661 }
2662
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002663 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002664
2665 if (context)
2666 {
2667 for (int i = 0; i < n; i++)
2668 {
2669 fences[i] = context->createFence();
2670 }
2671 }
2672 }
2673 catch(std::bad_alloc&)
2674 {
2675 return error(GL_OUT_OF_MEMORY);
2676 }
2677}
2678
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002679void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2680{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002681 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002682
2683 try
2684 {
2685 if (n < 0)
2686 {
2687 return error(GL_INVALID_VALUE);
2688 }
2689
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002690 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002691
2692 if (context)
2693 {
2694 for (int i = 0; i < n; i++)
2695 {
2696 framebuffers[i] = context->createFramebuffer();
2697 }
2698 }
2699 }
2700 catch(std::bad_alloc&)
2701 {
2702 return error(GL_OUT_OF_MEMORY);
2703 }
2704}
2705
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00002706void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
2707{
2708 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
2709
2710 try
2711 {
2712 if (n < 0)
2713 {
2714 return error(GL_INVALID_VALUE);
2715 }
2716
2717 gl::Context *context = gl::getNonLostContext();
2718
2719 if (context)
2720 {
2721 for (int i = 0; i < n; i++)
2722 {
2723 ids[i] = context->createQuery();
2724 }
2725 }
2726 }
2727 catch(std::bad_alloc&)
2728 {
2729 return error(GL_OUT_OF_MEMORY);
2730 }
2731}
2732
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002733void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2734{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002735 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002736
2737 try
2738 {
2739 if (n < 0)
2740 {
2741 return error(GL_INVALID_VALUE);
2742 }
2743
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002744 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002745
2746 if (context)
2747 {
2748 for (int i = 0; i < n; i++)
2749 {
2750 renderbuffers[i] = context->createRenderbuffer();
2751 }
2752 }
2753 }
2754 catch(std::bad_alloc&)
2755 {
2756 return error(GL_OUT_OF_MEMORY);
2757 }
2758}
2759
2760void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2761{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002762 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002763
2764 try
2765 {
2766 if (n < 0)
2767 {
2768 return error(GL_INVALID_VALUE);
2769 }
2770
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002771 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002772
2773 if (context)
2774 {
2775 for (int i = 0; i < n; i++)
2776 {
2777 textures[i] = context->createTexture();
2778 }
2779 }
2780 }
2781 catch(std::bad_alloc&)
2782 {
2783 return error(GL_OUT_OF_MEMORY);
2784 }
2785}
2786
daniel@transgaming.com85423182010-04-22 13:35:27 +00002787void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002788{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002789 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002790 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002791 program, index, bufsize, length, size, type, name);
2792
2793 try
2794 {
2795 if (bufsize < 0)
2796 {
2797 return error(GL_INVALID_VALUE);
2798 }
2799
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002800 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com85423182010-04-22 13:35:27 +00002801
2802 if (context)
2803 {
2804 gl::Program *programObject = context->getProgram(program);
2805
2806 if (!programObject)
2807 {
2808 if (context->getShader(program))
2809 {
2810 return error(GL_INVALID_OPERATION);
2811 }
2812 else
2813 {
2814 return error(GL_INVALID_VALUE);
2815 }
2816 }
2817
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002818 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002819 {
2820 return error(GL_INVALID_VALUE);
2821 }
2822
2823 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2824 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002825 }
2826 catch(std::bad_alloc&)
2827 {
2828 return error(GL_OUT_OF_MEMORY);
2829 }
2830}
2831
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002832void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002833{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002834 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002835 "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 +00002836 program, index, bufsize, length, size, type, name);
2837
2838 try
2839 {
2840 if (bufsize < 0)
2841 {
2842 return error(GL_INVALID_VALUE);
2843 }
2844
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002845 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002846
2847 if (context)
2848 {
2849 gl::Program *programObject = context->getProgram(program);
2850
2851 if (!programObject)
2852 {
2853 if (context->getShader(program))
2854 {
2855 return error(GL_INVALID_OPERATION);
2856 }
2857 else
2858 {
2859 return error(GL_INVALID_VALUE);
2860 }
2861 }
2862
2863 if (index >= (GLuint)programObject->getActiveUniformCount())
2864 {
2865 return error(GL_INVALID_VALUE);
2866 }
2867
2868 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2869 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002870 }
2871 catch(std::bad_alloc&)
2872 {
2873 return error(GL_OUT_OF_MEMORY);
2874 }
2875}
2876
2877void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2878{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002879 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 +00002880 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002881
2882 try
2883 {
2884 if (maxcount < 0)
2885 {
2886 return error(GL_INVALID_VALUE);
2887 }
2888
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002889 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002890
2891 if (context)
2892 {
2893 gl::Program *programObject = context->getProgram(program);
2894
2895 if (!programObject)
2896 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002897 if (context->getShader(program))
2898 {
2899 return error(GL_INVALID_OPERATION);
2900 }
2901 else
2902 {
2903 return error(GL_INVALID_VALUE);
2904 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002905 }
2906
2907 return programObject->getAttachedShaders(maxcount, count, shaders);
2908 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002909 }
2910 catch(std::bad_alloc&)
2911 {
2912 return error(GL_OUT_OF_MEMORY);
2913 }
2914}
2915
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002916int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002917{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002918 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002919
2920 try
2921 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002922 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002923
2924 if (context)
2925 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002926
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002927 gl::Program *programObject = context->getProgram(program);
2928
2929 if (!programObject)
2930 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002931 if (context->getShader(program))
2932 {
2933 return error(GL_INVALID_OPERATION, -1);
2934 }
2935 else
2936 {
2937 return error(GL_INVALID_VALUE, -1);
2938 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002939 }
2940
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00002941 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
2942 if (!programBinary)
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002943 {
2944 return error(GL_INVALID_OPERATION, -1);
2945 }
2946
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00002947 return programBinary->getAttributeLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002948 }
2949 }
2950 catch(std::bad_alloc&)
2951 {
2952 return error(GL_OUT_OF_MEMORY, -1);
2953 }
2954
2955 return -1;
2956}
2957
2958void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2959{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002960 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002961
2962 try
2963 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002964 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002965
2966 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002967 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002968 if (!(context->getBooleanv(pname, params)))
2969 {
2970 GLenum nativeType;
2971 unsigned int numParams = 0;
2972 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2973 return error(GL_INVALID_ENUM);
2974
2975 if (numParams == 0)
2976 return; // it is known that the pname is valid, but there are no parameters to return
2977
2978 if (nativeType == GL_FLOAT)
2979 {
2980 GLfloat *floatParams = NULL;
2981 floatParams = new GLfloat[numParams];
2982
2983 context->getFloatv(pname, floatParams);
2984
2985 for (unsigned int i = 0; i < numParams; ++i)
2986 {
2987 if (floatParams[i] == 0.0f)
2988 params[i] = GL_FALSE;
2989 else
2990 params[i] = GL_TRUE;
2991 }
2992
2993 delete [] floatParams;
2994 }
2995 else if (nativeType == GL_INT)
2996 {
2997 GLint *intParams = NULL;
2998 intParams = new GLint[numParams];
2999
3000 context->getIntegerv(pname, intParams);
3001
3002 for (unsigned int i = 0; i < numParams; ++i)
3003 {
3004 if (intParams[i] == 0)
3005 params[i] = GL_FALSE;
3006 else
3007 params[i] = GL_TRUE;
3008 }
3009
3010 delete [] intParams;
3011 }
3012 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003013 }
3014 }
3015 catch(std::bad_alloc&)
3016 {
3017 return error(GL_OUT_OF_MEMORY);
3018 }
3019}
3020
3021void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
3022{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003023 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 +00003024
3025 try
3026 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003027 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00003028
3029 if (context)
3030 {
3031 gl::Buffer *buffer;
3032
3033 switch (target)
3034 {
3035 case GL_ARRAY_BUFFER:
3036 buffer = context->getArrayBuffer();
3037 break;
3038 case GL_ELEMENT_ARRAY_BUFFER:
3039 buffer = context->getElementArrayBuffer();
3040 break;
3041 default: return error(GL_INVALID_ENUM);
3042 }
3043
3044 if (!buffer)
3045 {
3046 // A null buffer means that "0" is bound to the requested buffer target
3047 return error(GL_INVALID_OPERATION);
3048 }
3049
3050 switch (pname)
3051 {
3052 case GL_BUFFER_USAGE:
3053 *params = buffer->usage();
3054 break;
3055 case GL_BUFFER_SIZE:
3056 *params = buffer->size();
3057 break;
3058 default: return error(GL_INVALID_ENUM);
3059 }
3060 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003061 }
3062 catch(std::bad_alloc&)
3063 {
3064 return error(GL_OUT_OF_MEMORY);
3065 }
3066}
3067
3068GLenum __stdcall glGetError(void)
3069{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003070 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003071
3072 gl::Context *context = gl::getContext();
3073
3074 if (context)
3075 {
daniel@transgaming.com82b28912011-12-12 21:01:35 +00003076 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003077 }
3078
3079 return GL_NO_ERROR;
3080}
3081
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003082void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
3083{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003084 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003085
3086 try
3087 {
3088
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003089 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003090
3091 if (context)
3092 {
3093 gl::Fence *fenceObject = context->getFence(fence);
3094
3095 if (fenceObject == NULL)
3096 {
3097 return error(GL_INVALID_OPERATION);
3098 }
3099
3100 fenceObject->getFenceiv(pname, params);
3101 }
3102 }
3103 catch(std::bad_alloc&)
3104 {
3105 return error(GL_OUT_OF_MEMORY);
3106 }
3107}
3108
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003109void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
3110{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003111 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003112
3113 try
3114 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003115 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003116
3117 if (context)
3118 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003119 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003120 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003121 GLenum nativeType;
3122 unsigned int numParams = 0;
3123 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3124 return error(GL_INVALID_ENUM);
3125
3126 if (numParams == 0)
3127 return; // it is known that the pname is valid, but that there are no parameters to return.
3128
3129 if (nativeType == GL_BOOL)
3130 {
3131 GLboolean *boolParams = NULL;
3132 boolParams = new GLboolean[numParams];
3133
3134 context->getBooleanv(pname, boolParams);
3135
3136 for (unsigned int i = 0; i < numParams; ++i)
3137 {
3138 if (boolParams[i] == GL_FALSE)
3139 params[i] = 0.0f;
3140 else
3141 params[i] = 1.0f;
3142 }
3143
3144 delete [] boolParams;
3145 }
3146 else if (nativeType == GL_INT)
3147 {
3148 GLint *intParams = NULL;
3149 intParams = new GLint[numParams];
3150
3151 context->getIntegerv(pname, intParams);
3152
3153 for (unsigned int i = 0; i < numParams; ++i)
3154 {
3155 params[i] = (GLfloat)intParams[i];
3156 }
3157
3158 delete [] intParams;
3159 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003160 }
3161 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003162 }
3163 catch(std::bad_alloc&)
3164 {
3165 return error(GL_OUT_OF_MEMORY);
3166 }
3167}
3168
3169void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
3170{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003171 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 +00003172 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003173
3174 try
3175 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003176 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003177
3178 if (context)
3179 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003180 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003181 {
3182 return error(GL_INVALID_ENUM);
3183 }
3184
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003185 gl::Framebuffer *framebuffer = NULL;
3186 if (target == GL_READ_FRAMEBUFFER_ANGLE)
3187 {
3188 if(context->getReadFramebufferHandle() == 0)
3189 {
3190 return error(GL_INVALID_OPERATION);
3191 }
3192
3193 framebuffer = context->getReadFramebuffer();
3194 }
3195 else
3196 {
3197 if (context->getDrawFramebufferHandle() == 0)
3198 {
3199 return error(GL_INVALID_OPERATION);
3200 }
3201
3202 framebuffer = context->getDrawFramebuffer();
3203 }
3204
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003205 GLenum attachmentType;
3206 GLuint attachmentHandle;
3207 switch (attachment)
3208 {
3209 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003210 attachmentType = framebuffer->getColorbufferType();
3211 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003212 break;
3213 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003214 attachmentType = framebuffer->getDepthbufferType();
3215 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003216 break;
3217 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003218 attachmentType = framebuffer->getStencilbufferType();
3219 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003220 break;
3221 default: return error(GL_INVALID_ENUM);
3222 }
3223
3224 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00003225 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003226 {
3227 attachmentObjectType = attachmentType;
3228 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +00003229 else if (gl::IsInternalTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003230 {
3231 attachmentObjectType = GL_TEXTURE;
3232 }
apatrick@chromium.orga1d80592012-01-25 21:52:10 +00003233 else
3234 {
3235 UNREACHABLE();
3236 return;
3237 }
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003238
3239 switch (pname)
3240 {
3241 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3242 *params = attachmentObjectType;
3243 break;
3244 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3245 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
3246 {
3247 *params = attachmentHandle;
3248 }
3249 else
3250 {
3251 return error(GL_INVALID_ENUM);
3252 }
3253 break;
3254 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3255 if (attachmentObjectType == GL_TEXTURE)
3256 {
3257 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
3258 }
3259 else
3260 {
3261 return error(GL_INVALID_ENUM);
3262 }
3263 break;
3264 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3265 if (attachmentObjectType == GL_TEXTURE)
3266 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00003267 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003268 {
3269 *params = attachmentType;
3270 }
3271 else
3272 {
3273 *params = 0;
3274 }
3275 }
3276 else
3277 {
3278 return error(GL_INVALID_ENUM);
3279 }
3280 break;
3281 default:
3282 return error(GL_INVALID_ENUM);
3283 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003284 }
3285 }
3286 catch(std::bad_alloc&)
3287 {
3288 return error(GL_OUT_OF_MEMORY);
3289 }
3290}
3291
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00003292GLenum __stdcall glGetGraphicsResetStatusEXT(void)
3293{
3294 EVENT("()");
3295
3296 try
3297 {
3298 gl::Context *context = gl::getContext();
3299
3300 if (context)
3301 {
3302 return context->getResetStatus();
3303 }
3304
3305 return GL_NO_ERROR;
3306 }
3307 catch(std::bad_alloc&)
3308 {
3309 return GL_OUT_OF_MEMORY;
3310 }
3311}
3312
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003313void __stdcall glGetIntegerv(GLenum pname, GLint* params)
3314{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003315 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003316
3317 try
3318 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003319 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003320
3321 if (context)
3322 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003323 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003324 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003325 GLenum nativeType;
3326 unsigned int numParams = 0;
3327 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3328 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003329
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003330 if (numParams == 0)
3331 return; // it is known that pname is valid, but there are no parameters to return
3332
3333 if (nativeType == GL_BOOL)
3334 {
3335 GLboolean *boolParams = NULL;
3336 boolParams = new GLboolean[numParams];
3337
3338 context->getBooleanv(pname, boolParams);
3339
3340 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003341 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003342 if (boolParams[i] == GL_FALSE)
3343 params[i] = 0;
3344 else
3345 params[i] = 1;
3346 }
3347
3348 delete [] boolParams;
3349 }
3350 else if (nativeType == GL_FLOAT)
3351 {
3352 GLfloat *floatParams = NULL;
3353 floatParams = new GLfloat[numParams];
3354
3355 context->getFloatv(pname, floatParams);
3356
3357 for (unsigned int i = 0; i < numParams; ++i)
3358 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00003359 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 +00003360 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003361 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003362 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003363 else
3364 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 +00003365 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003366
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003367 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003368 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003369 }
3370 }
3371 }
3372 catch(std::bad_alloc&)
3373 {
3374 return error(GL_OUT_OF_MEMORY);
3375 }
3376}
3377
3378void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3379{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003380 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003381
3382 try
3383 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003384 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003385
3386 if (context)
3387 {
3388 gl::Program *programObject = context->getProgram(program);
3389
3390 if (!programObject)
3391 {
3392 return error(GL_INVALID_VALUE);
3393 }
3394
3395 switch (pname)
3396 {
3397 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003398 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003399 return;
3400 case GL_LINK_STATUS:
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003401 *params = programObject->getProgramBinary() != NULL;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003402 return;
3403 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003404 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003405 return;
3406 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003407 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003408 return;
3409 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003410 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003411 return;
3412 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003413 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003414 return;
3415 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003416 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003417 return;
3418 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003419 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003420 return;
3421 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003422 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003423 return;
3424 default:
3425 return error(GL_INVALID_ENUM);
3426 }
3427 }
3428 }
3429 catch(std::bad_alloc&)
3430 {
3431 return error(GL_OUT_OF_MEMORY);
3432 }
3433}
3434
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003435void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003436{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003437 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 +00003438 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003439
3440 try
3441 {
3442 if (bufsize < 0)
3443 {
3444 return error(GL_INVALID_VALUE);
3445 }
3446
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003447 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003448
3449 if (context)
3450 {
3451 gl::Program *programObject = context->getProgram(program);
3452
3453 if (!programObject)
3454 {
3455 return error(GL_INVALID_VALUE);
3456 }
3457
3458 programObject->getInfoLog(bufsize, length, infolog);
3459 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003460 }
3461 catch(std::bad_alloc&)
3462 {
3463 return error(GL_OUT_OF_MEMORY);
3464 }
3465}
3466
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003467void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3468{
3469 EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
3470
3471 try
3472 {
3473 switch (pname)
3474 {
3475 case GL_CURRENT_QUERY_EXT:
3476 break;
3477 default:
3478 return error(GL_INVALID_ENUM);
3479 }
3480
3481 gl::Context *context = gl::getNonLostContext();
3482
3483 if (context)
3484 {
3485 params[0] = context->getActiveQuery(target);
3486 }
3487 }
3488 catch(std::bad_alloc&)
3489 {
3490 return error(GL_OUT_OF_MEMORY);
3491 }
3492}
3493
3494void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
3495{
3496 EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
3497
3498 try
3499 {
3500 switch (pname)
3501 {
3502 case GL_QUERY_RESULT_EXT:
3503 case GL_QUERY_RESULT_AVAILABLE_EXT:
3504 break;
3505 default:
3506 return error(GL_INVALID_ENUM);
3507 }
3508 gl::Context *context = gl::getNonLostContext();
3509
3510 if (context)
3511 {
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003512 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
3513
3514 if (!queryObject)
3515 {
3516 return error(GL_INVALID_OPERATION);
3517 }
3518
3519 if (context->getActiveQuery(queryObject->getType()) == id)
3520 {
3521 return error(GL_INVALID_OPERATION);
3522 }
3523
3524 switch(pname)
3525 {
3526 case GL_QUERY_RESULT_EXT:
3527 params[0] = queryObject->getResult();
3528 break;
3529 case GL_QUERY_RESULT_AVAILABLE_EXT:
3530 params[0] = queryObject->isResultAvailable();
3531 break;
3532 default:
3533 ASSERT(false);
3534 }
3535 }
3536 }
3537 catch(std::bad_alloc&)
3538 {
3539 return error(GL_OUT_OF_MEMORY);
3540 }
3541}
3542
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003543void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3544{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003545 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 +00003546
3547 try
3548 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003549 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003550
3551 if (context)
3552 {
3553 if (target != GL_RENDERBUFFER)
3554 {
3555 return error(GL_INVALID_ENUM);
3556 }
3557
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003558 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003559 {
3560 return error(GL_INVALID_OPERATION);
3561 }
3562
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003563 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003564
3565 switch (pname)
3566 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003567 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3568 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3569 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3570 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3571 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3572 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3573 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3574 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3575 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003576 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003577 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003578 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003579 *params = renderbuffer->getSamples();
3580 }
3581 else
3582 {
3583 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003584 }
3585 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003586 default:
3587 return error(GL_INVALID_ENUM);
3588 }
3589 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003590 }
3591 catch(std::bad_alloc&)
3592 {
3593 return error(GL_OUT_OF_MEMORY);
3594 }
3595}
3596
3597void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3598{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003599 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003600
3601 try
3602 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003603 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003604
3605 if (context)
3606 {
3607 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003608
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003609 if (!shaderObject)
3610 {
3611 return error(GL_INVALID_VALUE);
3612 }
3613
3614 switch (pname)
3615 {
3616 case GL_SHADER_TYPE:
3617 *params = shaderObject->getType();
3618 return;
3619 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003620 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003621 return;
3622 case GL_COMPILE_STATUS:
3623 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3624 return;
3625 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003626 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003627 return;
3628 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003629 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003630 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003631 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3632 *params = shaderObject->getTranslatedSourceLength();
3633 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003634 default:
3635 return error(GL_INVALID_ENUM);
3636 }
3637 }
3638 }
3639 catch(std::bad_alloc&)
3640 {
3641 return error(GL_OUT_OF_MEMORY);
3642 }
3643}
3644
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003645void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003646{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003647 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 +00003648 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003649
3650 try
3651 {
3652 if (bufsize < 0)
3653 {
3654 return error(GL_INVALID_VALUE);
3655 }
3656
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003657 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003658
3659 if (context)
3660 {
3661 gl::Shader *shaderObject = context->getShader(shader);
3662
3663 if (!shaderObject)
3664 {
3665 return error(GL_INVALID_VALUE);
3666 }
3667
3668 shaderObject->getInfoLog(bufsize, length, infolog);
3669 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003670 }
3671 catch(std::bad_alloc&)
3672 {
3673 return error(GL_OUT_OF_MEMORY);
3674 }
3675}
3676
3677void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3678{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003679 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 +00003680 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003681
3682 try
3683 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003684 switch (shadertype)
3685 {
3686 case GL_VERTEX_SHADER:
3687 case GL_FRAGMENT_SHADER:
3688 break;
3689 default:
3690 return error(GL_INVALID_ENUM);
3691 }
3692
3693 switch (precisiontype)
3694 {
3695 case GL_LOW_FLOAT:
3696 case GL_MEDIUM_FLOAT:
3697 case GL_HIGH_FLOAT:
3698 // Assume IEEE 754 precision
3699 range[0] = 127;
3700 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003701 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003702 break;
3703 case GL_LOW_INT:
3704 case GL_MEDIUM_INT:
3705 case GL_HIGH_INT:
3706 // Some (most) hardware only supports single-precision floating-point numbers,
3707 // which can accurately represent integers up to +/-16777216
3708 range[0] = 24;
3709 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003710 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003711 break;
3712 default:
3713 return error(GL_INVALID_ENUM);
3714 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003715 }
3716 catch(std::bad_alloc&)
3717 {
3718 return error(GL_OUT_OF_MEMORY);
3719 }
3720}
3721
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003722void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003723{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003724 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 +00003725 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003726
3727 try
3728 {
3729 if (bufsize < 0)
3730 {
3731 return error(GL_INVALID_VALUE);
3732 }
3733
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003734 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003735
3736 if (context)
3737 {
3738 gl::Shader *shaderObject = context->getShader(shader);
3739
3740 if (!shaderObject)
3741 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003742 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003743 }
3744
3745 shaderObject->getSource(bufsize, length, source);
3746 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003747 }
3748 catch(std::bad_alloc&)
3749 {
3750 return error(GL_OUT_OF_MEMORY);
3751 }
3752}
3753
zmo@google.coma574f782011-10-03 21:45:23 +00003754void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3755{
3756 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3757 shader, bufsize, length, source);
3758
3759 try
3760 {
3761 if (bufsize < 0)
3762 {
3763 return error(GL_INVALID_VALUE);
3764 }
3765
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003766 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003767
3768 if (context)
3769 {
3770 gl::Shader *shaderObject = context->getShader(shader);
3771
3772 if (!shaderObject)
3773 {
3774 return error(GL_INVALID_OPERATION);
3775 }
3776
3777 shaderObject->getTranslatedSource(bufsize, length, source);
3778 }
3779 }
3780 catch(std::bad_alloc&)
3781 {
3782 return error(GL_OUT_OF_MEMORY);
3783 }
3784}
3785
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003786const GLubyte* __stdcall glGetString(GLenum name)
3787{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003788 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003789
3790 try
3791 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003792 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003793
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003794 switch (name)
3795 {
3796 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003797 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003798 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003799 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003800 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003801 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003802 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003803 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003804 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003805 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003806 default:
3807 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3808 }
3809 }
3810 catch(std::bad_alloc&)
3811 {
3812 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3813 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003814}
3815
3816void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3817{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003818 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 +00003819
3820 try
3821 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003822 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003823
3824 if (context)
3825 {
3826 gl::Texture *texture;
3827
3828 switch (target)
3829 {
3830 case GL_TEXTURE_2D:
3831 texture = context->getTexture2D();
3832 break;
3833 case GL_TEXTURE_CUBE_MAP:
3834 texture = context->getTextureCubeMap();
3835 break;
3836 default:
3837 return error(GL_INVALID_ENUM);
3838 }
3839
3840 switch (pname)
3841 {
3842 case GL_TEXTURE_MAG_FILTER:
3843 *params = (GLfloat)texture->getMagFilter();
3844 break;
3845 case GL_TEXTURE_MIN_FILTER:
3846 *params = (GLfloat)texture->getMinFilter();
3847 break;
3848 case GL_TEXTURE_WRAP_S:
3849 *params = (GLfloat)texture->getWrapS();
3850 break;
3851 case GL_TEXTURE_WRAP_T:
3852 *params = (GLfloat)texture->getWrapT();
3853 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003854 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3855 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3856 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003857 case GL_TEXTURE_USAGE_ANGLE:
3858 *params = (GLfloat)texture->getUsage();
3859 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003860 default:
3861 return error(GL_INVALID_ENUM);
3862 }
3863 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003864 }
3865 catch(std::bad_alloc&)
3866 {
3867 return error(GL_OUT_OF_MEMORY);
3868 }
3869}
3870
3871void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3872{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003873 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 +00003874
3875 try
3876 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003877 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003878
3879 if (context)
3880 {
3881 gl::Texture *texture;
3882
3883 switch (target)
3884 {
3885 case GL_TEXTURE_2D:
3886 texture = context->getTexture2D();
3887 break;
3888 case GL_TEXTURE_CUBE_MAP:
3889 texture = context->getTextureCubeMap();
3890 break;
3891 default:
3892 return error(GL_INVALID_ENUM);
3893 }
3894
3895 switch (pname)
3896 {
3897 case GL_TEXTURE_MAG_FILTER:
3898 *params = texture->getMagFilter();
3899 break;
3900 case GL_TEXTURE_MIN_FILTER:
3901 *params = texture->getMinFilter();
3902 break;
3903 case GL_TEXTURE_WRAP_S:
3904 *params = texture->getWrapS();
3905 break;
3906 case GL_TEXTURE_WRAP_T:
3907 *params = texture->getWrapT();
3908 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003909 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3910 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3911 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003912 case GL_TEXTURE_USAGE_ANGLE:
3913 *params = texture->getUsage();
3914 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003915 default:
3916 return error(GL_INVALID_ENUM);
3917 }
3918 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003919 }
3920 catch(std::bad_alloc&)
3921 {
3922 return error(GL_OUT_OF_MEMORY);
3923 }
3924}
3925
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003926void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3927{
3928 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3929 program, location, bufSize, params);
3930
3931 try
3932 {
3933 if (bufSize < 0)
3934 {
3935 return error(GL_INVALID_VALUE);
3936 }
3937
3938 gl::Context *context = gl::getNonLostContext();
3939
3940 if (context)
3941 {
3942 if (program == 0)
3943 {
3944 return error(GL_INVALID_VALUE);
3945 }
3946
3947 gl::Program *programObject = context->getProgram(program);
3948
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003949 if (!programObject)
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003950 {
3951 return error(GL_INVALID_OPERATION);
3952 }
3953
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003954 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
3955 if (!programBinary)
3956 {
3957 return error(GL_INVALID_OPERATION);
3958 }
3959
3960 if (!programBinary->getUniformfv(location, &bufSize, params))
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003961 {
3962 return error(GL_INVALID_OPERATION);
3963 }
3964 }
3965 }
3966 catch(std::bad_alloc&)
3967 {
3968 return error(GL_OUT_OF_MEMORY);
3969 }
3970}
3971
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003972void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3973{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003974 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003975
3976 try
3977 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003978 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003979
3980 if (context)
3981 {
3982 if (program == 0)
3983 {
3984 return error(GL_INVALID_VALUE);
3985 }
3986
3987 gl::Program *programObject = context->getProgram(program);
3988
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003989 if (!programObject)
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003990 {
3991 return error(GL_INVALID_OPERATION);
3992 }
3993
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003994 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
3995 if (!programBinary)
3996 {
3997 return error(GL_INVALID_OPERATION);
3998 }
3999
4000 if (!programBinary->getUniformfv(location, NULL, params))
daniel@transgaming.com9a849122011-11-12 03:18:00 +00004001 {
4002 return error(GL_INVALID_OPERATION);
4003 }
4004 }
4005 }
4006 catch(std::bad_alloc&)
4007 {
4008 return error(GL_OUT_OF_MEMORY);
4009 }
4010}
4011
4012void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
4013{
4014 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
4015 program, location, bufSize, params);
4016
4017 try
4018 {
4019 if (bufSize < 0)
4020 {
4021 return error(GL_INVALID_VALUE);
4022 }
4023
4024 gl::Context *context = gl::getNonLostContext();
4025
4026 if (context)
4027 {
4028 if (program == 0)
4029 {
4030 return error(GL_INVALID_VALUE);
4031 }
4032
4033 gl::Program *programObject = context->getProgram(program);
4034
daniel@transgaming.com9a849122011-11-12 03:18:00 +00004035 if (!programObject)
4036 {
4037 return error(GL_INVALID_OPERATION);
4038 }
4039
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004040 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4041 if (!programBinary)
4042 {
4043 return error(GL_INVALID_OPERATION);
4044 }
4045
4046 if (!programBinary->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004047 {
4048 return error(GL_INVALID_OPERATION);
4049 }
4050 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004051 }
4052 catch(std::bad_alloc&)
4053 {
4054 return error(GL_OUT_OF_MEMORY);
4055 }
4056}
4057
4058void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
4059{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004060 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004061
4062 try
4063 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004064 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004065
4066 if (context)
4067 {
4068 if (program == 0)
4069 {
4070 return error(GL_INVALID_VALUE);
4071 }
4072
4073 gl::Program *programObject = context->getProgram(program);
4074
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004075 if (!programObject)
4076 {
4077 return error(GL_INVALID_OPERATION);
4078 }
4079
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004080 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4081 if (!programBinary)
4082 {
4083 return error(GL_INVALID_OPERATION);
4084 }
4085
4086 if (!programBinary->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004087 {
4088 return error(GL_INVALID_OPERATION);
4089 }
4090 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004091 }
4092 catch(std::bad_alloc&)
4093 {
4094 return error(GL_OUT_OF_MEMORY);
4095 }
4096}
4097
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004098int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004099{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004100 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004101
4102 try
4103 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004104 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004105
4106 if (strstr(name, "gl_") == name)
4107 {
4108 return -1;
4109 }
4110
4111 if (context)
4112 {
4113 gl::Program *programObject = context->getProgram(program);
4114
4115 if (!programObject)
4116 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00004117 if (context->getShader(program))
4118 {
4119 return error(GL_INVALID_OPERATION, -1);
4120 }
4121 else
4122 {
4123 return error(GL_INVALID_VALUE, -1);
4124 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004125 }
4126
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004127 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4128 if (!programBinary)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004129 {
4130 return error(GL_INVALID_OPERATION, -1);
4131 }
4132
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004133 return programBinary->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004134 }
4135 }
4136 catch(std::bad_alloc&)
4137 {
4138 return error(GL_OUT_OF_MEMORY, -1);
4139 }
4140
4141 return -1;
4142}
4143
4144void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
4145{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004146 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004147
4148 try
4149 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004150 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004151
daniel@transgaming.come0078962010-04-15 20:45:08 +00004152 if (context)
4153 {
4154 if (index >= gl::MAX_VERTEX_ATTRIBS)
4155 {
4156 return error(GL_INVALID_VALUE);
4157 }
4158
daniel@transgaming.com83921382011-01-08 05:46:00 +00004159 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004160
daniel@transgaming.come0078962010-04-15 20:45:08 +00004161 switch (pname)
4162 {
4163 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004164 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004165 break;
4166 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004167 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004168 break;
4169 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004170 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004171 break;
4172 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004173 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004174 break;
4175 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004176 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004177 break;
4178 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004179 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004180 break;
4181 case GL_CURRENT_VERTEX_ATTRIB:
4182 for (int i = 0; i < 4; ++i)
4183 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004184 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004185 }
4186 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004187 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4188 *params = (GLfloat)attribState.mDivisor;
4189 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004190 default: return error(GL_INVALID_ENUM);
4191 }
4192 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004193 }
4194 catch(std::bad_alloc&)
4195 {
4196 return error(GL_OUT_OF_MEMORY);
4197 }
4198}
4199
4200void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
4201{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004202 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004203
4204 try
4205 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004206 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004207
daniel@transgaming.come0078962010-04-15 20:45:08 +00004208 if (context)
4209 {
4210 if (index >= gl::MAX_VERTEX_ATTRIBS)
4211 {
4212 return error(GL_INVALID_VALUE);
4213 }
4214
daniel@transgaming.com83921382011-01-08 05:46:00 +00004215 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004216
daniel@transgaming.come0078962010-04-15 20:45:08 +00004217 switch (pname)
4218 {
4219 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004220 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004221 break;
4222 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004223 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004224 break;
4225 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004226 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004227 break;
4228 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004229 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004230 break;
4231 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004232 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004233 break;
4234 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004235 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004236 break;
4237 case GL_CURRENT_VERTEX_ATTRIB:
4238 for (int i = 0; i < 4; ++i)
4239 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004240 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004241 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4242 }
4243 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004244 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4245 *params = (GLint)attribState.mDivisor;
4246 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004247 default: return error(GL_INVALID_ENUM);
4248 }
4249 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004250 }
4251 catch(std::bad_alloc&)
4252 {
4253 return error(GL_OUT_OF_MEMORY);
4254 }
4255}
4256
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004257void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004258{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004259 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004260
4261 try
4262 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004263 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004264
daniel@transgaming.come0078962010-04-15 20:45:08 +00004265 if (context)
4266 {
4267 if (index >= gl::MAX_VERTEX_ATTRIBS)
4268 {
4269 return error(GL_INVALID_VALUE);
4270 }
4271
4272 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4273 {
4274 return error(GL_INVALID_ENUM);
4275 }
4276
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004277 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00004278 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004279 }
4280 catch(std::bad_alloc&)
4281 {
4282 return error(GL_OUT_OF_MEMORY);
4283 }
4284}
4285
4286void __stdcall glHint(GLenum target, GLenum mode)
4287{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004288 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004289
4290 try
4291 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004292 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004293 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004294 case GL_FASTEST:
4295 case GL_NICEST:
4296 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004297 break;
4298 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004299 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004300 }
4301
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004302 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004303 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004304 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004305 case GL_GENERATE_MIPMAP_HINT:
4306 if (context) context->setGenerateMipmapHint(mode);
4307 break;
4308 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4309 if (context) context->setFragmentShaderDerivativeHint(mode);
4310 break;
4311 default:
4312 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004313 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004314 }
4315 catch(std::bad_alloc&)
4316 {
4317 return error(GL_OUT_OF_MEMORY);
4318 }
4319}
4320
4321GLboolean __stdcall glIsBuffer(GLuint buffer)
4322{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004323 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004324
4325 try
4326 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004327 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004328
4329 if (context && buffer)
4330 {
4331 gl::Buffer *bufferObject = context->getBuffer(buffer);
4332
4333 if (bufferObject)
4334 {
4335 return GL_TRUE;
4336 }
4337 }
4338 }
4339 catch(std::bad_alloc&)
4340 {
4341 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4342 }
4343
4344 return GL_FALSE;
4345}
4346
4347GLboolean __stdcall glIsEnabled(GLenum cap)
4348{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004349 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004350
4351 try
4352 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004353 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004354
4355 if (context)
4356 {
4357 switch (cap)
4358 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004359 case GL_CULL_FACE: return context->isCullFaceEnabled();
4360 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4361 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4362 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4363 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4364 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4365 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4366 case GL_BLEND: return context->isBlendEnabled();
4367 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004368 default:
4369 return error(GL_INVALID_ENUM, false);
4370 }
4371 }
4372 }
4373 catch(std::bad_alloc&)
4374 {
4375 return error(GL_OUT_OF_MEMORY, false);
4376 }
4377
4378 return false;
4379}
4380
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004381GLboolean __stdcall glIsFenceNV(GLuint fence)
4382{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004383 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004384
4385 try
4386 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004387 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004388
4389 if (context)
4390 {
4391 gl::Fence *fenceObject = context->getFence(fence);
4392
4393 if (fenceObject == NULL)
4394 {
4395 return GL_FALSE;
4396 }
4397
4398 return fenceObject->isFence();
4399 }
4400 }
4401 catch(std::bad_alloc&)
4402 {
4403 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4404 }
4405
4406 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004407}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004408
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004409GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
4410{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004411 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004412
4413 try
4414 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004415 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004416
4417 if (context && framebuffer)
4418 {
4419 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4420
4421 if (framebufferObject)
4422 {
4423 return GL_TRUE;
4424 }
4425 }
4426 }
4427 catch(std::bad_alloc&)
4428 {
4429 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4430 }
4431
4432 return GL_FALSE;
4433}
4434
4435GLboolean __stdcall glIsProgram(GLuint program)
4436{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004437 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004438
4439 try
4440 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004441 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004442
4443 if (context && program)
4444 {
4445 gl::Program *programObject = context->getProgram(program);
4446
4447 if (programObject)
4448 {
4449 return GL_TRUE;
4450 }
4451 }
4452 }
4453 catch(std::bad_alloc&)
4454 {
4455 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4456 }
4457
4458 return GL_FALSE;
4459}
4460
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00004461GLboolean __stdcall glIsQueryEXT(GLuint id)
4462{
4463 EVENT("(GLuint id = %d)", id);
4464
4465 try
4466 {
4467 if (id == 0)
4468 {
4469 return GL_FALSE;
4470 }
4471
4472 gl::Context *context = gl::getNonLostContext();
4473
4474 if (context)
4475 {
4476 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
4477
4478 if (queryObject)
4479 {
4480 return GL_TRUE;
4481 }
4482 }
4483 }
4484 catch(std::bad_alloc&)
4485 {
4486 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4487 }
4488
4489 return GL_FALSE;
4490}
4491
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004492GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
4493{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004494 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004495
4496 try
4497 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004498 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004499
4500 if (context && renderbuffer)
4501 {
4502 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4503
4504 if (renderbufferObject)
4505 {
4506 return GL_TRUE;
4507 }
4508 }
4509 }
4510 catch(std::bad_alloc&)
4511 {
4512 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4513 }
4514
4515 return GL_FALSE;
4516}
4517
4518GLboolean __stdcall glIsShader(GLuint shader)
4519{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004520 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004521
4522 try
4523 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004524 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004525
4526 if (context && shader)
4527 {
4528 gl::Shader *shaderObject = context->getShader(shader);
4529
4530 if (shaderObject)
4531 {
4532 return GL_TRUE;
4533 }
4534 }
4535 }
4536 catch(std::bad_alloc&)
4537 {
4538 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4539 }
4540
4541 return GL_FALSE;
4542}
4543
4544GLboolean __stdcall glIsTexture(GLuint texture)
4545{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004546 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004547
4548 try
4549 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004550 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004551
4552 if (context && texture)
4553 {
4554 gl::Texture *textureObject = context->getTexture(texture);
4555
4556 if (textureObject)
4557 {
4558 return GL_TRUE;
4559 }
4560 }
4561 }
4562 catch(std::bad_alloc&)
4563 {
4564 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4565 }
4566
4567 return GL_FALSE;
4568}
4569
4570void __stdcall glLineWidth(GLfloat width)
4571{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004572 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004573
4574 try
4575 {
4576 if (width <= 0.0f)
4577 {
4578 return error(GL_INVALID_VALUE);
4579 }
4580
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004581 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004582
4583 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004584 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004585 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004586 }
4587 }
4588 catch(std::bad_alloc&)
4589 {
4590 return error(GL_OUT_OF_MEMORY);
4591 }
4592}
4593
4594void __stdcall glLinkProgram(GLuint program)
4595{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004596 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004597
4598 try
4599 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004600 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004601
4602 if (context)
4603 {
4604 gl::Program *programObject = context->getProgram(program);
4605
4606 if (!programObject)
4607 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004608 if (context->getShader(program))
4609 {
4610 return error(GL_INVALID_OPERATION);
4611 }
4612 else
4613 {
4614 return error(GL_INVALID_VALUE);
4615 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004616 }
4617
4618 programObject->link();
4619 }
4620 }
4621 catch(std::bad_alloc&)
4622 {
4623 return error(GL_OUT_OF_MEMORY);
4624 }
4625}
4626
4627void __stdcall glPixelStorei(GLenum pname, GLint param)
4628{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004629 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004630
4631 try
4632 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004633 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004634
4635 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004636 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004637 switch (pname)
4638 {
4639 case GL_UNPACK_ALIGNMENT:
4640 if (param != 1 && param != 2 && param != 4 && param != 8)
4641 {
4642 return error(GL_INVALID_VALUE);
4643 }
4644
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004645 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004646 break;
4647
4648 case GL_PACK_ALIGNMENT:
4649 if (param != 1 && param != 2 && param != 4 && param != 8)
4650 {
4651 return error(GL_INVALID_VALUE);
4652 }
4653
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004654 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004655 break;
4656
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004657 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4658 context->setPackReverseRowOrder(param != 0);
4659 break;
4660
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004661 default:
4662 return error(GL_INVALID_ENUM);
4663 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004664 }
4665 }
4666 catch(std::bad_alloc&)
4667 {
4668 return error(GL_OUT_OF_MEMORY);
4669 }
4670}
4671
4672void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4673{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004674 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004675
4676 try
4677 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004678 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004679
4680 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004681 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004682 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004683 }
4684 }
4685 catch(std::bad_alloc&)
4686 {
4687 return error(GL_OUT_OF_MEMORY);
4688 }
4689}
4690
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004691void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4692 GLenum format, GLenum type, GLsizei bufSize,
4693 GLvoid *data)
4694{
4695 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4696 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4697 x, y, width, height, format, type, bufSize, data);
4698
4699 try
4700 {
4701 if (width < 0 || height < 0 || bufSize < 0)
4702 {
4703 return error(GL_INVALID_VALUE);
4704 }
4705
4706 if (!validReadFormatType(format, type))
4707 {
4708 return error(GL_INVALID_OPERATION);
4709 }
4710
4711 gl::Context *context = gl::getNonLostContext();
4712
4713 if (context)
4714 {
4715 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4716 }
4717 }
4718 catch(std::bad_alloc&)
4719 {
4720 return error(GL_OUT_OF_MEMORY);
4721 }
4722}
4723
4724void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4725 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004726{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004727 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004728 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004729 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004730
4731 try
4732 {
4733 if (width < 0 || height < 0)
4734 {
4735 return error(GL_INVALID_VALUE);
4736 }
4737
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004738 if (!validReadFormatType(format, type))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004739 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004740 return error(GL_INVALID_OPERATION);
4741 }
4742
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004743 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004744
4745 if (context)
4746 {
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004747 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004748 }
4749 }
4750 catch(std::bad_alloc&)
4751 {
4752 return error(GL_OUT_OF_MEMORY);
4753 }
4754}
4755
4756void __stdcall glReleaseShaderCompiler(void)
4757{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004758 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004759
4760 try
4761 {
4762 gl::Shader::releaseCompiler();
4763 }
4764 catch(std::bad_alloc&)
4765 {
4766 return error(GL_OUT_OF_MEMORY);
4767 }
4768}
4769
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004770void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004771{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004772 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 +00004773 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004774
4775 try
4776 {
4777 switch (target)
4778 {
4779 case GL_RENDERBUFFER:
4780 break;
4781 default:
4782 return error(GL_INVALID_ENUM);
4783 }
4784
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004785 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004786 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004787 return error(GL_INVALID_ENUM);
4788 }
4789
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004790 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004791 {
4792 return error(GL_INVALID_VALUE);
4793 }
4794
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004795 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004796
4797 if (context)
4798 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004799 if (width > context->getMaximumRenderbufferDimension() ||
4800 height > context->getMaximumRenderbufferDimension() ||
4801 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004802 {
4803 return error(GL_INVALID_VALUE);
4804 }
4805
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004806 GLuint handle = context->getRenderbufferHandle();
4807 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004808 {
4809 return error(GL_INVALID_OPERATION);
4810 }
4811
4812 switch (internalformat)
4813 {
4814 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004815 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004816 break;
4817 case GL_RGBA4:
4818 case GL_RGB5_A1:
4819 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004820 case GL_RGB8_OES:
4821 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004822 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004823 break;
4824 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004825 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004826 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004827 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004828 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004829 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004830 default:
4831 return error(GL_INVALID_ENUM);
4832 }
4833 }
4834 }
4835 catch(std::bad_alloc&)
4836 {
4837 return error(GL_OUT_OF_MEMORY);
4838 }
4839}
4840
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004841void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4842{
4843 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4844}
4845
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004846void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4847{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004848 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004849
4850 try
4851 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004852 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004853
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004854 if (context)
4855 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004856 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004857 }
4858 }
4859 catch(std::bad_alloc&)
4860 {
4861 return error(GL_OUT_OF_MEMORY);
4862 }
4863}
4864
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004865void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4866{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004867 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004868
4869 try
4870 {
4871 if (condition != GL_ALL_COMPLETED_NV)
4872 {
4873 return error(GL_INVALID_ENUM);
4874 }
4875
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004876 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004877
4878 if (context)
4879 {
4880 gl::Fence *fenceObject = context->getFence(fence);
4881
4882 if (fenceObject == NULL)
4883 {
4884 return error(GL_INVALID_OPERATION);
4885 }
4886
4887 fenceObject->setFence(condition);
4888 }
4889 }
4890 catch(std::bad_alloc&)
4891 {
4892 return error(GL_OUT_OF_MEMORY);
4893 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004894}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004895
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004896void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4897{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004898 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 +00004899
4900 try
4901 {
4902 if (width < 0 || height < 0)
4903 {
4904 return error(GL_INVALID_VALUE);
4905 }
4906
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004907 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004908
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004909 if (context)
4910 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004911 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004912 }
4913 }
4914 catch(std::bad_alloc&)
4915 {
4916 return error(GL_OUT_OF_MEMORY);
4917 }
4918}
4919
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004920void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004921{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004922 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004923 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004924 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004925
4926 try
4927 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004928 // No binary shader formats are supported.
4929 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004930 }
4931 catch(std::bad_alloc&)
4932 {
4933 return error(GL_OUT_OF_MEMORY);
4934 }
4935}
4936
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004937void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004938{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004939 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 +00004940 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004941
4942 try
4943 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004944 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004945 {
4946 return error(GL_INVALID_VALUE);
4947 }
4948
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004949 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004950
4951 if (context)
4952 {
4953 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004954
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004955 if (!shaderObject)
4956 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004957 if (context->getProgram(shader))
4958 {
4959 return error(GL_INVALID_OPERATION);
4960 }
4961 else
4962 {
4963 return error(GL_INVALID_VALUE);
4964 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004965 }
4966
4967 shaderObject->setSource(count, string, length);
4968 }
4969 }
4970 catch(std::bad_alloc&)
4971 {
4972 return error(GL_OUT_OF_MEMORY);
4973 }
4974}
4975
4976void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4977{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004978 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004979}
4980
4981void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4982{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004983 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 +00004984
4985 try
4986 {
4987 switch (face)
4988 {
4989 case GL_FRONT:
4990 case GL_BACK:
4991 case GL_FRONT_AND_BACK:
4992 break;
4993 default:
4994 return error(GL_INVALID_ENUM);
4995 }
4996
4997 switch (func)
4998 {
4999 case GL_NEVER:
5000 case GL_ALWAYS:
5001 case GL_LESS:
5002 case GL_LEQUAL:
5003 case GL_EQUAL:
5004 case GL_GEQUAL:
5005 case GL_GREATER:
5006 case GL_NOTEQUAL:
5007 break;
5008 default:
5009 return error(GL_INVALID_ENUM);
5010 }
5011
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005012 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005013
5014 if (context)
5015 {
5016 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5017 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005018 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005019 }
5020
5021 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5022 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005023 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005024 }
5025 }
5026 }
5027 catch(std::bad_alloc&)
5028 {
5029 return error(GL_OUT_OF_MEMORY);
5030 }
5031}
5032
5033void __stdcall glStencilMask(GLuint mask)
5034{
5035 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
5036}
5037
5038void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
5039{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005040 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005041
5042 try
5043 {
5044 switch (face)
5045 {
5046 case GL_FRONT:
5047 case GL_BACK:
5048 case GL_FRONT_AND_BACK:
5049 break;
5050 default:
5051 return error(GL_INVALID_ENUM);
5052 }
5053
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005054 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005055
5056 if (context)
5057 {
5058 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5059 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005060 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005061 }
5062
5063 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5064 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005065 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005066 }
5067 }
5068 }
5069 catch(std::bad_alloc&)
5070 {
5071 return error(GL_OUT_OF_MEMORY);
5072 }
5073}
5074
5075void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
5076{
5077 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
5078}
5079
5080void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
5081{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005082 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 +00005083 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005084
5085 try
5086 {
5087 switch (face)
5088 {
5089 case GL_FRONT:
5090 case GL_BACK:
5091 case GL_FRONT_AND_BACK:
5092 break;
5093 default:
5094 return error(GL_INVALID_ENUM);
5095 }
5096
5097 switch (fail)
5098 {
5099 case GL_ZERO:
5100 case GL_KEEP:
5101 case GL_REPLACE:
5102 case GL_INCR:
5103 case GL_DECR:
5104 case GL_INVERT:
5105 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005106 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005107 break;
5108 default:
5109 return error(GL_INVALID_ENUM);
5110 }
5111
5112 switch (zfail)
5113 {
5114 case GL_ZERO:
5115 case GL_KEEP:
5116 case GL_REPLACE:
5117 case GL_INCR:
5118 case GL_DECR:
5119 case GL_INVERT:
5120 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005121 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005122 break;
5123 default:
5124 return error(GL_INVALID_ENUM);
5125 }
5126
5127 switch (zpass)
5128 {
5129 case GL_ZERO:
5130 case GL_KEEP:
5131 case GL_REPLACE:
5132 case GL_INCR:
5133 case GL_DECR:
5134 case GL_INVERT:
5135 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005136 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005137 break;
5138 default:
5139 return error(GL_INVALID_ENUM);
5140 }
5141
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005142 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005143
5144 if (context)
5145 {
5146 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5147 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005148 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005149 }
5150
5151 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5152 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005153 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005154 }
5155 }
5156 }
5157 catch(std::bad_alloc&)
5158 {
5159 return error(GL_OUT_OF_MEMORY);
5160 }
5161}
5162
daniel@transgaming.comfe208882010-09-01 15:47:57 +00005163GLboolean __stdcall glTestFenceNV(GLuint fence)
5164{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005165 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005166
5167 try
5168 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005169 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005170
5171 if (context)
5172 {
5173 gl::Fence *fenceObject = context->getFence(fence);
5174
5175 if (fenceObject == NULL)
5176 {
5177 return error(GL_INVALID_OPERATION, GL_TRUE);
5178 }
5179
5180 return fenceObject->testFence();
5181 }
5182 }
5183 catch(std::bad_alloc&)
5184 {
5185 error(GL_OUT_OF_MEMORY);
5186 }
5187
5188 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00005189}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005190
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005191void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
5192 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005193{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005194 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 +00005195 "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 +00005196 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005197
5198 try
5199 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00005200 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005201 {
5202 return error(GL_INVALID_VALUE);
5203 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005204
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +00005205 if (internalformat != GLint(format))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005206 {
5207 return error(GL_INVALID_OPERATION);
5208 }
5209
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005210 // validate <type> by itself (used as secondary key below)
5211 switch (type)
5212 {
5213 case GL_UNSIGNED_BYTE:
5214 case GL_UNSIGNED_SHORT_5_6_5:
5215 case GL_UNSIGNED_SHORT_4_4_4_4:
5216 case GL_UNSIGNED_SHORT_5_5_5_1:
5217 case GL_UNSIGNED_SHORT:
5218 case GL_UNSIGNED_INT:
5219 case GL_UNSIGNED_INT_24_8_OES:
5220 case GL_HALF_FLOAT_OES:
5221 case GL_FLOAT:
5222 break;
5223 default:
5224 return error(GL_INVALID_ENUM);
5225 }
5226
5227 // validate <format> + <type> combinations
5228 // - invalid <format> -> sets INVALID_ENUM
5229 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005230 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005231 {
5232 case GL_ALPHA:
5233 case GL_LUMINANCE:
5234 case GL_LUMINANCE_ALPHA:
5235 switch (type)
5236 {
5237 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005238 case GL_FLOAT:
5239 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005240 break;
5241 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005242 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005243 }
5244 break;
5245 case GL_RGB:
5246 switch (type)
5247 {
5248 case GL_UNSIGNED_BYTE:
5249 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005250 case GL_FLOAT:
5251 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005252 break;
5253 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005254 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005255 }
5256 break;
5257 case GL_RGBA:
5258 switch (type)
5259 {
5260 case GL_UNSIGNED_BYTE:
5261 case GL_UNSIGNED_SHORT_4_4_4_4:
5262 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005263 case GL_FLOAT:
5264 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005265 break;
5266 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005267 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005268 }
5269 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005270 case GL_BGRA_EXT:
5271 switch (type)
5272 {
5273 case GL_UNSIGNED_BYTE:
5274 break;
5275 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005276 return error(GL_INVALID_OPERATION);
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005277 }
5278 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005279 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
5280 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00005281 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5282 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00005283 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005284 case GL_DEPTH_COMPONENT:
5285 switch (type)
5286 {
5287 case GL_UNSIGNED_SHORT:
5288 case GL_UNSIGNED_INT:
5289 break;
5290 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005291 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005292 }
5293 break;
5294 case GL_DEPTH_STENCIL_OES:
5295 switch (type)
5296 {
5297 case GL_UNSIGNED_INT_24_8_OES:
5298 break;
5299 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005300 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005301 }
5302 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005303 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005304 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005305 }
5306
5307 if (border != 0)
5308 {
5309 return error(GL_INVALID_VALUE);
5310 }
5311
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005312 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005313
5314 if (context)
5315 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00005316 if (level > context->getMaximumTextureLevel())
5317 {
5318 return error(GL_INVALID_VALUE);
5319 }
5320
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005321 switch (target)
5322 {
5323 case GL_TEXTURE_2D:
5324 if (width > (context->getMaximumTextureDimension() >> level) ||
5325 height > (context->getMaximumTextureDimension() >> level))
5326 {
5327 return error(GL_INVALID_VALUE);
5328 }
5329 break;
5330 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5331 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5332 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5333 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5334 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5335 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5336 if (width != height)
5337 {
5338 return error(GL_INVALID_VALUE);
5339 }
5340
5341 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
5342 height > (context->getMaximumCubeTextureDimension() >> level))
5343 {
5344 return error(GL_INVALID_VALUE);
5345 }
5346 break;
5347 default:
5348 return error(GL_INVALID_ENUM);
5349 }
5350
gman@chromium.org50c526d2011-08-10 05:19:44 +00005351 switch (format) {
5352 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5353 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5354 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00005355 {
5356 return error(GL_INVALID_OPERATION);
5357 }
5358 else
5359 {
5360 return error(GL_INVALID_ENUM);
5361 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00005362 break;
5363 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5364 if (context->supportsDXT3Textures())
5365 {
5366 return error(GL_INVALID_OPERATION);
5367 }
5368 else
5369 {
5370 return error(GL_INVALID_ENUM);
5371 }
5372 break;
5373 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5374 if (context->supportsDXT5Textures())
5375 {
5376 return error(GL_INVALID_OPERATION);
5377 }
5378 else
5379 {
5380 return error(GL_INVALID_ENUM);
5381 }
5382 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005383 case GL_DEPTH_COMPONENT:
5384 case GL_DEPTH_STENCIL_OES:
5385 if (!context->supportsDepthTextures())
5386 {
5387 return error(GL_INVALID_VALUE);
5388 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005389 if (target != GL_TEXTURE_2D)
5390 {
5391 return error(GL_INVALID_OPERATION);
5392 }
daniel@transgaming.com797924b2012-06-05 19:50:01 +00005393 // OES_depth_texture supports loading depth data and multiple levels,
5394 // but ANGLE_depth_texture does not
5395 if (pixels != NULL || level != 0)
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005396 {
5397 return error(GL_INVALID_OPERATION);
5398 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005399 break;
gman@chromium.org50c526d2011-08-10 05:19:44 +00005400 default:
5401 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005402 }
5403
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005404 if (type == GL_FLOAT)
5405 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005406 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005407 {
5408 return error(GL_INVALID_ENUM);
5409 }
5410 }
5411 else if (type == GL_HALF_FLOAT_OES)
5412 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005413 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005414 {
5415 return error(GL_INVALID_ENUM);
5416 }
5417 }
5418
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005419 if (target == GL_TEXTURE_2D)
5420 {
5421 gl::Texture2D *texture = context->getTexture2D();
5422
5423 if (!texture)
5424 {
5425 return error(GL_INVALID_OPERATION);
5426 }
5427
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005428 if (texture->isImmutable())
5429 {
5430 return error(GL_INVALID_OPERATION);
5431 }
5432
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005433 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005434 }
5435 else
5436 {
5437 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5438
5439 if (!texture)
5440 {
5441 return error(GL_INVALID_OPERATION);
5442 }
5443
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005444 if (texture->isImmutable())
5445 {
5446 return error(GL_INVALID_OPERATION);
5447 }
5448
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005449 switch (target)
5450 {
5451 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005452 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005453 break;
5454 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005455 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005456 break;
5457 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005458 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005459 break;
5460 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005461 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005462 break;
5463 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005464 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005465 break;
5466 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005467 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005468 break;
5469 default: UNREACHABLE();
5470 }
5471 }
5472 }
5473 }
5474 catch(std::bad_alloc&)
5475 {
5476 return error(GL_OUT_OF_MEMORY);
5477 }
5478}
5479
5480void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5481{
5482 glTexParameteri(target, pname, (GLint)param);
5483}
5484
5485void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5486{
5487 glTexParameteri(target, pname, (GLint)*params);
5488}
5489
5490void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
5491{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005492 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005493
5494 try
5495 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005496 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005497
5498 if (context)
5499 {
5500 gl::Texture *texture;
5501
5502 switch (target)
5503 {
5504 case GL_TEXTURE_2D:
5505 texture = context->getTexture2D();
5506 break;
5507 case GL_TEXTURE_CUBE_MAP:
5508 texture = context->getTextureCubeMap();
5509 break;
5510 default:
5511 return error(GL_INVALID_ENUM);
5512 }
5513
5514 switch (pname)
5515 {
5516 case GL_TEXTURE_WRAP_S:
5517 if (!texture->setWrapS((GLenum)param))
5518 {
5519 return error(GL_INVALID_ENUM);
5520 }
5521 break;
5522 case GL_TEXTURE_WRAP_T:
5523 if (!texture->setWrapT((GLenum)param))
5524 {
5525 return error(GL_INVALID_ENUM);
5526 }
5527 break;
5528 case GL_TEXTURE_MIN_FILTER:
5529 if (!texture->setMinFilter((GLenum)param))
5530 {
5531 return error(GL_INVALID_ENUM);
5532 }
5533 break;
5534 case GL_TEXTURE_MAG_FILTER:
5535 if (!texture->setMagFilter((GLenum)param))
5536 {
5537 return error(GL_INVALID_ENUM);
5538 }
5539 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00005540 case GL_TEXTURE_USAGE_ANGLE:
5541 if (!texture->setUsage((GLenum)param))
5542 {
5543 return error(GL_INVALID_ENUM);
5544 }
5545 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005546 default:
5547 return error(GL_INVALID_ENUM);
5548 }
5549 }
5550 }
5551 catch(std::bad_alloc&)
5552 {
5553 return error(GL_OUT_OF_MEMORY);
5554 }
5555}
5556
5557void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5558{
5559 glTexParameteri(target, pname, *params);
5560}
5561
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005562void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5563{
5564 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5565 target, levels, internalformat, width, height);
5566
5567 try
5568 {
5569 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5570 {
5571 return error(GL_INVALID_ENUM);
5572 }
5573
5574 if (width < 1 || height < 1 || levels < 1)
5575 {
5576 return error(GL_INVALID_VALUE);
5577 }
5578
5579 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5580 {
5581 return error(GL_INVALID_VALUE);
5582 }
5583
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005584 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005585 {
5586 return error(GL_INVALID_OPERATION);
5587 }
5588
5589 GLenum format = gl::ExtractFormat(internalformat);
5590 GLenum type = gl::ExtractType(internalformat);
5591
5592 if (format == GL_NONE || type == GL_NONE)
5593 {
5594 return error(GL_INVALID_ENUM);
5595 }
5596
5597 gl::Context *context = gl::getNonLostContext();
5598
5599 if (context)
5600 {
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005601 switch (target)
5602 {
5603 case GL_TEXTURE_2D:
5604 if (width > context->getMaximumTextureDimension() ||
5605 height > context->getMaximumTextureDimension())
5606 {
5607 return error(GL_INVALID_VALUE);
5608 }
5609 break;
5610 case GL_TEXTURE_CUBE_MAP:
5611 if (width > context->getMaximumCubeTextureDimension() ||
5612 height > context->getMaximumCubeTextureDimension())
5613 {
5614 return error(GL_INVALID_VALUE);
5615 }
5616 break;
5617 default:
5618 return error(GL_INVALID_ENUM);
5619 }
5620
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005621 if (levels != 1 && !context->supportsNonPower2Texture())
5622 {
5623 if (!gl::isPow2(width) || !gl::isPow2(height))
5624 {
5625 return error(GL_INVALID_OPERATION);
5626 }
5627 }
5628
daniel@transgaming.come1077362011-11-11 04:16:50 +00005629 switch (internalformat)
5630 {
5631 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5632 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5633 if (!context->supportsDXT1Textures())
5634 {
5635 return error(GL_INVALID_ENUM);
5636 }
5637 break;
5638 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5639 if (!context->supportsDXT3Textures())
5640 {
5641 return error(GL_INVALID_ENUM);
5642 }
5643 break;
5644 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5645 if (!context->supportsDXT5Textures())
5646 {
5647 return error(GL_INVALID_ENUM);
5648 }
5649 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005650 case GL_RGBA32F_EXT:
5651 case GL_RGB32F_EXT:
5652 case GL_ALPHA32F_EXT:
5653 case GL_LUMINANCE32F_EXT:
5654 case GL_LUMINANCE_ALPHA32F_EXT:
5655 if (!context->supportsFloat32Textures())
5656 {
5657 return error(GL_INVALID_ENUM);
5658 }
5659 break;
5660 case GL_RGBA16F_EXT:
5661 case GL_RGB16F_EXT:
5662 case GL_ALPHA16F_EXT:
5663 case GL_LUMINANCE16F_EXT:
5664 case GL_LUMINANCE_ALPHA16F_EXT:
5665 if (!context->supportsFloat16Textures())
5666 {
5667 return error(GL_INVALID_ENUM);
5668 }
5669 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005670 case GL_DEPTH_COMPONENT16:
5671 case GL_DEPTH_COMPONENT32_OES:
5672 case GL_DEPTH24_STENCIL8_OES:
5673 if (!context->supportsDepthTextures())
5674 {
5675 return error(GL_INVALID_ENUM);
5676 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005677 if (target != GL_TEXTURE_2D)
5678 {
5679 return error(GL_INVALID_OPERATION);
5680 }
daniel@transgaming.com797924b2012-06-05 19:50:01 +00005681 // ANGLE_depth_texture only supports 1-level textures
5682 if (levels != 1)
5683 {
5684 return error(GL_INVALID_OPERATION);
5685 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005686 break;
5687 default:
5688 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005689 }
5690
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005691 if (target == GL_TEXTURE_2D)
5692 {
5693 gl::Texture2D *texture = context->getTexture2D();
5694
5695 if (!texture || texture->id() == 0)
5696 {
5697 return error(GL_INVALID_OPERATION);
5698 }
5699
5700 if (texture->isImmutable())
5701 {
5702 return error(GL_INVALID_OPERATION);
5703 }
5704
5705 texture->storage(levels, internalformat, width, height);
5706 }
5707 else if (target == GL_TEXTURE_CUBE_MAP)
5708 {
5709 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5710
5711 if (!texture || texture->id() == 0)
5712 {
5713 return error(GL_INVALID_OPERATION);
5714 }
5715
5716 if (texture->isImmutable())
5717 {
5718 return error(GL_INVALID_OPERATION);
5719 }
5720
5721 texture->storage(levels, internalformat, width);
5722 }
5723 else UNREACHABLE();
5724 }
5725 }
5726 catch(std::bad_alloc&)
5727 {
5728 return error(GL_OUT_OF_MEMORY);
5729 }
5730}
5731
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005732void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5733 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005734{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005735 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005736 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005737 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005738 target, level, xoffset, yoffset, width, height, format, type, pixels);
5739
5740 try
5741 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00005742 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005743 {
5744 return error(GL_INVALID_ENUM);
5745 }
5746
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005747 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005748 {
5749 return error(GL_INVALID_VALUE);
5750 }
5751
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005752 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5753 {
5754 return error(GL_INVALID_VALUE);
5755 }
5756
daniel@transgaming.com8833dd22012-06-05 19:49:58 +00005757 if (!checkTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005758 {
daniel@transgaming.com8833dd22012-06-05 19:49:58 +00005759 return; // error is set by helper function
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005760 }
5761
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005762 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005763
5764 if (context)
5765 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005766 if (level > context->getMaximumTextureLevel())
5767 {
5768 return error(GL_INVALID_VALUE);
5769 }
5770
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005771 if (format == GL_FLOAT)
5772 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005773 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005774 {
5775 return error(GL_INVALID_ENUM);
5776 }
5777 }
5778 else if (format == GL_HALF_FLOAT_OES)
5779 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005780 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005781 {
5782 return error(GL_INVALID_ENUM);
5783 }
5784 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005785 else if (gl::IsDepthTexture(format))
5786 {
5787 if (!context->supportsDepthTextures())
5788 {
5789 return error(GL_INVALID_ENUM);
5790 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005791 if (target != GL_TEXTURE_2D)
5792 {
5793 return error(GL_INVALID_OPERATION);
5794 }
5795 // OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not
5796 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005797 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005798
daniel@transgaming.com1d2d3c42012-05-31 01:14:15 +00005799 if (width == 0 || height == 0 || pixels == NULL)
5800 {
5801 return;
5802 }
5803
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005804 if (target == GL_TEXTURE_2D)
5805 {
5806 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00005807 if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005808 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005809 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005810 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005811 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005812 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005813 {
5814 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00005815 if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005816 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005817 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005818 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005819 }
5820 else
5821 {
5822 UNREACHABLE();
5823 }
5824 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005825 }
5826 catch(std::bad_alloc&)
5827 {
5828 return error(GL_OUT_OF_MEMORY);
5829 }
5830}
5831
5832void __stdcall glUniform1f(GLint location, GLfloat x)
5833{
5834 glUniform1fv(location, 1, &x);
5835}
5836
5837void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5838{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005839 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005840
5841 try
5842 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005843 if (count < 0)
5844 {
5845 return error(GL_INVALID_VALUE);
5846 }
5847
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005848 if (location == -1)
5849 {
5850 return;
5851 }
5852
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005853 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005854
5855 if (context)
5856 {
5857 gl::Program *program = context->getCurrentProgram();
5858
5859 if (!program)
5860 {
5861 return error(GL_INVALID_OPERATION);
5862 }
5863
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00005864 gl::ProgramBinary *programBinary = program->getProgramBinary();
5865 if (!programBinary)
5866 {
5867 return error(GL_INVALID_OPERATION);
5868 }
5869
5870 if (!programBinary->setUniform1fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005871 {
5872 return error(GL_INVALID_OPERATION);
5873 }
5874 }
5875 }
5876 catch(std::bad_alloc&)
5877 {
5878 return error(GL_OUT_OF_MEMORY);
5879 }
5880}
5881
5882void __stdcall glUniform1i(GLint location, GLint x)
5883{
5884 glUniform1iv(location, 1, &x);
5885}
5886
5887void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5888{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005889 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005890
5891 try
5892 {
5893 if (count < 0)
5894 {
5895 return error(GL_INVALID_VALUE);
5896 }
5897
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005898 if (location == -1)
5899 {
5900 return;
5901 }
5902
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005903 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005904
5905 if (context)
5906 {
5907 gl::Program *program = context->getCurrentProgram();
5908
5909 if (!program)
5910 {
5911 return error(GL_INVALID_OPERATION);
5912 }
5913
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00005914 gl::ProgramBinary *programBinary = program->getProgramBinary();
5915 if (!programBinary)
5916 {
5917 return error(GL_INVALID_OPERATION);
5918 }
5919
5920 if (!programBinary->setUniform1iv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005921 {
5922 return error(GL_INVALID_OPERATION);
5923 }
5924 }
5925 }
5926 catch(std::bad_alloc&)
5927 {
5928 return error(GL_OUT_OF_MEMORY);
5929 }
5930}
5931
5932void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5933{
5934 GLfloat xy[2] = {x, y};
5935
5936 glUniform2fv(location, 1, (GLfloat*)&xy);
5937}
5938
5939void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5940{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005941 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005942
5943 try
5944 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005945 if (count < 0)
5946 {
5947 return error(GL_INVALID_VALUE);
5948 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005949
5950 if (location == -1)
5951 {
5952 return;
5953 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005954
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005955 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005956
5957 if (context)
5958 {
5959 gl::Program *program = context->getCurrentProgram();
5960
5961 if (!program)
5962 {
5963 return error(GL_INVALID_OPERATION);
5964 }
5965
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00005966 gl::ProgramBinary *programBinary = program->getProgramBinary();
5967 if (!programBinary)
5968 {
5969 return error(GL_INVALID_OPERATION);
5970 }
5971
5972 if (!programBinary->setUniform2fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005973 {
5974 return error(GL_INVALID_OPERATION);
5975 }
5976 }
5977 }
5978 catch(std::bad_alloc&)
5979 {
5980 return error(GL_OUT_OF_MEMORY);
5981 }
5982}
5983
5984void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5985{
5986 GLint xy[4] = {x, y};
5987
5988 glUniform2iv(location, 1, (GLint*)&xy);
5989}
5990
5991void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5992{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005993 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005994
5995 try
5996 {
5997 if (count < 0)
5998 {
5999 return error(GL_INVALID_VALUE);
6000 }
6001
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006002 if (location == -1)
6003 {
6004 return;
6005 }
6006
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006007 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006008
6009 if (context)
6010 {
6011 gl::Program *program = context->getCurrentProgram();
6012
6013 if (!program)
6014 {
6015 return error(GL_INVALID_OPERATION);
6016 }
6017
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006018 gl::ProgramBinary *programBinary = program->getProgramBinary();
6019 if (!programBinary)
6020 {
6021 return error(GL_INVALID_OPERATION);
6022 }
6023
6024 if (!programBinary->setUniform2iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006025 {
6026 return error(GL_INVALID_OPERATION);
6027 }
6028 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006029 }
6030 catch(std::bad_alloc&)
6031 {
6032 return error(GL_OUT_OF_MEMORY);
6033 }
6034}
6035
6036void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
6037{
6038 GLfloat xyz[3] = {x, y, z};
6039
6040 glUniform3fv(location, 1, (GLfloat*)&xyz);
6041}
6042
6043void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
6044{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006045 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006046
6047 try
6048 {
6049 if (count < 0)
6050 {
6051 return error(GL_INVALID_VALUE);
6052 }
6053
6054 if (location == -1)
6055 {
6056 return;
6057 }
6058
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006059 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006060
6061 if (context)
6062 {
6063 gl::Program *program = context->getCurrentProgram();
6064
6065 if (!program)
6066 {
6067 return error(GL_INVALID_OPERATION);
6068 }
6069
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006070 gl::ProgramBinary *programBinary = program->getProgramBinary();
6071 if (!programBinary)
6072 {
6073 return error(GL_INVALID_OPERATION);
6074 }
6075
6076 if (!programBinary->setUniform3fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006077 {
6078 return error(GL_INVALID_OPERATION);
6079 }
6080 }
6081 }
6082 catch(std::bad_alloc&)
6083 {
6084 return error(GL_OUT_OF_MEMORY);
6085 }
6086}
6087
6088void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
6089{
6090 GLint xyz[3] = {x, y, z};
6091
6092 glUniform3iv(location, 1, (GLint*)&xyz);
6093}
6094
6095void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
6096{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006097 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006098
6099 try
6100 {
6101 if (count < 0)
6102 {
6103 return error(GL_INVALID_VALUE);
6104 }
6105
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006106 if (location == -1)
6107 {
6108 return;
6109 }
6110
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006111 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006112
6113 if (context)
6114 {
6115 gl::Program *program = context->getCurrentProgram();
6116
6117 if (!program)
6118 {
6119 return error(GL_INVALID_OPERATION);
6120 }
6121
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006122 gl::ProgramBinary *programBinary = program->getProgramBinary();
6123 if (!programBinary)
6124 {
6125 return error(GL_INVALID_OPERATION);
6126 }
6127
6128 if (!programBinary->setUniform3iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006129 {
6130 return error(GL_INVALID_OPERATION);
6131 }
6132 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006133 }
6134 catch(std::bad_alloc&)
6135 {
6136 return error(GL_OUT_OF_MEMORY);
6137 }
6138}
6139
6140void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6141{
6142 GLfloat xyzw[4] = {x, y, z, w};
6143
6144 glUniform4fv(location, 1, (GLfloat*)&xyzw);
6145}
6146
6147void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
6148{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006149 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006150
6151 try
6152 {
6153 if (count < 0)
6154 {
6155 return error(GL_INVALID_VALUE);
6156 }
6157
6158 if (location == -1)
6159 {
6160 return;
6161 }
6162
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006163 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006164
6165 if (context)
6166 {
6167 gl::Program *program = context->getCurrentProgram();
6168
6169 if (!program)
6170 {
6171 return error(GL_INVALID_OPERATION);
6172 }
6173
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006174 gl::ProgramBinary *programBinary = program->getProgramBinary();
6175 if (!programBinary)
6176 {
6177 return error(GL_INVALID_OPERATION);
6178 }
6179
6180 if (!programBinary->setUniform4fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006181 {
6182 return error(GL_INVALID_OPERATION);
6183 }
6184 }
6185 }
6186 catch(std::bad_alloc&)
6187 {
6188 return error(GL_OUT_OF_MEMORY);
6189 }
6190}
6191
6192void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
6193{
6194 GLint xyzw[4] = {x, y, z, w};
6195
6196 glUniform4iv(location, 1, (GLint*)&xyzw);
6197}
6198
6199void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
6200{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006201 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006202
6203 try
6204 {
6205 if (count < 0)
6206 {
6207 return error(GL_INVALID_VALUE);
6208 }
6209
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006210 if (location == -1)
6211 {
6212 return;
6213 }
6214
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006215 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006216
6217 if (context)
6218 {
6219 gl::Program *program = context->getCurrentProgram();
6220
6221 if (!program)
6222 {
6223 return error(GL_INVALID_OPERATION);
6224 }
6225
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006226 gl::ProgramBinary *programBinary = program->getProgramBinary();
6227 if (!programBinary)
6228 {
6229 return error(GL_INVALID_OPERATION);
6230 }
6231
6232 if (!programBinary->setUniform4iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006233 {
6234 return error(GL_INVALID_OPERATION);
6235 }
6236 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006237 }
6238 catch(std::bad_alloc&)
6239 {
6240 return error(GL_OUT_OF_MEMORY);
6241 }
6242}
6243
6244void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6245{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006246 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006247 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006248
6249 try
6250 {
6251 if (count < 0 || transpose != GL_FALSE)
6252 {
6253 return error(GL_INVALID_VALUE);
6254 }
6255
6256 if (location == -1)
6257 {
6258 return;
6259 }
6260
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006261 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006262
6263 if (context)
6264 {
6265 gl::Program *program = context->getCurrentProgram();
6266
6267 if (!program)
6268 {
6269 return error(GL_INVALID_OPERATION);
6270 }
6271
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006272 gl::ProgramBinary *programBinary = program->getProgramBinary();
6273 if (!programBinary)
6274 {
6275 return error(GL_INVALID_OPERATION);
6276 }
6277
6278 if (!programBinary->setUniformMatrix2fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006279 {
6280 return error(GL_INVALID_OPERATION);
6281 }
6282 }
6283 }
6284 catch(std::bad_alloc&)
6285 {
6286 return error(GL_OUT_OF_MEMORY);
6287 }
6288}
6289
6290void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6291{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006292 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006293 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006294
6295 try
6296 {
6297 if (count < 0 || transpose != GL_FALSE)
6298 {
6299 return error(GL_INVALID_VALUE);
6300 }
6301
6302 if (location == -1)
6303 {
6304 return;
6305 }
6306
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006307 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006308
6309 if (context)
6310 {
6311 gl::Program *program = context->getCurrentProgram();
6312
6313 if (!program)
6314 {
6315 return error(GL_INVALID_OPERATION);
6316 }
6317
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006318 gl::ProgramBinary *programBinary = program->getProgramBinary();
6319 if (!programBinary)
6320 {
6321 return error(GL_INVALID_OPERATION);
6322 }
6323
6324 if (!programBinary->setUniformMatrix3fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006325 {
6326 return error(GL_INVALID_OPERATION);
6327 }
6328 }
6329 }
6330 catch(std::bad_alloc&)
6331 {
6332 return error(GL_OUT_OF_MEMORY);
6333 }
6334}
6335
6336void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6337{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006338 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006339 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006340
6341 try
6342 {
6343 if (count < 0 || transpose != GL_FALSE)
6344 {
6345 return error(GL_INVALID_VALUE);
6346 }
6347
6348 if (location == -1)
6349 {
6350 return;
6351 }
6352
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006353 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006354
6355 if (context)
6356 {
6357 gl::Program *program = context->getCurrentProgram();
6358
6359 if (!program)
6360 {
6361 return error(GL_INVALID_OPERATION);
6362 }
6363
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006364 gl::ProgramBinary *programBinary = program->getProgramBinary();
6365 if (!programBinary)
6366 {
6367 return error(GL_INVALID_OPERATION);
6368 }
6369
6370 if (!programBinary->setUniformMatrix4fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006371 {
6372 return error(GL_INVALID_OPERATION);
6373 }
6374 }
6375 }
6376 catch(std::bad_alloc&)
6377 {
6378 return error(GL_OUT_OF_MEMORY);
6379 }
6380}
6381
6382void __stdcall glUseProgram(GLuint program)
6383{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006384 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006385
6386 try
6387 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006388 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006389
6390 if (context)
6391 {
6392 gl::Program *programObject = context->getProgram(program);
6393
daniel@transgaming.comc8478202010-04-13 19:53:35 +00006394 if (!programObject && program != 0)
6395 {
6396 if (context->getShader(program))
6397 {
6398 return error(GL_INVALID_OPERATION);
6399 }
6400 else
6401 {
6402 return error(GL_INVALID_VALUE);
6403 }
6404 }
6405
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006406 if (program != 0 && !programObject->getProgramBinary())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006407 {
6408 return error(GL_INVALID_OPERATION);
6409 }
6410
6411 context->useProgram(program);
6412 }
6413 }
6414 catch(std::bad_alloc&)
6415 {
6416 return error(GL_OUT_OF_MEMORY);
6417 }
6418}
6419
6420void __stdcall glValidateProgram(GLuint program)
6421{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006422 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006423
6424 try
6425 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006426 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006427
6428 if (context)
6429 {
6430 gl::Program *programObject = context->getProgram(program);
6431
6432 if (!programObject)
6433 {
6434 if (context->getShader(program))
6435 {
6436 return error(GL_INVALID_OPERATION);
6437 }
6438 else
6439 {
6440 return error(GL_INVALID_VALUE);
6441 }
6442 }
6443
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006444 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
6445 if (!programBinary)
6446 {
6447 return;
6448 }
6449
6450 programBinary->validate();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006451 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006452 }
6453 catch(std::bad_alloc&)
6454 {
6455 return error(GL_OUT_OF_MEMORY);
6456 }
6457}
6458
6459void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
6460{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006461 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006462
6463 try
6464 {
6465 if (index >= gl::MAX_VERTEX_ATTRIBS)
6466 {
6467 return error(GL_INVALID_VALUE);
6468 }
6469
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006470 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006471
6472 if (context)
6473 {
6474 GLfloat vals[4] = { x, 0, 0, 1 };
6475 context->setVertexAttrib(index, vals);
6476 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006477 }
6478 catch(std::bad_alloc&)
6479 {
6480 return error(GL_OUT_OF_MEMORY);
6481 }
6482}
6483
6484void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
6485{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006486 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006487
6488 try
6489 {
6490 if (index >= gl::MAX_VERTEX_ATTRIBS)
6491 {
6492 return error(GL_INVALID_VALUE);
6493 }
6494
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006495 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006496
6497 if (context)
6498 {
6499 GLfloat vals[4] = { values[0], 0, 0, 1 };
6500 context->setVertexAttrib(index, vals);
6501 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006502 }
6503 catch(std::bad_alloc&)
6504 {
6505 return error(GL_OUT_OF_MEMORY);
6506 }
6507}
6508
6509void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6510{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006511 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006512
6513 try
6514 {
6515 if (index >= gl::MAX_VERTEX_ATTRIBS)
6516 {
6517 return error(GL_INVALID_VALUE);
6518 }
6519
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006520 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006521
6522 if (context)
6523 {
6524 GLfloat vals[4] = { x, y, 0, 1 };
6525 context->setVertexAttrib(index, vals);
6526 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006527 }
6528 catch(std::bad_alloc&)
6529 {
6530 return error(GL_OUT_OF_MEMORY);
6531 }
6532}
6533
6534void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
6535{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006536 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006537
6538 try
6539 {
6540 if (index >= gl::MAX_VERTEX_ATTRIBS)
6541 {
6542 return error(GL_INVALID_VALUE);
6543 }
6544
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006545 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006546
6547 if (context)
6548 {
6549 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6550 context->setVertexAttrib(index, vals);
6551 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006552 }
6553 catch(std::bad_alloc&)
6554 {
6555 return error(GL_OUT_OF_MEMORY);
6556 }
6557}
6558
6559void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6560{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006561 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 +00006562
6563 try
6564 {
6565 if (index >= gl::MAX_VERTEX_ATTRIBS)
6566 {
6567 return error(GL_INVALID_VALUE);
6568 }
6569
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006570 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006571
6572 if (context)
6573 {
6574 GLfloat vals[4] = { x, y, z, 1 };
6575 context->setVertexAttrib(index, vals);
6576 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006577 }
6578 catch(std::bad_alloc&)
6579 {
6580 return error(GL_OUT_OF_MEMORY);
6581 }
6582}
6583
6584void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
6585{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006586 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006587
6588 try
6589 {
6590 if (index >= gl::MAX_VERTEX_ATTRIBS)
6591 {
6592 return error(GL_INVALID_VALUE);
6593 }
6594
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006595 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006596
6597 if (context)
6598 {
6599 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6600 context->setVertexAttrib(index, vals);
6601 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006602 }
6603 catch(std::bad_alloc&)
6604 {
6605 return error(GL_OUT_OF_MEMORY);
6606 }
6607}
6608
6609void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6610{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006611 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 +00006612
6613 try
6614 {
6615 if (index >= gl::MAX_VERTEX_ATTRIBS)
6616 {
6617 return error(GL_INVALID_VALUE);
6618 }
6619
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006620 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006621
6622 if (context)
6623 {
6624 GLfloat vals[4] = { x, y, z, w };
6625 context->setVertexAttrib(index, vals);
6626 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006627 }
6628 catch(std::bad_alloc&)
6629 {
6630 return error(GL_OUT_OF_MEMORY);
6631 }
6632}
6633
6634void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
6635{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006636 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006637
6638 try
6639 {
6640 if (index >= gl::MAX_VERTEX_ATTRIBS)
6641 {
6642 return error(GL_INVALID_VALUE);
6643 }
6644
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006645 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006646
6647 if (context)
6648 {
6649 context->setVertexAttrib(index, values);
6650 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006651 }
6652 catch(std::bad_alloc&)
6653 {
6654 return error(GL_OUT_OF_MEMORY);
6655 }
6656}
6657
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00006658void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
6659{
6660 EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
6661
6662 try
6663 {
6664 if (index >= gl::MAX_VERTEX_ATTRIBS)
6665 {
6666 return error(GL_INVALID_VALUE);
6667 }
6668
6669 gl::Context *context = gl::getNonLostContext();
6670
6671 if (context)
6672 {
6673 context->setVertexAttribDivisor(index, divisor);
6674 }
6675 }
6676 catch(std::bad_alloc&)
6677 {
6678 return error(GL_OUT_OF_MEMORY);
6679 }
6680}
6681
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006682void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006683{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006684 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006685 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006686 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006687
6688 try
6689 {
6690 if (index >= gl::MAX_VERTEX_ATTRIBS)
6691 {
6692 return error(GL_INVALID_VALUE);
6693 }
6694
6695 if (size < 1 || size > 4)
6696 {
6697 return error(GL_INVALID_VALUE);
6698 }
6699
6700 switch (type)
6701 {
6702 case GL_BYTE:
6703 case GL_UNSIGNED_BYTE:
6704 case GL_SHORT:
6705 case GL_UNSIGNED_SHORT:
6706 case GL_FIXED:
6707 case GL_FLOAT:
6708 break;
6709 default:
6710 return error(GL_INVALID_ENUM);
6711 }
6712
6713 if (stride < 0)
6714 {
6715 return error(GL_INVALID_VALUE);
6716 }
6717
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006718 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006719
6720 if (context)
6721 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006722 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006723 }
6724 }
6725 catch(std::bad_alloc&)
6726 {
6727 return error(GL_OUT_OF_MEMORY);
6728 }
6729}
6730
6731void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6732{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006733 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 +00006734
6735 try
6736 {
6737 if (width < 0 || height < 0)
6738 {
6739 return error(GL_INVALID_VALUE);
6740 }
6741
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006742 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006743
6744 if (context)
6745 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006746 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006747 }
6748 }
6749 catch(std::bad_alloc&)
6750 {
6751 return error(GL_OUT_OF_MEMORY);
6752 }
6753}
6754
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006755void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6756 GLbitfield mask, GLenum filter)
6757{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006758 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006759 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6760 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6761 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6762
6763 try
6764 {
6765 switch (filter)
6766 {
6767 case GL_NEAREST:
6768 break;
6769 default:
6770 return error(GL_INVALID_ENUM);
6771 }
6772
6773 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6774 {
6775 return error(GL_INVALID_VALUE);
6776 }
6777
6778 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6779 {
6780 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6781 return error(GL_INVALID_OPERATION);
6782 }
6783
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006784 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006785
6786 if (context)
6787 {
6788 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6789 {
6790 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6791 return error(GL_INVALID_OPERATION);
6792 }
6793
6794 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6795 }
6796 }
6797 catch(std::bad_alloc&)
6798 {
6799 return error(GL_OUT_OF_MEMORY);
6800 }
6801}
6802
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006803void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6804 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006805{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006806 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006807 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006808 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006809 target, level, internalformat, width, height, depth, border, format, type, pixels);
6810
6811 try
6812 {
6813 UNIMPLEMENTED(); // FIXME
6814 }
6815 catch(std::bad_alloc&)
6816 {
6817 return error(GL_OUT_OF_MEMORY);
6818 }
6819}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006820
6821__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6822{
6823 struct Extension
6824 {
6825 const char *name;
6826 __eglMustCastToProperFunctionPointerType address;
6827 };
6828
6829 static const Extension glExtensions[] =
6830 {
6831 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006832 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006833 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006834 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6835 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6836 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6837 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6838 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6839 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6840 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006841 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006842 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006843 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6844 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6845 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6846 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00006847 {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT},
6848 {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT},
6849 {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT},
6850 {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT},
6851 {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
6852 {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
6853 {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
daniel@transgaming.comdce02fd2012-01-27 15:39:51 +00006854 {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE},
6855 {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE},
6856 {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006857 };
6858
6859 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6860 {
6861 if (strcmp(procname, glExtensions[ext].name) == 0)
6862 {
6863 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6864 }
6865 }
6866
6867 return NULL;
6868}
6869
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006870// Non-public functions used by EGL
6871
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006872bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006873{
6874 EVENT("(egl::Surface* surface = 0x%0.8p)",
6875 surface);
6876
6877 try
6878 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006879 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006880
6881 if (context)
6882 {
6883 gl::Texture2D *textureObject = context->getTexture2D();
6884
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006885 if (textureObject->isImmutable())
6886 {
6887 return false;
6888 }
6889
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006890 if (textureObject)
6891 {
6892 textureObject->bindTexImage(surface);
6893 }
6894 }
6895 }
6896 catch(std::bad_alloc&)
6897 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006898 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006899 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006900
6901 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006902}
6903
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006904}