blob: fba253d8a4130fdd53afeead2a529973bd83f9f7 [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;
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00003424 case GL_PROGRAM_BINARY_LENGTH_OES:
3425 *params = 0;
3426 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003427 default:
3428 return error(GL_INVALID_ENUM);
3429 }
3430 }
3431 }
3432 catch(std::bad_alloc&)
3433 {
3434 return error(GL_OUT_OF_MEMORY);
3435 }
3436}
3437
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003438void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003439{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003440 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 +00003441 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003442
3443 try
3444 {
3445 if (bufsize < 0)
3446 {
3447 return error(GL_INVALID_VALUE);
3448 }
3449
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003450 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003451
3452 if (context)
3453 {
3454 gl::Program *programObject = context->getProgram(program);
3455
3456 if (!programObject)
3457 {
3458 return error(GL_INVALID_VALUE);
3459 }
3460
3461 programObject->getInfoLog(bufsize, length, infolog);
3462 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003463 }
3464 catch(std::bad_alloc&)
3465 {
3466 return error(GL_OUT_OF_MEMORY);
3467 }
3468}
3469
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003470void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3471{
3472 EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
3473
3474 try
3475 {
3476 switch (pname)
3477 {
3478 case GL_CURRENT_QUERY_EXT:
3479 break;
3480 default:
3481 return error(GL_INVALID_ENUM);
3482 }
3483
3484 gl::Context *context = gl::getNonLostContext();
3485
3486 if (context)
3487 {
3488 params[0] = context->getActiveQuery(target);
3489 }
3490 }
3491 catch(std::bad_alloc&)
3492 {
3493 return error(GL_OUT_OF_MEMORY);
3494 }
3495}
3496
3497void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
3498{
3499 EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
3500
3501 try
3502 {
3503 switch (pname)
3504 {
3505 case GL_QUERY_RESULT_EXT:
3506 case GL_QUERY_RESULT_AVAILABLE_EXT:
3507 break;
3508 default:
3509 return error(GL_INVALID_ENUM);
3510 }
3511 gl::Context *context = gl::getNonLostContext();
3512
3513 if (context)
3514 {
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003515 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
3516
3517 if (!queryObject)
3518 {
3519 return error(GL_INVALID_OPERATION);
3520 }
3521
3522 if (context->getActiveQuery(queryObject->getType()) == id)
3523 {
3524 return error(GL_INVALID_OPERATION);
3525 }
3526
3527 switch(pname)
3528 {
3529 case GL_QUERY_RESULT_EXT:
3530 params[0] = queryObject->getResult();
3531 break;
3532 case GL_QUERY_RESULT_AVAILABLE_EXT:
3533 params[0] = queryObject->isResultAvailable();
3534 break;
3535 default:
3536 ASSERT(false);
3537 }
3538 }
3539 }
3540 catch(std::bad_alloc&)
3541 {
3542 return error(GL_OUT_OF_MEMORY);
3543 }
3544}
3545
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003546void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3547{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003548 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 +00003549
3550 try
3551 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003552 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003553
3554 if (context)
3555 {
3556 if (target != GL_RENDERBUFFER)
3557 {
3558 return error(GL_INVALID_ENUM);
3559 }
3560
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003561 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003562 {
3563 return error(GL_INVALID_OPERATION);
3564 }
3565
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003566 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003567
3568 switch (pname)
3569 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003570 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3571 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3572 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3573 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3574 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3575 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3576 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3577 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3578 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003579 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003580 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003581 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003582 *params = renderbuffer->getSamples();
3583 }
3584 else
3585 {
3586 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003587 }
3588 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003589 default:
3590 return error(GL_INVALID_ENUM);
3591 }
3592 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003593 }
3594 catch(std::bad_alloc&)
3595 {
3596 return error(GL_OUT_OF_MEMORY);
3597 }
3598}
3599
3600void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3601{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003602 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003603
3604 try
3605 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003606 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003607
3608 if (context)
3609 {
3610 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003611
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003612 if (!shaderObject)
3613 {
3614 return error(GL_INVALID_VALUE);
3615 }
3616
3617 switch (pname)
3618 {
3619 case GL_SHADER_TYPE:
3620 *params = shaderObject->getType();
3621 return;
3622 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003623 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003624 return;
3625 case GL_COMPILE_STATUS:
3626 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3627 return;
3628 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003629 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003630 return;
3631 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003632 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003633 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003634 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3635 *params = shaderObject->getTranslatedSourceLength();
3636 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003637 default:
3638 return error(GL_INVALID_ENUM);
3639 }
3640 }
3641 }
3642 catch(std::bad_alloc&)
3643 {
3644 return error(GL_OUT_OF_MEMORY);
3645 }
3646}
3647
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003648void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003649{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003650 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 +00003651 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003652
3653 try
3654 {
3655 if (bufsize < 0)
3656 {
3657 return error(GL_INVALID_VALUE);
3658 }
3659
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003660 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003661
3662 if (context)
3663 {
3664 gl::Shader *shaderObject = context->getShader(shader);
3665
3666 if (!shaderObject)
3667 {
3668 return error(GL_INVALID_VALUE);
3669 }
3670
3671 shaderObject->getInfoLog(bufsize, length, infolog);
3672 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003673 }
3674 catch(std::bad_alloc&)
3675 {
3676 return error(GL_OUT_OF_MEMORY);
3677 }
3678}
3679
3680void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3681{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003682 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 +00003683 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003684
3685 try
3686 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003687 switch (shadertype)
3688 {
3689 case GL_VERTEX_SHADER:
3690 case GL_FRAGMENT_SHADER:
3691 break;
3692 default:
3693 return error(GL_INVALID_ENUM);
3694 }
3695
3696 switch (precisiontype)
3697 {
3698 case GL_LOW_FLOAT:
3699 case GL_MEDIUM_FLOAT:
3700 case GL_HIGH_FLOAT:
3701 // Assume IEEE 754 precision
3702 range[0] = 127;
3703 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003704 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003705 break;
3706 case GL_LOW_INT:
3707 case GL_MEDIUM_INT:
3708 case GL_HIGH_INT:
3709 // Some (most) hardware only supports single-precision floating-point numbers,
3710 // which can accurately represent integers up to +/-16777216
3711 range[0] = 24;
3712 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003713 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003714 break;
3715 default:
3716 return error(GL_INVALID_ENUM);
3717 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003718 }
3719 catch(std::bad_alloc&)
3720 {
3721 return error(GL_OUT_OF_MEMORY);
3722 }
3723}
3724
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003725void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003726{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003727 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 +00003728 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003729
3730 try
3731 {
3732 if (bufsize < 0)
3733 {
3734 return error(GL_INVALID_VALUE);
3735 }
3736
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003737 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003738
3739 if (context)
3740 {
3741 gl::Shader *shaderObject = context->getShader(shader);
3742
3743 if (!shaderObject)
3744 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003745 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003746 }
3747
3748 shaderObject->getSource(bufsize, length, source);
3749 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003750 }
3751 catch(std::bad_alloc&)
3752 {
3753 return error(GL_OUT_OF_MEMORY);
3754 }
3755}
3756
zmo@google.coma574f782011-10-03 21:45:23 +00003757void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3758{
3759 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3760 shader, bufsize, length, source);
3761
3762 try
3763 {
3764 if (bufsize < 0)
3765 {
3766 return error(GL_INVALID_VALUE);
3767 }
3768
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003769 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003770
3771 if (context)
3772 {
3773 gl::Shader *shaderObject = context->getShader(shader);
3774
3775 if (!shaderObject)
3776 {
3777 return error(GL_INVALID_OPERATION);
3778 }
3779
3780 shaderObject->getTranslatedSource(bufsize, length, source);
3781 }
3782 }
3783 catch(std::bad_alloc&)
3784 {
3785 return error(GL_OUT_OF_MEMORY);
3786 }
3787}
3788
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003789const GLubyte* __stdcall glGetString(GLenum name)
3790{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003791 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003792
3793 try
3794 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003795 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003796
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003797 switch (name)
3798 {
3799 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003800 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003801 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003802 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003803 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003804 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003805 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003806 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003807 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003808 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003809 default:
3810 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3811 }
3812 }
3813 catch(std::bad_alloc&)
3814 {
3815 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3816 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003817}
3818
3819void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3820{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003821 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 +00003822
3823 try
3824 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003825 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003826
3827 if (context)
3828 {
3829 gl::Texture *texture;
3830
3831 switch (target)
3832 {
3833 case GL_TEXTURE_2D:
3834 texture = context->getTexture2D();
3835 break;
3836 case GL_TEXTURE_CUBE_MAP:
3837 texture = context->getTextureCubeMap();
3838 break;
3839 default:
3840 return error(GL_INVALID_ENUM);
3841 }
3842
3843 switch (pname)
3844 {
3845 case GL_TEXTURE_MAG_FILTER:
3846 *params = (GLfloat)texture->getMagFilter();
3847 break;
3848 case GL_TEXTURE_MIN_FILTER:
3849 *params = (GLfloat)texture->getMinFilter();
3850 break;
3851 case GL_TEXTURE_WRAP_S:
3852 *params = (GLfloat)texture->getWrapS();
3853 break;
3854 case GL_TEXTURE_WRAP_T:
3855 *params = (GLfloat)texture->getWrapT();
3856 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003857 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3858 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3859 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003860 case GL_TEXTURE_USAGE_ANGLE:
3861 *params = (GLfloat)texture->getUsage();
3862 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003863 default:
3864 return error(GL_INVALID_ENUM);
3865 }
3866 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003867 }
3868 catch(std::bad_alloc&)
3869 {
3870 return error(GL_OUT_OF_MEMORY);
3871 }
3872}
3873
3874void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3875{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003876 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 +00003877
3878 try
3879 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003880 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003881
3882 if (context)
3883 {
3884 gl::Texture *texture;
3885
3886 switch (target)
3887 {
3888 case GL_TEXTURE_2D:
3889 texture = context->getTexture2D();
3890 break;
3891 case GL_TEXTURE_CUBE_MAP:
3892 texture = context->getTextureCubeMap();
3893 break;
3894 default:
3895 return error(GL_INVALID_ENUM);
3896 }
3897
3898 switch (pname)
3899 {
3900 case GL_TEXTURE_MAG_FILTER:
3901 *params = texture->getMagFilter();
3902 break;
3903 case GL_TEXTURE_MIN_FILTER:
3904 *params = texture->getMinFilter();
3905 break;
3906 case GL_TEXTURE_WRAP_S:
3907 *params = texture->getWrapS();
3908 break;
3909 case GL_TEXTURE_WRAP_T:
3910 *params = texture->getWrapT();
3911 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003912 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3913 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3914 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003915 case GL_TEXTURE_USAGE_ANGLE:
3916 *params = texture->getUsage();
3917 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003918 default:
3919 return error(GL_INVALID_ENUM);
3920 }
3921 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003922 }
3923 catch(std::bad_alloc&)
3924 {
3925 return error(GL_OUT_OF_MEMORY);
3926 }
3927}
3928
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003929void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3930{
3931 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3932 program, location, bufSize, params);
3933
3934 try
3935 {
3936 if (bufSize < 0)
3937 {
3938 return error(GL_INVALID_VALUE);
3939 }
3940
3941 gl::Context *context = gl::getNonLostContext();
3942
3943 if (context)
3944 {
3945 if (program == 0)
3946 {
3947 return error(GL_INVALID_VALUE);
3948 }
3949
3950 gl::Program *programObject = context->getProgram(program);
3951
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003952 if (!programObject)
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003953 {
3954 return error(GL_INVALID_OPERATION);
3955 }
3956
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003957 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
3958 if (!programBinary)
3959 {
3960 return error(GL_INVALID_OPERATION);
3961 }
3962
3963 if (!programBinary->getUniformfv(location, &bufSize, params))
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003964 {
3965 return error(GL_INVALID_OPERATION);
3966 }
3967 }
3968 }
3969 catch(std::bad_alloc&)
3970 {
3971 return error(GL_OUT_OF_MEMORY);
3972 }
3973}
3974
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003975void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3976{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003977 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003978
3979 try
3980 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003981 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003982
3983 if (context)
3984 {
3985 if (program == 0)
3986 {
3987 return error(GL_INVALID_VALUE);
3988 }
3989
3990 gl::Program *programObject = context->getProgram(program);
3991
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003992 if (!programObject)
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003993 {
3994 return error(GL_INVALID_OPERATION);
3995 }
3996
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003997 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
3998 if (!programBinary)
3999 {
4000 return error(GL_INVALID_OPERATION);
4001 }
4002
4003 if (!programBinary->getUniformfv(location, NULL, params))
daniel@transgaming.com9a849122011-11-12 03:18:00 +00004004 {
4005 return error(GL_INVALID_OPERATION);
4006 }
4007 }
4008 }
4009 catch(std::bad_alloc&)
4010 {
4011 return error(GL_OUT_OF_MEMORY);
4012 }
4013}
4014
4015void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
4016{
4017 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
4018 program, location, bufSize, params);
4019
4020 try
4021 {
4022 if (bufSize < 0)
4023 {
4024 return error(GL_INVALID_VALUE);
4025 }
4026
4027 gl::Context *context = gl::getNonLostContext();
4028
4029 if (context)
4030 {
4031 if (program == 0)
4032 {
4033 return error(GL_INVALID_VALUE);
4034 }
4035
4036 gl::Program *programObject = context->getProgram(program);
4037
daniel@transgaming.com9a849122011-11-12 03:18:00 +00004038 if (!programObject)
4039 {
4040 return error(GL_INVALID_OPERATION);
4041 }
4042
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004043 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4044 if (!programBinary)
4045 {
4046 return error(GL_INVALID_OPERATION);
4047 }
4048
4049 if (!programBinary->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004050 {
4051 return error(GL_INVALID_OPERATION);
4052 }
4053 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004054 }
4055 catch(std::bad_alloc&)
4056 {
4057 return error(GL_OUT_OF_MEMORY);
4058 }
4059}
4060
4061void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
4062{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004063 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004064
4065 try
4066 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004067 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004068
4069 if (context)
4070 {
4071 if (program == 0)
4072 {
4073 return error(GL_INVALID_VALUE);
4074 }
4075
4076 gl::Program *programObject = context->getProgram(program);
4077
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004078 if (!programObject)
4079 {
4080 return error(GL_INVALID_OPERATION);
4081 }
4082
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004083 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4084 if (!programBinary)
4085 {
4086 return error(GL_INVALID_OPERATION);
4087 }
4088
4089 if (!programBinary->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004090 {
4091 return error(GL_INVALID_OPERATION);
4092 }
4093 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004094 }
4095 catch(std::bad_alloc&)
4096 {
4097 return error(GL_OUT_OF_MEMORY);
4098 }
4099}
4100
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004101int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004102{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004103 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004104
4105 try
4106 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004107 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004108
4109 if (strstr(name, "gl_") == name)
4110 {
4111 return -1;
4112 }
4113
4114 if (context)
4115 {
4116 gl::Program *programObject = context->getProgram(program);
4117
4118 if (!programObject)
4119 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00004120 if (context->getShader(program))
4121 {
4122 return error(GL_INVALID_OPERATION, -1);
4123 }
4124 else
4125 {
4126 return error(GL_INVALID_VALUE, -1);
4127 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004128 }
4129
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004130 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4131 if (!programBinary)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004132 {
4133 return error(GL_INVALID_OPERATION, -1);
4134 }
4135
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004136 return programBinary->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004137 }
4138 }
4139 catch(std::bad_alloc&)
4140 {
4141 return error(GL_OUT_OF_MEMORY, -1);
4142 }
4143
4144 return -1;
4145}
4146
4147void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
4148{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004149 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004150
4151 try
4152 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004153 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004154
daniel@transgaming.come0078962010-04-15 20:45:08 +00004155 if (context)
4156 {
4157 if (index >= gl::MAX_VERTEX_ATTRIBS)
4158 {
4159 return error(GL_INVALID_VALUE);
4160 }
4161
daniel@transgaming.com83921382011-01-08 05:46:00 +00004162 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004163
daniel@transgaming.come0078962010-04-15 20:45:08 +00004164 switch (pname)
4165 {
4166 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004167 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004168 break;
4169 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004170 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004171 break;
4172 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004173 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004174 break;
4175 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004176 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004177 break;
4178 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004179 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004180 break;
4181 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004182 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004183 break;
4184 case GL_CURRENT_VERTEX_ATTRIB:
4185 for (int i = 0; i < 4; ++i)
4186 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004187 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004188 }
4189 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004190 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4191 *params = (GLfloat)attribState.mDivisor;
4192 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004193 default: return error(GL_INVALID_ENUM);
4194 }
4195 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004196 }
4197 catch(std::bad_alloc&)
4198 {
4199 return error(GL_OUT_OF_MEMORY);
4200 }
4201}
4202
4203void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
4204{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004205 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004206
4207 try
4208 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004209 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004210
daniel@transgaming.come0078962010-04-15 20:45:08 +00004211 if (context)
4212 {
4213 if (index >= gl::MAX_VERTEX_ATTRIBS)
4214 {
4215 return error(GL_INVALID_VALUE);
4216 }
4217
daniel@transgaming.com83921382011-01-08 05:46:00 +00004218 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004219
daniel@transgaming.come0078962010-04-15 20:45:08 +00004220 switch (pname)
4221 {
4222 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004223 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004224 break;
4225 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004226 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004227 break;
4228 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004229 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004230 break;
4231 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004232 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004233 break;
4234 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004235 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004236 break;
4237 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004238 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004239 break;
4240 case GL_CURRENT_VERTEX_ATTRIB:
4241 for (int i = 0; i < 4; ++i)
4242 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004243 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004244 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4245 }
4246 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004247 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4248 *params = (GLint)attribState.mDivisor;
4249 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004250 default: return error(GL_INVALID_ENUM);
4251 }
4252 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004253 }
4254 catch(std::bad_alloc&)
4255 {
4256 return error(GL_OUT_OF_MEMORY);
4257 }
4258}
4259
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004260void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004261{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004262 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004263
4264 try
4265 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004266 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004267
daniel@transgaming.come0078962010-04-15 20:45:08 +00004268 if (context)
4269 {
4270 if (index >= gl::MAX_VERTEX_ATTRIBS)
4271 {
4272 return error(GL_INVALID_VALUE);
4273 }
4274
4275 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4276 {
4277 return error(GL_INVALID_ENUM);
4278 }
4279
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004280 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00004281 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004282 }
4283 catch(std::bad_alloc&)
4284 {
4285 return error(GL_OUT_OF_MEMORY);
4286 }
4287}
4288
4289void __stdcall glHint(GLenum target, GLenum mode)
4290{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004291 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004292
4293 try
4294 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004295 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004296 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004297 case GL_FASTEST:
4298 case GL_NICEST:
4299 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004300 break;
4301 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004302 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004303 }
4304
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004305 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004306 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004307 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004308 case GL_GENERATE_MIPMAP_HINT:
4309 if (context) context->setGenerateMipmapHint(mode);
4310 break;
4311 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4312 if (context) context->setFragmentShaderDerivativeHint(mode);
4313 break;
4314 default:
4315 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004316 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004317 }
4318 catch(std::bad_alloc&)
4319 {
4320 return error(GL_OUT_OF_MEMORY);
4321 }
4322}
4323
4324GLboolean __stdcall glIsBuffer(GLuint buffer)
4325{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004326 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004327
4328 try
4329 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004330 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004331
4332 if (context && buffer)
4333 {
4334 gl::Buffer *bufferObject = context->getBuffer(buffer);
4335
4336 if (bufferObject)
4337 {
4338 return GL_TRUE;
4339 }
4340 }
4341 }
4342 catch(std::bad_alloc&)
4343 {
4344 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4345 }
4346
4347 return GL_FALSE;
4348}
4349
4350GLboolean __stdcall glIsEnabled(GLenum cap)
4351{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004352 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004353
4354 try
4355 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004356 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004357
4358 if (context)
4359 {
4360 switch (cap)
4361 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004362 case GL_CULL_FACE: return context->isCullFaceEnabled();
4363 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4364 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4365 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4366 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4367 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4368 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4369 case GL_BLEND: return context->isBlendEnabled();
4370 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004371 default:
4372 return error(GL_INVALID_ENUM, false);
4373 }
4374 }
4375 }
4376 catch(std::bad_alloc&)
4377 {
4378 return error(GL_OUT_OF_MEMORY, false);
4379 }
4380
4381 return false;
4382}
4383
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004384GLboolean __stdcall glIsFenceNV(GLuint fence)
4385{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004386 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004387
4388 try
4389 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004390 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004391
4392 if (context)
4393 {
4394 gl::Fence *fenceObject = context->getFence(fence);
4395
4396 if (fenceObject == NULL)
4397 {
4398 return GL_FALSE;
4399 }
4400
4401 return fenceObject->isFence();
4402 }
4403 }
4404 catch(std::bad_alloc&)
4405 {
4406 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4407 }
4408
4409 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004410}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004411
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004412GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
4413{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004414 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004415
4416 try
4417 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004418 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004419
4420 if (context && framebuffer)
4421 {
4422 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4423
4424 if (framebufferObject)
4425 {
4426 return GL_TRUE;
4427 }
4428 }
4429 }
4430 catch(std::bad_alloc&)
4431 {
4432 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4433 }
4434
4435 return GL_FALSE;
4436}
4437
4438GLboolean __stdcall glIsProgram(GLuint program)
4439{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004440 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004441
4442 try
4443 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004444 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004445
4446 if (context && program)
4447 {
4448 gl::Program *programObject = context->getProgram(program);
4449
4450 if (programObject)
4451 {
4452 return GL_TRUE;
4453 }
4454 }
4455 }
4456 catch(std::bad_alloc&)
4457 {
4458 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4459 }
4460
4461 return GL_FALSE;
4462}
4463
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00004464GLboolean __stdcall glIsQueryEXT(GLuint id)
4465{
4466 EVENT("(GLuint id = %d)", id);
4467
4468 try
4469 {
4470 if (id == 0)
4471 {
4472 return GL_FALSE;
4473 }
4474
4475 gl::Context *context = gl::getNonLostContext();
4476
4477 if (context)
4478 {
4479 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
4480
4481 if (queryObject)
4482 {
4483 return GL_TRUE;
4484 }
4485 }
4486 }
4487 catch(std::bad_alloc&)
4488 {
4489 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4490 }
4491
4492 return GL_FALSE;
4493}
4494
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004495GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
4496{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004497 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004498
4499 try
4500 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004501 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004502
4503 if (context && renderbuffer)
4504 {
4505 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4506
4507 if (renderbufferObject)
4508 {
4509 return GL_TRUE;
4510 }
4511 }
4512 }
4513 catch(std::bad_alloc&)
4514 {
4515 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4516 }
4517
4518 return GL_FALSE;
4519}
4520
4521GLboolean __stdcall glIsShader(GLuint shader)
4522{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004523 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004524
4525 try
4526 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004527 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004528
4529 if (context && shader)
4530 {
4531 gl::Shader *shaderObject = context->getShader(shader);
4532
4533 if (shaderObject)
4534 {
4535 return GL_TRUE;
4536 }
4537 }
4538 }
4539 catch(std::bad_alloc&)
4540 {
4541 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4542 }
4543
4544 return GL_FALSE;
4545}
4546
4547GLboolean __stdcall glIsTexture(GLuint texture)
4548{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004549 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004550
4551 try
4552 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004553 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004554
4555 if (context && texture)
4556 {
4557 gl::Texture *textureObject = context->getTexture(texture);
4558
4559 if (textureObject)
4560 {
4561 return GL_TRUE;
4562 }
4563 }
4564 }
4565 catch(std::bad_alloc&)
4566 {
4567 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4568 }
4569
4570 return GL_FALSE;
4571}
4572
4573void __stdcall glLineWidth(GLfloat width)
4574{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004575 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004576
4577 try
4578 {
4579 if (width <= 0.0f)
4580 {
4581 return error(GL_INVALID_VALUE);
4582 }
4583
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004584 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004585
4586 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004587 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004588 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004589 }
4590 }
4591 catch(std::bad_alloc&)
4592 {
4593 return error(GL_OUT_OF_MEMORY);
4594 }
4595}
4596
4597void __stdcall glLinkProgram(GLuint program)
4598{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004599 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004600
4601 try
4602 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004603 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004604
4605 if (context)
4606 {
4607 gl::Program *programObject = context->getProgram(program);
4608
4609 if (!programObject)
4610 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004611 if (context->getShader(program))
4612 {
4613 return error(GL_INVALID_OPERATION);
4614 }
4615 else
4616 {
4617 return error(GL_INVALID_VALUE);
4618 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004619 }
4620
4621 programObject->link();
4622 }
4623 }
4624 catch(std::bad_alloc&)
4625 {
4626 return error(GL_OUT_OF_MEMORY);
4627 }
4628}
4629
4630void __stdcall glPixelStorei(GLenum pname, GLint param)
4631{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004632 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004633
4634 try
4635 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004636 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004637
4638 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004639 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004640 switch (pname)
4641 {
4642 case GL_UNPACK_ALIGNMENT:
4643 if (param != 1 && param != 2 && param != 4 && param != 8)
4644 {
4645 return error(GL_INVALID_VALUE);
4646 }
4647
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004648 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004649 break;
4650
4651 case GL_PACK_ALIGNMENT:
4652 if (param != 1 && param != 2 && param != 4 && param != 8)
4653 {
4654 return error(GL_INVALID_VALUE);
4655 }
4656
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004657 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004658 break;
4659
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004660 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4661 context->setPackReverseRowOrder(param != 0);
4662 break;
4663
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004664 default:
4665 return error(GL_INVALID_ENUM);
4666 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004667 }
4668 }
4669 catch(std::bad_alloc&)
4670 {
4671 return error(GL_OUT_OF_MEMORY);
4672 }
4673}
4674
4675void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4676{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004677 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004678
4679 try
4680 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004681 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004682
4683 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004684 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004685 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004686 }
4687 }
4688 catch(std::bad_alloc&)
4689 {
4690 return error(GL_OUT_OF_MEMORY);
4691 }
4692}
4693
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004694void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4695 GLenum format, GLenum type, GLsizei bufSize,
4696 GLvoid *data)
4697{
4698 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4699 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4700 x, y, width, height, format, type, bufSize, data);
4701
4702 try
4703 {
4704 if (width < 0 || height < 0 || bufSize < 0)
4705 {
4706 return error(GL_INVALID_VALUE);
4707 }
4708
4709 if (!validReadFormatType(format, type))
4710 {
4711 return error(GL_INVALID_OPERATION);
4712 }
4713
4714 gl::Context *context = gl::getNonLostContext();
4715
4716 if (context)
4717 {
4718 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4719 }
4720 }
4721 catch(std::bad_alloc&)
4722 {
4723 return error(GL_OUT_OF_MEMORY);
4724 }
4725}
4726
4727void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4728 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004729{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004730 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004731 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004732 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004733
4734 try
4735 {
4736 if (width < 0 || height < 0)
4737 {
4738 return error(GL_INVALID_VALUE);
4739 }
4740
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004741 if (!validReadFormatType(format, type))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004742 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004743 return error(GL_INVALID_OPERATION);
4744 }
4745
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004746 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004747
4748 if (context)
4749 {
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004750 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004751 }
4752 }
4753 catch(std::bad_alloc&)
4754 {
4755 return error(GL_OUT_OF_MEMORY);
4756 }
4757}
4758
4759void __stdcall glReleaseShaderCompiler(void)
4760{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004761 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004762
4763 try
4764 {
4765 gl::Shader::releaseCompiler();
4766 }
4767 catch(std::bad_alloc&)
4768 {
4769 return error(GL_OUT_OF_MEMORY);
4770 }
4771}
4772
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004773void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004774{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004775 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 +00004776 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004777
4778 try
4779 {
4780 switch (target)
4781 {
4782 case GL_RENDERBUFFER:
4783 break;
4784 default:
4785 return error(GL_INVALID_ENUM);
4786 }
4787
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004788 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004789 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004790 return error(GL_INVALID_ENUM);
4791 }
4792
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004793 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004794 {
4795 return error(GL_INVALID_VALUE);
4796 }
4797
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004798 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004799
4800 if (context)
4801 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004802 if (width > context->getMaximumRenderbufferDimension() ||
4803 height > context->getMaximumRenderbufferDimension() ||
4804 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004805 {
4806 return error(GL_INVALID_VALUE);
4807 }
4808
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004809 GLuint handle = context->getRenderbufferHandle();
4810 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004811 {
4812 return error(GL_INVALID_OPERATION);
4813 }
4814
4815 switch (internalformat)
4816 {
4817 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004818 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004819 break;
4820 case GL_RGBA4:
4821 case GL_RGB5_A1:
4822 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004823 case GL_RGB8_OES:
4824 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004825 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004826 break;
4827 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004828 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004829 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004830 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004831 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004832 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004833 default:
4834 return error(GL_INVALID_ENUM);
4835 }
4836 }
4837 }
4838 catch(std::bad_alloc&)
4839 {
4840 return error(GL_OUT_OF_MEMORY);
4841 }
4842}
4843
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004844void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4845{
4846 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4847}
4848
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004849void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4850{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004851 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004852
4853 try
4854 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004855 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004856
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004857 if (context)
4858 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004859 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004860 }
4861 }
4862 catch(std::bad_alloc&)
4863 {
4864 return error(GL_OUT_OF_MEMORY);
4865 }
4866}
4867
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004868void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4869{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004870 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004871
4872 try
4873 {
4874 if (condition != GL_ALL_COMPLETED_NV)
4875 {
4876 return error(GL_INVALID_ENUM);
4877 }
4878
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004879 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004880
4881 if (context)
4882 {
4883 gl::Fence *fenceObject = context->getFence(fence);
4884
4885 if (fenceObject == NULL)
4886 {
4887 return error(GL_INVALID_OPERATION);
4888 }
4889
4890 fenceObject->setFence(condition);
4891 }
4892 }
4893 catch(std::bad_alloc&)
4894 {
4895 return error(GL_OUT_OF_MEMORY);
4896 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004897}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004898
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004899void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4900{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004901 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 +00004902
4903 try
4904 {
4905 if (width < 0 || height < 0)
4906 {
4907 return error(GL_INVALID_VALUE);
4908 }
4909
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004910 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004911
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004912 if (context)
4913 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004914 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004915 }
4916 }
4917 catch(std::bad_alloc&)
4918 {
4919 return error(GL_OUT_OF_MEMORY);
4920 }
4921}
4922
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004923void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004924{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004925 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004926 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004927 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004928
4929 try
4930 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004931 // No binary shader formats are supported.
4932 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004933 }
4934 catch(std::bad_alloc&)
4935 {
4936 return error(GL_OUT_OF_MEMORY);
4937 }
4938}
4939
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004940void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004941{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004942 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 +00004943 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004944
4945 try
4946 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004947 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004948 {
4949 return error(GL_INVALID_VALUE);
4950 }
4951
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004952 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004953
4954 if (context)
4955 {
4956 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004957
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004958 if (!shaderObject)
4959 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004960 if (context->getProgram(shader))
4961 {
4962 return error(GL_INVALID_OPERATION);
4963 }
4964 else
4965 {
4966 return error(GL_INVALID_VALUE);
4967 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004968 }
4969
4970 shaderObject->setSource(count, string, length);
4971 }
4972 }
4973 catch(std::bad_alloc&)
4974 {
4975 return error(GL_OUT_OF_MEMORY);
4976 }
4977}
4978
4979void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4980{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004981 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004982}
4983
4984void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4985{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004986 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 +00004987
4988 try
4989 {
4990 switch (face)
4991 {
4992 case GL_FRONT:
4993 case GL_BACK:
4994 case GL_FRONT_AND_BACK:
4995 break;
4996 default:
4997 return error(GL_INVALID_ENUM);
4998 }
4999
5000 switch (func)
5001 {
5002 case GL_NEVER:
5003 case GL_ALWAYS:
5004 case GL_LESS:
5005 case GL_LEQUAL:
5006 case GL_EQUAL:
5007 case GL_GEQUAL:
5008 case GL_GREATER:
5009 case GL_NOTEQUAL:
5010 break;
5011 default:
5012 return error(GL_INVALID_ENUM);
5013 }
5014
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005015 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005016
5017 if (context)
5018 {
5019 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5020 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005021 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005022 }
5023
5024 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5025 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005026 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005027 }
5028 }
5029 }
5030 catch(std::bad_alloc&)
5031 {
5032 return error(GL_OUT_OF_MEMORY);
5033 }
5034}
5035
5036void __stdcall glStencilMask(GLuint mask)
5037{
5038 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
5039}
5040
5041void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
5042{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005043 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005044
5045 try
5046 {
5047 switch (face)
5048 {
5049 case GL_FRONT:
5050 case GL_BACK:
5051 case GL_FRONT_AND_BACK:
5052 break;
5053 default:
5054 return error(GL_INVALID_ENUM);
5055 }
5056
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005057 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005058
5059 if (context)
5060 {
5061 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5062 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005063 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005064 }
5065
5066 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5067 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005068 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005069 }
5070 }
5071 }
5072 catch(std::bad_alloc&)
5073 {
5074 return error(GL_OUT_OF_MEMORY);
5075 }
5076}
5077
5078void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
5079{
5080 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
5081}
5082
5083void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
5084{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005085 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 +00005086 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005087
5088 try
5089 {
5090 switch (face)
5091 {
5092 case GL_FRONT:
5093 case GL_BACK:
5094 case GL_FRONT_AND_BACK:
5095 break;
5096 default:
5097 return error(GL_INVALID_ENUM);
5098 }
5099
5100 switch (fail)
5101 {
5102 case GL_ZERO:
5103 case GL_KEEP:
5104 case GL_REPLACE:
5105 case GL_INCR:
5106 case GL_DECR:
5107 case GL_INVERT:
5108 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005109 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005110 break;
5111 default:
5112 return error(GL_INVALID_ENUM);
5113 }
5114
5115 switch (zfail)
5116 {
5117 case GL_ZERO:
5118 case GL_KEEP:
5119 case GL_REPLACE:
5120 case GL_INCR:
5121 case GL_DECR:
5122 case GL_INVERT:
5123 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005124 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005125 break;
5126 default:
5127 return error(GL_INVALID_ENUM);
5128 }
5129
5130 switch (zpass)
5131 {
5132 case GL_ZERO:
5133 case GL_KEEP:
5134 case GL_REPLACE:
5135 case GL_INCR:
5136 case GL_DECR:
5137 case GL_INVERT:
5138 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005139 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005140 break;
5141 default:
5142 return error(GL_INVALID_ENUM);
5143 }
5144
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005145 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005146
5147 if (context)
5148 {
5149 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5150 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005151 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005152 }
5153
5154 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5155 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005156 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005157 }
5158 }
5159 }
5160 catch(std::bad_alloc&)
5161 {
5162 return error(GL_OUT_OF_MEMORY);
5163 }
5164}
5165
daniel@transgaming.comfe208882010-09-01 15:47:57 +00005166GLboolean __stdcall glTestFenceNV(GLuint fence)
5167{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005168 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005169
5170 try
5171 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005172 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005173
5174 if (context)
5175 {
5176 gl::Fence *fenceObject = context->getFence(fence);
5177
5178 if (fenceObject == NULL)
5179 {
5180 return error(GL_INVALID_OPERATION, GL_TRUE);
5181 }
5182
5183 return fenceObject->testFence();
5184 }
5185 }
5186 catch(std::bad_alloc&)
5187 {
5188 error(GL_OUT_OF_MEMORY);
5189 }
5190
5191 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00005192}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005193
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005194void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
5195 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005196{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005197 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 +00005198 "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 +00005199 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005200
5201 try
5202 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00005203 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005204 {
5205 return error(GL_INVALID_VALUE);
5206 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005207
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +00005208 if (internalformat != GLint(format))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005209 {
5210 return error(GL_INVALID_OPERATION);
5211 }
5212
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005213 // validate <type> by itself (used as secondary key below)
5214 switch (type)
5215 {
5216 case GL_UNSIGNED_BYTE:
5217 case GL_UNSIGNED_SHORT_5_6_5:
5218 case GL_UNSIGNED_SHORT_4_4_4_4:
5219 case GL_UNSIGNED_SHORT_5_5_5_1:
5220 case GL_UNSIGNED_SHORT:
5221 case GL_UNSIGNED_INT:
5222 case GL_UNSIGNED_INT_24_8_OES:
5223 case GL_HALF_FLOAT_OES:
5224 case GL_FLOAT:
5225 break;
5226 default:
5227 return error(GL_INVALID_ENUM);
5228 }
5229
5230 // validate <format> + <type> combinations
5231 // - invalid <format> -> sets INVALID_ENUM
5232 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005233 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005234 {
5235 case GL_ALPHA:
5236 case GL_LUMINANCE:
5237 case GL_LUMINANCE_ALPHA:
5238 switch (type)
5239 {
5240 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005241 case GL_FLOAT:
5242 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005243 break;
5244 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005245 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005246 }
5247 break;
5248 case GL_RGB:
5249 switch (type)
5250 {
5251 case GL_UNSIGNED_BYTE:
5252 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005253 case GL_FLOAT:
5254 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005255 break;
5256 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005257 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005258 }
5259 break;
5260 case GL_RGBA:
5261 switch (type)
5262 {
5263 case GL_UNSIGNED_BYTE:
5264 case GL_UNSIGNED_SHORT_4_4_4_4:
5265 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005266 case GL_FLOAT:
5267 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005268 break;
5269 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005270 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005271 }
5272 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005273 case GL_BGRA_EXT:
5274 switch (type)
5275 {
5276 case GL_UNSIGNED_BYTE:
5277 break;
5278 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005279 return error(GL_INVALID_OPERATION);
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005280 }
5281 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005282 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
5283 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00005284 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5285 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00005286 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005287 case GL_DEPTH_COMPONENT:
5288 switch (type)
5289 {
5290 case GL_UNSIGNED_SHORT:
5291 case GL_UNSIGNED_INT:
5292 break;
5293 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005294 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005295 }
5296 break;
5297 case GL_DEPTH_STENCIL_OES:
5298 switch (type)
5299 {
5300 case GL_UNSIGNED_INT_24_8_OES:
5301 break;
5302 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005303 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005304 }
5305 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005306 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005307 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005308 }
5309
5310 if (border != 0)
5311 {
5312 return error(GL_INVALID_VALUE);
5313 }
5314
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005315 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005316
5317 if (context)
5318 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00005319 if (level > context->getMaximumTextureLevel())
5320 {
5321 return error(GL_INVALID_VALUE);
5322 }
5323
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005324 switch (target)
5325 {
5326 case GL_TEXTURE_2D:
5327 if (width > (context->getMaximumTextureDimension() >> level) ||
5328 height > (context->getMaximumTextureDimension() >> level))
5329 {
5330 return error(GL_INVALID_VALUE);
5331 }
5332 break;
5333 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5334 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5335 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5336 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5337 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5338 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5339 if (width != height)
5340 {
5341 return error(GL_INVALID_VALUE);
5342 }
5343
5344 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
5345 height > (context->getMaximumCubeTextureDimension() >> level))
5346 {
5347 return error(GL_INVALID_VALUE);
5348 }
5349 break;
5350 default:
5351 return error(GL_INVALID_ENUM);
5352 }
5353
gman@chromium.org50c526d2011-08-10 05:19:44 +00005354 switch (format) {
5355 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5356 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5357 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00005358 {
5359 return error(GL_INVALID_OPERATION);
5360 }
5361 else
5362 {
5363 return error(GL_INVALID_ENUM);
5364 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00005365 break;
5366 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5367 if (context->supportsDXT3Textures())
5368 {
5369 return error(GL_INVALID_OPERATION);
5370 }
5371 else
5372 {
5373 return error(GL_INVALID_ENUM);
5374 }
5375 break;
5376 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5377 if (context->supportsDXT5Textures())
5378 {
5379 return error(GL_INVALID_OPERATION);
5380 }
5381 else
5382 {
5383 return error(GL_INVALID_ENUM);
5384 }
5385 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005386 case GL_DEPTH_COMPONENT:
5387 case GL_DEPTH_STENCIL_OES:
5388 if (!context->supportsDepthTextures())
5389 {
5390 return error(GL_INVALID_VALUE);
5391 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005392 if (target != GL_TEXTURE_2D)
5393 {
5394 return error(GL_INVALID_OPERATION);
5395 }
daniel@transgaming.com797924b2012-06-05 19:50:01 +00005396 // OES_depth_texture supports loading depth data and multiple levels,
5397 // but ANGLE_depth_texture does not
5398 if (pixels != NULL || level != 0)
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005399 {
5400 return error(GL_INVALID_OPERATION);
5401 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005402 break;
gman@chromium.org50c526d2011-08-10 05:19:44 +00005403 default:
5404 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005405 }
5406
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005407 if (type == GL_FLOAT)
5408 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005409 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005410 {
5411 return error(GL_INVALID_ENUM);
5412 }
5413 }
5414 else if (type == GL_HALF_FLOAT_OES)
5415 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005416 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005417 {
5418 return error(GL_INVALID_ENUM);
5419 }
5420 }
5421
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005422 if (target == GL_TEXTURE_2D)
5423 {
5424 gl::Texture2D *texture = context->getTexture2D();
5425
5426 if (!texture)
5427 {
5428 return error(GL_INVALID_OPERATION);
5429 }
5430
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005431 if (texture->isImmutable())
5432 {
5433 return error(GL_INVALID_OPERATION);
5434 }
5435
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005436 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005437 }
5438 else
5439 {
5440 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5441
5442 if (!texture)
5443 {
5444 return error(GL_INVALID_OPERATION);
5445 }
5446
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005447 if (texture->isImmutable())
5448 {
5449 return error(GL_INVALID_OPERATION);
5450 }
5451
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005452 switch (target)
5453 {
5454 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005455 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005456 break;
5457 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005458 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005459 break;
5460 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005461 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005462 break;
5463 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005464 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005465 break;
5466 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005467 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005468 break;
5469 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005470 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005471 break;
5472 default: UNREACHABLE();
5473 }
5474 }
5475 }
5476 }
5477 catch(std::bad_alloc&)
5478 {
5479 return error(GL_OUT_OF_MEMORY);
5480 }
5481}
5482
5483void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5484{
5485 glTexParameteri(target, pname, (GLint)param);
5486}
5487
5488void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5489{
5490 glTexParameteri(target, pname, (GLint)*params);
5491}
5492
5493void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
5494{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005495 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005496
5497 try
5498 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005499 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005500
5501 if (context)
5502 {
5503 gl::Texture *texture;
5504
5505 switch (target)
5506 {
5507 case GL_TEXTURE_2D:
5508 texture = context->getTexture2D();
5509 break;
5510 case GL_TEXTURE_CUBE_MAP:
5511 texture = context->getTextureCubeMap();
5512 break;
5513 default:
5514 return error(GL_INVALID_ENUM);
5515 }
5516
5517 switch (pname)
5518 {
5519 case GL_TEXTURE_WRAP_S:
5520 if (!texture->setWrapS((GLenum)param))
5521 {
5522 return error(GL_INVALID_ENUM);
5523 }
5524 break;
5525 case GL_TEXTURE_WRAP_T:
5526 if (!texture->setWrapT((GLenum)param))
5527 {
5528 return error(GL_INVALID_ENUM);
5529 }
5530 break;
5531 case GL_TEXTURE_MIN_FILTER:
5532 if (!texture->setMinFilter((GLenum)param))
5533 {
5534 return error(GL_INVALID_ENUM);
5535 }
5536 break;
5537 case GL_TEXTURE_MAG_FILTER:
5538 if (!texture->setMagFilter((GLenum)param))
5539 {
5540 return error(GL_INVALID_ENUM);
5541 }
5542 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00005543 case GL_TEXTURE_USAGE_ANGLE:
5544 if (!texture->setUsage((GLenum)param))
5545 {
5546 return error(GL_INVALID_ENUM);
5547 }
5548 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005549 default:
5550 return error(GL_INVALID_ENUM);
5551 }
5552 }
5553 }
5554 catch(std::bad_alloc&)
5555 {
5556 return error(GL_OUT_OF_MEMORY);
5557 }
5558}
5559
5560void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5561{
5562 glTexParameteri(target, pname, *params);
5563}
5564
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005565void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5566{
5567 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5568 target, levels, internalformat, width, height);
5569
5570 try
5571 {
5572 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5573 {
5574 return error(GL_INVALID_ENUM);
5575 }
5576
5577 if (width < 1 || height < 1 || levels < 1)
5578 {
5579 return error(GL_INVALID_VALUE);
5580 }
5581
5582 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5583 {
5584 return error(GL_INVALID_VALUE);
5585 }
5586
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005587 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005588 {
5589 return error(GL_INVALID_OPERATION);
5590 }
5591
5592 GLenum format = gl::ExtractFormat(internalformat);
5593 GLenum type = gl::ExtractType(internalformat);
5594
5595 if (format == GL_NONE || type == GL_NONE)
5596 {
5597 return error(GL_INVALID_ENUM);
5598 }
5599
5600 gl::Context *context = gl::getNonLostContext();
5601
5602 if (context)
5603 {
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005604 switch (target)
5605 {
5606 case GL_TEXTURE_2D:
5607 if (width > context->getMaximumTextureDimension() ||
5608 height > context->getMaximumTextureDimension())
5609 {
5610 return error(GL_INVALID_VALUE);
5611 }
5612 break;
5613 case GL_TEXTURE_CUBE_MAP:
5614 if (width > context->getMaximumCubeTextureDimension() ||
5615 height > context->getMaximumCubeTextureDimension())
5616 {
5617 return error(GL_INVALID_VALUE);
5618 }
5619 break;
5620 default:
5621 return error(GL_INVALID_ENUM);
5622 }
5623
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005624 if (levels != 1 && !context->supportsNonPower2Texture())
5625 {
5626 if (!gl::isPow2(width) || !gl::isPow2(height))
5627 {
5628 return error(GL_INVALID_OPERATION);
5629 }
5630 }
5631
daniel@transgaming.come1077362011-11-11 04:16:50 +00005632 switch (internalformat)
5633 {
5634 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5635 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5636 if (!context->supportsDXT1Textures())
5637 {
5638 return error(GL_INVALID_ENUM);
5639 }
5640 break;
5641 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5642 if (!context->supportsDXT3Textures())
5643 {
5644 return error(GL_INVALID_ENUM);
5645 }
5646 break;
5647 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5648 if (!context->supportsDXT5Textures())
5649 {
5650 return error(GL_INVALID_ENUM);
5651 }
5652 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005653 case GL_RGBA32F_EXT:
5654 case GL_RGB32F_EXT:
5655 case GL_ALPHA32F_EXT:
5656 case GL_LUMINANCE32F_EXT:
5657 case GL_LUMINANCE_ALPHA32F_EXT:
5658 if (!context->supportsFloat32Textures())
5659 {
5660 return error(GL_INVALID_ENUM);
5661 }
5662 break;
5663 case GL_RGBA16F_EXT:
5664 case GL_RGB16F_EXT:
5665 case GL_ALPHA16F_EXT:
5666 case GL_LUMINANCE16F_EXT:
5667 case GL_LUMINANCE_ALPHA16F_EXT:
5668 if (!context->supportsFloat16Textures())
5669 {
5670 return error(GL_INVALID_ENUM);
5671 }
5672 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005673 case GL_DEPTH_COMPONENT16:
5674 case GL_DEPTH_COMPONENT32_OES:
5675 case GL_DEPTH24_STENCIL8_OES:
5676 if (!context->supportsDepthTextures())
5677 {
5678 return error(GL_INVALID_ENUM);
5679 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005680 if (target != GL_TEXTURE_2D)
5681 {
5682 return error(GL_INVALID_OPERATION);
5683 }
daniel@transgaming.com797924b2012-06-05 19:50:01 +00005684 // ANGLE_depth_texture only supports 1-level textures
5685 if (levels != 1)
5686 {
5687 return error(GL_INVALID_OPERATION);
5688 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005689 break;
5690 default:
5691 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005692 }
5693
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005694 if (target == GL_TEXTURE_2D)
5695 {
5696 gl::Texture2D *texture = context->getTexture2D();
5697
5698 if (!texture || texture->id() == 0)
5699 {
5700 return error(GL_INVALID_OPERATION);
5701 }
5702
5703 if (texture->isImmutable())
5704 {
5705 return error(GL_INVALID_OPERATION);
5706 }
5707
5708 texture->storage(levels, internalformat, width, height);
5709 }
5710 else if (target == GL_TEXTURE_CUBE_MAP)
5711 {
5712 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5713
5714 if (!texture || texture->id() == 0)
5715 {
5716 return error(GL_INVALID_OPERATION);
5717 }
5718
5719 if (texture->isImmutable())
5720 {
5721 return error(GL_INVALID_OPERATION);
5722 }
5723
5724 texture->storage(levels, internalformat, width);
5725 }
5726 else UNREACHABLE();
5727 }
5728 }
5729 catch(std::bad_alloc&)
5730 {
5731 return error(GL_OUT_OF_MEMORY);
5732 }
5733}
5734
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005735void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5736 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005737{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005738 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005739 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005740 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005741 target, level, xoffset, yoffset, width, height, format, type, pixels);
5742
5743 try
5744 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00005745 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005746 {
5747 return error(GL_INVALID_ENUM);
5748 }
5749
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005750 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005751 {
5752 return error(GL_INVALID_VALUE);
5753 }
5754
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005755 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5756 {
5757 return error(GL_INVALID_VALUE);
5758 }
5759
daniel@transgaming.com8833dd22012-06-05 19:49:58 +00005760 if (!checkTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005761 {
daniel@transgaming.com8833dd22012-06-05 19:49:58 +00005762 return; // error is set by helper function
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005763 }
5764
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005765 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005766
5767 if (context)
5768 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005769 if (level > context->getMaximumTextureLevel())
5770 {
5771 return error(GL_INVALID_VALUE);
5772 }
5773
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005774 if (format == GL_FLOAT)
5775 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005776 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005777 {
5778 return error(GL_INVALID_ENUM);
5779 }
5780 }
5781 else if (format == GL_HALF_FLOAT_OES)
5782 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005783 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005784 {
5785 return error(GL_INVALID_ENUM);
5786 }
5787 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005788 else if (gl::IsDepthTexture(format))
5789 {
5790 if (!context->supportsDepthTextures())
5791 {
5792 return error(GL_INVALID_ENUM);
5793 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005794 if (target != GL_TEXTURE_2D)
5795 {
5796 return error(GL_INVALID_OPERATION);
5797 }
5798 // OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not
5799 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005800 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005801
daniel@transgaming.com1d2d3c42012-05-31 01:14:15 +00005802 if (width == 0 || height == 0 || pixels == NULL)
5803 {
5804 return;
5805 }
5806
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005807 if (target == GL_TEXTURE_2D)
5808 {
5809 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00005810 if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005811 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005812 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005813 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005814 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005815 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005816 {
5817 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00005818 if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005819 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005820 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005821 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005822 }
5823 else
5824 {
5825 UNREACHABLE();
5826 }
5827 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005828 }
5829 catch(std::bad_alloc&)
5830 {
5831 return error(GL_OUT_OF_MEMORY);
5832 }
5833}
5834
5835void __stdcall glUniform1f(GLint location, GLfloat x)
5836{
5837 glUniform1fv(location, 1, &x);
5838}
5839
5840void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5841{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005842 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005843
5844 try
5845 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005846 if (count < 0)
5847 {
5848 return error(GL_INVALID_VALUE);
5849 }
5850
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005851 if (location == -1)
5852 {
5853 return;
5854 }
5855
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005856 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005857
5858 if (context)
5859 {
5860 gl::Program *program = context->getCurrentProgram();
5861
5862 if (!program)
5863 {
5864 return error(GL_INVALID_OPERATION);
5865 }
5866
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00005867 gl::ProgramBinary *programBinary = program->getProgramBinary();
5868 if (!programBinary)
5869 {
5870 return error(GL_INVALID_OPERATION);
5871 }
5872
5873 if (!programBinary->setUniform1fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005874 {
5875 return error(GL_INVALID_OPERATION);
5876 }
5877 }
5878 }
5879 catch(std::bad_alloc&)
5880 {
5881 return error(GL_OUT_OF_MEMORY);
5882 }
5883}
5884
5885void __stdcall glUniform1i(GLint location, GLint x)
5886{
5887 glUniform1iv(location, 1, &x);
5888}
5889
5890void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5891{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005892 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005893
5894 try
5895 {
5896 if (count < 0)
5897 {
5898 return error(GL_INVALID_VALUE);
5899 }
5900
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005901 if (location == -1)
5902 {
5903 return;
5904 }
5905
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005906 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005907
5908 if (context)
5909 {
5910 gl::Program *program = context->getCurrentProgram();
5911
5912 if (!program)
5913 {
5914 return error(GL_INVALID_OPERATION);
5915 }
5916
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00005917 gl::ProgramBinary *programBinary = program->getProgramBinary();
5918 if (!programBinary)
5919 {
5920 return error(GL_INVALID_OPERATION);
5921 }
5922
5923 if (!programBinary->setUniform1iv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005924 {
5925 return error(GL_INVALID_OPERATION);
5926 }
5927 }
5928 }
5929 catch(std::bad_alloc&)
5930 {
5931 return error(GL_OUT_OF_MEMORY);
5932 }
5933}
5934
5935void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5936{
5937 GLfloat xy[2] = {x, y};
5938
5939 glUniform2fv(location, 1, (GLfloat*)&xy);
5940}
5941
5942void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5943{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005944 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005945
5946 try
5947 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005948 if (count < 0)
5949 {
5950 return error(GL_INVALID_VALUE);
5951 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005952
5953 if (location == -1)
5954 {
5955 return;
5956 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005957
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005958 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005959
5960 if (context)
5961 {
5962 gl::Program *program = context->getCurrentProgram();
5963
5964 if (!program)
5965 {
5966 return error(GL_INVALID_OPERATION);
5967 }
5968
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00005969 gl::ProgramBinary *programBinary = program->getProgramBinary();
5970 if (!programBinary)
5971 {
5972 return error(GL_INVALID_OPERATION);
5973 }
5974
5975 if (!programBinary->setUniform2fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005976 {
5977 return error(GL_INVALID_OPERATION);
5978 }
5979 }
5980 }
5981 catch(std::bad_alloc&)
5982 {
5983 return error(GL_OUT_OF_MEMORY);
5984 }
5985}
5986
5987void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5988{
5989 GLint xy[4] = {x, y};
5990
5991 glUniform2iv(location, 1, (GLint*)&xy);
5992}
5993
5994void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5995{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005996 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005997
5998 try
5999 {
6000 if (count < 0)
6001 {
6002 return error(GL_INVALID_VALUE);
6003 }
6004
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006005 if (location == -1)
6006 {
6007 return;
6008 }
6009
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006010 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006011
6012 if (context)
6013 {
6014 gl::Program *program = context->getCurrentProgram();
6015
6016 if (!program)
6017 {
6018 return error(GL_INVALID_OPERATION);
6019 }
6020
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006021 gl::ProgramBinary *programBinary = program->getProgramBinary();
6022 if (!programBinary)
6023 {
6024 return error(GL_INVALID_OPERATION);
6025 }
6026
6027 if (!programBinary->setUniform2iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006028 {
6029 return error(GL_INVALID_OPERATION);
6030 }
6031 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006032 }
6033 catch(std::bad_alloc&)
6034 {
6035 return error(GL_OUT_OF_MEMORY);
6036 }
6037}
6038
6039void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
6040{
6041 GLfloat xyz[3] = {x, y, z};
6042
6043 glUniform3fv(location, 1, (GLfloat*)&xyz);
6044}
6045
6046void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
6047{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006048 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006049
6050 try
6051 {
6052 if (count < 0)
6053 {
6054 return error(GL_INVALID_VALUE);
6055 }
6056
6057 if (location == -1)
6058 {
6059 return;
6060 }
6061
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006062 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006063
6064 if (context)
6065 {
6066 gl::Program *program = context->getCurrentProgram();
6067
6068 if (!program)
6069 {
6070 return error(GL_INVALID_OPERATION);
6071 }
6072
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006073 gl::ProgramBinary *programBinary = program->getProgramBinary();
6074 if (!programBinary)
6075 {
6076 return error(GL_INVALID_OPERATION);
6077 }
6078
6079 if (!programBinary->setUniform3fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006080 {
6081 return error(GL_INVALID_OPERATION);
6082 }
6083 }
6084 }
6085 catch(std::bad_alloc&)
6086 {
6087 return error(GL_OUT_OF_MEMORY);
6088 }
6089}
6090
6091void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
6092{
6093 GLint xyz[3] = {x, y, z};
6094
6095 glUniform3iv(location, 1, (GLint*)&xyz);
6096}
6097
6098void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
6099{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006100 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006101
6102 try
6103 {
6104 if (count < 0)
6105 {
6106 return error(GL_INVALID_VALUE);
6107 }
6108
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006109 if (location == -1)
6110 {
6111 return;
6112 }
6113
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006114 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006115
6116 if (context)
6117 {
6118 gl::Program *program = context->getCurrentProgram();
6119
6120 if (!program)
6121 {
6122 return error(GL_INVALID_OPERATION);
6123 }
6124
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006125 gl::ProgramBinary *programBinary = program->getProgramBinary();
6126 if (!programBinary)
6127 {
6128 return error(GL_INVALID_OPERATION);
6129 }
6130
6131 if (!programBinary->setUniform3iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006132 {
6133 return error(GL_INVALID_OPERATION);
6134 }
6135 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006136 }
6137 catch(std::bad_alloc&)
6138 {
6139 return error(GL_OUT_OF_MEMORY);
6140 }
6141}
6142
6143void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6144{
6145 GLfloat xyzw[4] = {x, y, z, w};
6146
6147 glUniform4fv(location, 1, (GLfloat*)&xyzw);
6148}
6149
6150void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
6151{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006152 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006153
6154 try
6155 {
6156 if (count < 0)
6157 {
6158 return error(GL_INVALID_VALUE);
6159 }
6160
6161 if (location == -1)
6162 {
6163 return;
6164 }
6165
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006166 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006167
6168 if (context)
6169 {
6170 gl::Program *program = context->getCurrentProgram();
6171
6172 if (!program)
6173 {
6174 return error(GL_INVALID_OPERATION);
6175 }
6176
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006177 gl::ProgramBinary *programBinary = program->getProgramBinary();
6178 if (!programBinary)
6179 {
6180 return error(GL_INVALID_OPERATION);
6181 }
6182
6183 if (!programBinary->setUniform4fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006184 {
6185 return error(GL_INVALID_OPERATION);
6186 }
6187 }
6188 }
6189 catch(std::bad_alloc&)
6190 {
6191 return error(GL_OUT_OF_MEMORY);
6192 }
6193}
6194
6195void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
6196{
6197 GLint xyzw[4] = {x, y, z, w};
6198
6199 glUniform4iv(location, 1, (GLint*)&xyzw);
6200}
6201
6202void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
6203{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006204 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006205
6206 try
6207 {
6208 if (count < 0)
6209 {
6210 return error(GL_INVALID_VALUE);
6211 }
6212
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006213 if (location == -1)
6214 {
6215 return;
6216 }
6217
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006218 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006219
6220 if (context)
6221 {
6222 gl::Program *program = context->getCurrentProgram();
6223
6224 if (!program)
6225 {
6226 return error(GL_INVALID_OPERATION);
6227 }
6228
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006229 gl::ProgramBinary *programBinary = program->getProgramBinary();
6230 if (!programBinary)
6231 {
6232 return error(GL_INVALID_OPERATION);
6233 }
6234
6235 if (!programBinary->setUniform4iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006236 {
6237 return error(GL_INVALID_OPERATION);
6238 }
6239 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006240 }
6241 catch(std::bad_alloc&)
6242 {
6243 return error(GL_OUT_OF_MEMORY);
6244 }
6245}
6246
6247void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6248{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006249 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006250 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006251
6252 try
6253 {
6254 if (count < 0 || transpose != GL_FALSE)
6255 {
6256 return error(GL_INVALID_VALUE);
6257 }
6258
6259 if (location == -1)
6260 {
6261 return;
6262 }
6263
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006264 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006265
6266 if (context)
6267 {
6268 gl::Program *program = context->getCurrentProgram();
6269
6270 if (!program)
6271 {
6272 return error(GL_INVALID_OPERATION);
6273 }
6274
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006275 gl::ProgramBinary *programBinary = program->getProgramBinary();
6276 if (!programBinary)
6277 {
6278 return error(GL_INVALID_OPERATION);
6279 }
6280
6281 if (!programBinary->setUniformMatrix2fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006282 {
6283 return error(GL_INVALID_OPERATION);
6284 }
6285 }
6286 }
6287 catch(std::bad_alloc&)
6288 {
6289 return error(GL_OUT_OF_MEMORY);
6290 }
6291}
6292
6293void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6294{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006295 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006296 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006297
6298 try
6299 {
6300 if (count < 0 || transpose != GL_FALSE)
6301 {
6302 return error(GL_INVALID_VALUE);
6303 }
6304
6305 if (location == -1)
6306 {
6307 return;
6308 }
6309
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006310 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006311
6312 if (context)
6313 {
6314 gl::Program *program = context->getCurrentProgram();
6315
6316 if (!program)
6317 {
6318 return error(GL_INVALID_OPERATION);
6319 }
6320
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006321 gl::ProgramBinary *programBinary = program->getProgramBinary();
6322 if (!programBinary)
6323 {
6324 return error(GL_INVALID_OPERATION);
6325 }
6326
6327 if (!programBinary->setUniformMatrix3fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006328 {
6329 return error(GL_INVALID_OPERATION);
6330 }
6331 }
6332 }
6333 catch(std::bad_alloc&)
6334 {
6335 return error(GL_OUT_OF_MEMORY);
6336 }
6337}
6338
6339void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6340{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006341 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006342 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006343
6344 try
6345 {
6346 if (count < 0 || transpose != GL_FALSE)
6347 {
6348 return error(GL_INVALID_VALUE);
6349 }
6350
6351 if (location == -1)
6352 {
6353 return;
6354 }
6355
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006356 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006357
6358 if (context)
6359 {
6360 gl::Program *program = context->getCurrentProgram();
6361
6362 if (!program)
6363 {
6364 return error(GL_INVALID_OPERATION);
6365 }
6366
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006367 gl::ProgramBinary *programBinary = program->getProgramBinary();
6368 if (!programBinary)
6369 {
6370 return error(GL_INVALID_OPERATION);
6371 }
6372
6373 if (!programBinary->setUniformMatrix4fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006374 {
6375 return error(GL_INVALID_OPERATION);
6376 }
6377 }
6378 }
6379 catch(std::bad_alloc&)
6380 {
6381 return error(GL_OUT_OF_MEMORY);
6382 }
6383}
6384
6385void __stdcall glUseProgram(GLuint program)
6386{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006387 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006388
6389 try
6390 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006391 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006392
6393 if (context)
6394 {
6395 gl::Program *programObject = context->getProgram(program);
6396
daniel@transgaming.comc8478202010-04-13 19:53:35 +00006397 if (!programObject && program != 0)
6398 {
6399 if (context->getShader(program))
6400 {
6401 return error(GL_INVALID_OPERATION);
6402 }
6403 else
6404 {
6405 return error(GL_INVALID_VALUE);
6406 }
6407 }
6408
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006409 if (program != 0 && !programObject->getProgramBinary())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006410 {
6411 return error(GL_INVALID_OPERATION);
6412 }
6413
6414 context->useProgram(program);
6415 }
6416 }
6417 catch(std::bad_alloc&)
6418 {
6419 return error(GL_OUT_OF_MEMORY);
6420 }
6421}
6422
6423void __stdcall glValidateProgram(GLuint program)
6424{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006425 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006426
6427 try
6428 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006429 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006430
6431 if (context)
6432 {
6433 gl::Program *programObject = context->getProgram(program);
6434
6435 if (!programObject)
6436 {
6437 if (context->getShader(program))
6438 {
6439 return error(GL_INVALID_OPERATION);
6440 }
6441 else
6442 {
6443 return error(GL_INVALID_VALUE);
6444 }
6445 }
6446
apatrick@chromium.org253b8d22012-06-22 19:27:21 +00006447 programObject->validate();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006448 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006449 }
6450 catch(std::bad_alloc&)
6451 {
6452 return error(GL_OUT_OF_MEMORY);
6453 }
6454}
6455
6456void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
6457{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006458 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006459
6460 try
6461 {
6462 if (index >= gl::MAX_VERTEX_ATTRIBS)
6463 {
6464 return error(GL_INVALID_VALUE);
6465 }
6466
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006467 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006468
6469 if (context)
6470 {
6471 GLfloat vals[4] = { x, 0, 0, 1 };
6472 context->setVertexAttrib(index, vals);
6473 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006474 }
6475 catch(std::bad_alloc&)
6476 {
6477 return error(GL_OUT_OF_MEMORY);
6478 }
6479}
6480
6481void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
6482{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006483 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006484
6485 try
6486 {
6487 if (index >= gl::MAX_VERTEX_ATTRIBS)
6488 {
6489 return error(GL_INVALID_VALUE);
6490 }
6491
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006492 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006493
6494 if (context)
6495 {
6496 GLfloat vals[4] = { values[0], 0, 0, 1 };
6497 context->setVertexAttrib(index, vals);
6498 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006499 }
6500 catch(std::bad_alloc&)
6501 {
6502 return error(GL_OUT_OF_MEMORY);
6503 }
6504}
6505
6506void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6507{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006508 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006509
6510 try
6511 {
6512 if (index >= gl::MAX_VERTEX_ATTRIBS)
6513 {
6514 return error(GL_INVALID_VALUE);
6515 }
6516
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006517 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006518
6519 if (context)
6520 {
6521 GLfloat vals[4] = { x, y, 0, 1 };
6522 context->setVertexAttrib(index, vals);
6523 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006524 }
6525 catch(std::bad_alloc&)
6526 {
6527 return error(GL_OUT_OF_MEMORY);
6528 }
6529}
6530
6531void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
6532{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006533 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006534
6535 try
6536 {
6537 if (index >= gl::MAX_VERTEX_ATTRIBS)
6538 {
6539 return error(GL_INVALID_VALUE);
6540 }
6541
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006542 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006543
6544 if (context)
6545 {
6546 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6547 context->setVertexAttrib(index, vals);
6548 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006549 }
6550 catch(std::bad_alloc&)
6551 {
6552 return error(GL_OUT_OF_MEMORY);
6553 }
6554}
6555
6556void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6557{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006558 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 +00006559
6560 try
6561 {
6562 if (index >= gl::MAX_VERTEX_ATTRIBS)
6563 {
6564 return error(GL_INVALID_VALUE);
6565 }
6566
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006567 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006568
6569 if (context)
6570 {
6571 GLfloat vals[4] = { x, y, z, 1 };
6572 context->setVertexAttrib(index, vals);
6573 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006574 }
6575 catch(std::bad_alloc&)
6576 {
6577 return error(GL_OUT_OF_MEMORY);
6578 }
6579}
6580
6581void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
6582{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006583 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006584
6585 try
6586 {
6587 if (index >= gl::MAX_VERTEX_ATTRIBS)
6588 {
6589 return error(GL_INVALID_VALUE);
6590 }
6591
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006592 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006593
6594 if (context)
6595 {
6596 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6597 context->setVertexAttrib(index, vals);
6598 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006599 }
6600 catch(std::bad_alloc&)
6601 {
6602 return error(GL_OUT_OF_MEMORY);
6603 }
6604}
6605
6606void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6607{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006608 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 +00006609
6610 try
6611 {
6612 if (index >= gl::MAX_VERTEX_ATTRIBS)
6613 {
6614 return error(GL_INVALID_VALUE);
6615 }
6616
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006617 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006618
6619 if (context)
6620 {
6621 GLfloat vals[4] = { x, y, z, w };
6622 context->setVertexAttrib(index, vals);
6623 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006624 }
6625 catch(std::bad_alloc&)
6626 {
6627 return error(GL_OUT_OF_MEMORY);
6628 }
6629}
6630
6631void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
6632{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006633 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006634
6635 try
6636 {
6637 if (index >= gl::MAX_VERTEX_ATTRIBS)
6638 {
6639 return error(GL_INVALID_VALUE);
6640 }
6641
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006642 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006643
6644 if (context)
6645 {
6646 context->setVertexAttrib(index, values);
6647 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006648 }
6649 catch(std::bad_alloc&)
6650 {
6651 return error(GL_OUT_OF_MEMORY);
6652 }
6653}
6654
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00006655void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
6656{
6657 EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
6658
6659 try
6660 {
6661 if (index >= gl::MAX_VERTEX_ATTRIBS)
6662 {
6663 return error(GL_INVALID_VALUE);
6664 }
6665
6666 gl::Context *context = gl::getNonLostContext();
6667
6668 if (context)
6669 {
6670 context->setVertexAttribDivisor(index, divisor);
6671 }
6672 }
6673 catch(std::bad_alloc&)
6674 {
6675 return error(GL_OUT_OF_MEMORY);
6676 }
6677}
6678
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006679void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006680{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006681 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006682 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006683 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006684
6685 try
6686 {
6687 if (index >= gl::MAX_VERTEX_ATTRIBS)
6688 {
6689 return error(GL_INVALID_VALUE);
6690 }
6691
6692 if (size < 1 || size > 4)
6693 {
6694 return error(GL_INVALID_VALUE);
6695 }
6696
6697 switch (type)
6698 {
6699 case GL_BYTE:
6700 case GL_UNSIGNED_BYTE:
6701 case GL_SHORT:
6702 case GL_UNSIGNED_SHORT:
6703 case GL_FIXED:
6704 case GL_FLOAT:
6705 break;
6706 default:
6707 return error(GL_INVALID_ENUM);
6708 }
6709
6710 if (stride < 0)
6711 {
6712 return error(GL_INVALID_VALUE);
6713 }
6714
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006715 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006716
6717 if (context)
6718 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006719 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006720 }
6721 }
6722 catch(std::bad_alloc&)
6723 {
6724 return error(GL_OUT_OF_MEMORY);
6725 }
6726}
6727
6728void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6729{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006730 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 +00006731
6732 try
6733 {
6734 if (width < 0 || height < 0)
6735 {
6736 return error(GL_INVALID_VALUE);
6737 }
6738
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006739 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006740
6741 if (context)
6742 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006743 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006744 }
6745 }
6746 catch(std::bad_alloc&)
6747 {
6748 return error(GL_OUT_OF_MEMORY);
6749 }
6750}
6751
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006752void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6753 GLbitfield mask, GLenum filter)
6754{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006755 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006756 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6757 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6758 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6759
6760 try
6761 {
6762 switch (filter)
6763 {
6764 case GL_NEAREST:
6765 break;
6766 default:
6767 return error(GL_INVALID_ENUM);
6768 }
6769
6770 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6771 {
6772 return error(GL_INVALID_VALUE);
6773 }
6774
6775 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6776 {
6777 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6778 return error(GL_INVALID_OPERATION);
6779 }
6780
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006781 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006782
6783 if (context)
6784 {
6785 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6786 {
6787 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6788 return error(GL_INVALID_OPERATION);
6789 }
6790
6791 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6792 }
6793 }
6794 catch(std::bad_alloc&)
6795 {
6796 return error(GL_OUT_OF_MEMORY);
6797 }
6798}
6799
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006800void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6801 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006802{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006803 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006804 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006805 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006806 target, level, internalformat, width, height, depth, border, format, type, pixels);
6807
6808 try
6809 {
6810 UNIMPLEMENTED(); // FIXME
6811 }
6812 catch(std::bad_alloc&)
6813 {
6814 return error(GL_OUT_OF_MEMORY);
6815 }
6816}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006817
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006818void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length,
6819 GLenum *binaryFormat, void *binary)
6820{
6821 EVENT("(GLenum program = 0x%X, bufSize = %s, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)",
6822 program, bufSize, length, binaryFormat, binary);
6823
6824 try
6825 {
6826 gl::Context *context = gl::getNonLostContext();
6827
6828 if (context)
6829 {
6830 gl::Program *programObject = context->getProgram(program);
6831
6832 if (!programObject)
6833 {
6834 return error(GL_INVALID_OPERATION);
6835 }
6836
6837 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
6838
6839 if (!programBinary)
6840 {
6841 return error(GL_INVALID_OPERATION);
6842 }
6843
6844 *binaryFormat = GL_PROGRAM_BINARY_ANGLE;
6845
6846 if (length)
6847 {
6848 *length = 0;
6849 }
6850 }
6851 }
6852 catch(std::bad_alloc&)
6853 {
6854 return error(GL_OUT_OF_MEMORY);
6855 }
6856}
6857
6858void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat,
6859 const void *binary, GLint length)
6860{
6861 EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)",
6862 program, binaryFormat, binary, length);
6863
6864 try
6865 {
6866 gl::Context *context = gl::getNonLostContext();
6867
6868 if (context)
6869 {
6870 if (binaryFormat != GL_PROGRAM_BINARY_ANGLE)
6871 {
6872 return error(GL_INVALID_ENUM);
6873 }
6874
6875 gl::Program *programObject = context->getProgram(program);
6876
6877 if (!programObject)
6878 {
6879 return error(GL_INVALID_OPERATION);
6880 }
6881
6882 programObject->setProgramBinary(NULL);
6883 }
6884 }
6885 catch(std::bad_alloc&)
6886 {
6887 return error(GL_OUT_OF_MEMORY);
6888 }
6889}
6890
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006891__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6892{
6893 struct Extension
6894 {
6895 const char *name;
6896 __eglMustCastToProperFunctionPointerType address;
6897 };
6898
6899 static const Extension glExtensions[] =
6900 {
6901 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006902 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006903 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006904 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6905 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6906 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6907 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6908 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6909 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6910 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006911 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006912 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006913 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6914 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6915 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6916 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00006917 {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT},
6918 {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT},
6919 {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT},
6920 {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT},
6921 {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
6922 {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
6923 {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
daniel@transgaming.comdce02fd2012-01-27 15:39:51 +00006924 {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE},
6925 {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE},
6926 {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE},
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006927 {"glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glGetProgramBinaryOES},
6928 {"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES}, };
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006929
6930 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6931 {
6932 if (strcmp(procname, glExtensions[ext].name) == 0)
6933 {
6934 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6935 }
6936 }
6937
6938 return NULL;
6939}
6940
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006941// Non-public functions used by EGL
6942
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006943bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006944{
6945 EVENT("(egl::Surface* surface = 0x%0.8p)",
6946 surface);
6947
6948 try
6949 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006950 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006951
6952 if (context)
6953 {
6954 gl::Texture2D *textureObject = context->getTexture2D();
6955
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006956 if (textureObject->isImmutable())
6957 {
6958 return false;
6959 }
6960
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006961 if (textureObject)
6962 {
6963 textureObject->bindTexImage(surface);
6964 }
6965 }
6966 }
6967 catch(std::bad_alloc&)
6968 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006969 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006970 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006971
6972 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006973}
6974
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006975}