blob: bd000ecb15edf5f40f23cbcf9ed5e4cf264e2e8b [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +00002// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +000017#include "common/version.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000018
19#include "libGLESv2/main.h"
20#include "libGLESv2/mathutil.h"
21#include "libGLESv2/utilities.h"
22#include "libGLESv2/Buffer.h"
23#include "libGLESv2/Context.h"
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000024#include "libGLESv2/Fence.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000025#include "libGLESv2/Framebuffer.h"
26#include "libGLESv2/Program.h"
27#include "libGLESv2/Renderbuffer.h"
28#include "libGLESv2/Shader.h"
29#include "libGLESv2/Texture.h"
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000030#include "libGLESv2/Query.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000031
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +000032bool validImageSize(GLint level, GLsizei width, GLsizei height)
33{
34 if (level < 0 || width < 0 || height < 0)
35 {
36 return false;
37 }
38
39 if (gl::getContext() && gl::getContext()->supportsNonPower2Texture())
40 {
41 return true;
42 }
43
44 if (level == 0)
45 {
46 return true;
47 }
48
49 if (gl::isPow2(width) && gl::isPow2(height))
50 {
51 return true;
52 }
53
54 return false;
55}
56
daniel@transgaming.com343373a2011-11-29 19:42:32 +000057bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLint level, GLenum format, gl::Texture *texture)
58{
59 if (!texture)
60 {
61 return error(GL_INVALID_OPERATION, false);
62 }
63
64 if (compressed != texture->isCompressed())
65 {
66 return error(GL_INVALID_OPERATION, false);
67 }
68
69 if (format != GL_NONE && format != texture->getInternalFormat())
70 {
71 return error(GL_INVALID_OPERATION, false);
72 }
73
74 if (compressed)
75 {
76 if ((width % 4 != 0 && width != texture->getWidth(0)) ||
77 (height % 4 != 0 && height != texture->getHeight(0)))
78 {
79 return error(GL_INVALID_OPERATION, false);
80 }
81 }
82
83 if (xoffset + width > texture->getWidth(level) ||
84 yoffset + height > texture->getHeight(level))
85 {
86 return error(GL_INVALID_VALUE, false);
87 }
88
89 return true;
90}
91
daniel@transgaming.comb7915a52011-11-12 03:14:20 +000092// check for combinations of format and type that are valid for ReadPixels
93bool validReadFormatType(GLenum format, GLenum type)
94{
95 switch (format)
96 {
97 case GL_RGBA:
98 switch (type)
99 {
100 case GL_UNSIGNED_BYTE:
101 break;
102 default:
103 return false;
104 }
105 break;
106 case GL_BGRA_EXT:
107 switch (type)
108 {
109 case GL_UNSIGNED_BYTE:
110 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
111 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
112 break;
113 default:
114 return false;
115 }
116 break;
117 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
118 switch (type)
119 {
120 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
121 break;
122 default:
123 return false;
124 }
125 break;
126 default:
127 return false;
128 }
129 return true;
130}
131
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000132extern "C"
133{
134
135void __stdcall glActiveTexture(GLenum texture)
136{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000137 EVENT("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000138
139 try
140 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000141 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000142
143 if (context)
144 {
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +0000145 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
146 {
147 return error(GL_INVALID_ENUM);
148 }
149
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000150 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000151 }
152 }
153 catch(std::bad_alloc&)
154 {
155 return error(GL_OUT_OF_MEMORY);
156 }
157}
158
159void __stdcall glAttachShader(GLuint program, GLuint shader)
160{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000161 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000162
163 try
164 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000165 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000166
167 if (context)
168 {
169 gl::Program *programObject = context->getProgram(program);
170 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000171
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000172 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000173 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000174 if (context->getShader(program))
175 {
176 return error(GL_INVALID_OPERATION);
177 }
178 else
179 {
180 return error(GL_INVALID_VALUE);
181 }
182 }
183
184 if (!shaderObject)
185 {
186 if (context->getProgram(shader))
187 {
188 return error(GL_INVALID_OPERATION);
189 }
190 else
191 {
192 return error(GL_INVALID_VALUE);
193 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000194 }
195
196 if (!programObject->attachShader(shaderObject))
197 {
198 return error(GL_INVALID_OPERATION);
199 }
200 }
201 }
202 catch(std::bad_alloc&)
203 {
204 return error(GL_OUT_OF_MEMORY);
205 }
206}
207
daniel@transgaming.com86bdb822012-01-20 18:24:39 +0000208void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
209{
210 EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
211
212 try
213 {
214 switch (target)
215 {
216 case GL_ANY_SAMPLES_PASSED_EXT:
217 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
218 break;
219 default:
220 return error(GL_INVALID_ENUM);
221 }
222
223 if (id == 0)
224 {
225 return error(GL_INVALID_OPERATION);
226 }
227
228 gl::Context *context = gl::getNonLostContext();
229
230 if (context)
231 {
232 context->beginQuery(target, id);
233 }
234 }
235 catch(std::bad_alloc&)
236 {
237 return error(GL_OUT_OF_MEMORY);
238 }
239}
240
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000241void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000242{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000243 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000244
245 try
246 {
247 if (index >= gl::MAX_VERTEX_ATTRIBS)
248 {
249 return error(GL_INVALID_VALUE);
250 }
251
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000252 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000253
254 if (context)
255 {
256 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000257
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000258 if (!programObject)
259 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000260 if (context->getShader(program))
261 {
262 return error(GL_INVALID_OPERATION);
263 }
264 else
265 {
266 return error(GL_INVALID_VALUE);
267 }
268 }
269
270 if (strncmp(name, "gl_", 3) == 0)
271 {
272 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000273 }
274
275 programObject->bindAttributeLocation(index, name);
276 }
277 }
278 catch(std::bad_alloc&)
279 {
280 return error(GL_OUT_OF_MEMORY);
281 }
282}
283
284void __stdcall glBindBuffer(GLenum target, GLuint buffer)
285{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000286 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000287
288 try
289 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000290 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000291
292 if (context)
293 {
294 switch (target)
295 {
296 case GL_ARRAY_BUFFER:
297 context->bindArrayBuffer(buffer);
298 return;
299 case GL_ELEMENT_ARRAY_BUFFER:
300 context->bindElementArrayBuffer(buffer);
301 return;
302 default:
303 return error(GL_INVALID_ENUM);
304 }
305 }
306 }
307 catch(std::bad_alloc&)
308 {
309 return error(GL_OUT_OF_MEMORY);
310 }
311}
312
313void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
314{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000315 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000316
317 try
318 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000319 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000320 {
321 return error(GL_INVALID_ENUM);
322 }
323
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000324 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000325
326 if (context)
327 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000328 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
329 {
330 context->bindReadFramebuffer(framebuffer);
331 }
332
333 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
334 {
335 context->bindDrawFramebuffer(framebuffer);
336 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000337 }
338 }
339 catch(std::bad_alloc&)
340 {
341 return error(GL_OUT_OF_MEMORY);
342 }
343}
344
345void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
346{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000347 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000348
349 try
350 {
351 if (target != GL_RENDERBUFFER)
352 {
353 return error(GL_INVALID_ENUM);
354 }
355
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000356 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000357
358 if (context)
359 {
360 context->bindRenderbuffer(renderbuffer);
361 }
362 }
363 catch(std::bad_alloc&)
364 {
365 return error(GL_OUT_OF_MEMORY);
366 }
367}
368
369void __stdcall glBindTexture(GLenum target, GLuint texture)
370{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000371 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000372
373 try
374 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000375 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000376
377 if (context)
378 {
379 gl::Texture *textureObject = context->getTexture(texture);
380
381 if (textureObject && textureObject->getTarget() != target && texture != 0)
382 {
383 return error(GL_INVALID_OPERATION);
384 }
385
386 switch (target)
387 {
388 case GL_TEXTURE_2D:
389 context->bindTexture2D(texture);
390 return;
391 case GL_TEXTURE_CUBE_MAP:
392 context->bindTextureCubeMap(texture);
393 return;
394 default:
395 return error(GL_INVALID_ENUM);
396 }
397 }
398 }
399 catch(std::bad_alloc&)
400 {
401 return error(GL_OUT_OF_MEMORY);
402 }
403}
404
405void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
406{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000407 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000408 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000409
410 try
411 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000412 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000413
414 if (context)
415 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000416 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000417 }
418 }
419 catch(std::bad_alloc&)
420 {
421 return error(GL_OUT_OF_MEMORY);
422 }
423}
424
425void __stdcall glBlendEquation(GLenum mode)
426{
427 glBlendEquationSeparate(mode, mode);
428}
429
430void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
431{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000432 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000433
434 try
435 {
436 switch (modeRGB)
437 {
438 case GL_FUNC_ADD:
439 case GL_FUNC_SUBTRACT:
440 case GL_FUNC_REVERSE_SUBTRACT:
441 break;
442 default:
443 return error(GL_INVALID_ENUM);
444 }
445
446 switch (modeAlpha)
447 {
448 case GL_FUNC_ADD:
449 case GL_FUNC_SUBTRACT:
450 case GL_FUNC_REVERSE_SUBTRACT:
451 break;
452 default:
453 return error(GL_INVALID_ENUM);
454 }
455
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000456 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000457
458 if (context)
459 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000460 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000461 }
462 }
463 catch(std::bad_alloc&)
464 {
465 return error(GL_OUT_OF_MEMORY);
466 }
467}
468
469void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
470{
471 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
472}
473
474void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
475{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000476 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 +0000477 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000478
479 try
480 {
481 switch (srcRGB)
482 {
483 case GL_ZERO:
484 case GL_ONE:
485 case GL_SRC_COLOR:
486 case GL_ONE_MINUS_SRC_COLOR:
487 case GL_DST_COLOR:
488 case GL_ONE_MINUS_DST_COLOR:
489 case GL_SRC_ALPHA:
490 case GL_ONE_MINUS_SRC_ALPHA:
491 case GL_DST_ALPHA:
492 case GL_ONE_MINUS_DST_ALPHA:
493 case GL_CONSTANT_COLOR:
494 case GL_ONE_MINUS_CONSTANT_COLOR:
495 case GL_CONSTANT_ALPHA:
496 case GL_ONE_MINUS_CONSTANT_ALPHA:
497 case GL_SRC_ALPHA_SATURATE:
498 break;
499 default:
500 return error(GL_INVALID_ENUM);
501 }
502
503 switch (dstRGB)
504 {
505 case GL_ZERO:
506 case GL_ONE:
507 case GL_SRC_COLOR:
508 case GL_ONE_MINUS_SRC_COLOR:
509 case GL_DST_COLOR:
510 case GL_ONE_MINUS_DST_COLOR:
511 case GL_SRC_ALPHA:
512 case GL_ONE_MINUS_SRC_ALPHA:
513 case GL_DST_ALPHA:
514 case GL_ONE_MINUS_DST_ALPHA:
515 case GL_CONSTANT_COLOR:
516 case GL_ONE_MINUS_CONSTANT_COLOR:
517 case GL_CONSTANT_ALPHA:
518 case GL_ONE_MINUS_CONSTANT_ALPHA:
519 break;
520 default:
521 return error(GL_INVALID_ENUM);
522 }
523
524 switch (srcAlpha)
525 {
526 case GL_ZERO:
527 case GL_ONE:
528 case GL_SRC_COLOR:
529 case GL_ONE_MINUS_SRC_COLOR:
530 case GL_DST_COLOR:
531 case GL_ONE_MINUS_DST_COLOR:
532 case GL_SRC_ALPHA:
533 case GL_ONE_MINUS_SRC_ALPHA:
534 case GL_DST_ALPHA:
535 case GL_ONE_MINUS_DST_ALPHA:
536 case GL_CONSTANT_COLOR:
537 case GL_ONE_MINUS_CONSTANT_COLOR:
538 case GL_CONSTANT_ALPHA:
539 case GL_ONE_MINUS_CONSTANT_ALPHA:
540 case GL_SRC_ALPHA_SATURATE:
541 break;
542 default:
543 return error(GL_INVALID_ENUM);
544 }
545
546 switch (dstAlpha)
547 {
548 case GL_ZERO:
549 case GL_ONE:
550 case GL_SRC_COLOR:
551 case GL_ONE_MINUS_SRC_COLOR:
552 case GL_DST_COLOR:
553 case GL_ONE_MINUS_DST_COLOR:
554 case GL_SRC_ALPHA:
555 case GL_ONE_MINUS_SRC_ALPHA:
556 case GL_DST_ALPHA:
557 case GL_ONE_MINUS_DST_ALPHA:
558 case GL_CONSTANT_COLOR:
559 case GL_ONE_MINUS_CONSTANT_COLOR:
560 case GL_CONSTANT_ALPHA:
561 case GL_ONE_MINUS_CONSTANT_ALPHA:
562 break;
563 default:
564 return error(GL_INVALID_ENUM);
565 }
566
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000567 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
568 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
569
570 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
571 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
572
573 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000574 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000575 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
576 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000577 }
578
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000579 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000580
581 if (context)
582 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000583 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000584 }
585 }
586 catch(std::bad_alloc&)
587 {
588 return error(GL_OUT_OF_MEMORY);
589 }
590}
591
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000592void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000593{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000594 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 +0000595 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000596
597 try
598 {
599 if (size < 0)
600 {
601 return error(GL_INVALID_VALUE);
602 }
603
604 switch (usage)
605 {
606 case GL_STREAM_DRAW:
607 case GL_STATIC_DRAW:
608 case GL_DYNAMIC_DRAW:
609 break;
610 default:
611 return error(GL_INVALID_ENUM);
612 }
613
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000614 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000615
616 if (context)
617 {
618 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000619
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000620 switch (target)
621 {
622 case GL_ARRAY_BUFFER:
623 buffer = context->getArrayBuffer();
624 break;
625 case GL_ELEMENT_ARRAY_BUFFER:
626 buffer = context->getElementArrayBuffer();
627 break;
628 default:
629 return error(GL_INVALID_ENUM);
630 }
631
632 if (!buffer)
633 {
634 return error(GL_INVALID_OPERATION);
635 }
636
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000637 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000638 }
639 }
640 catch(std::bad_alloc&)
641 {
642 return error(GL_OUT_OF_MEMORY);
643 }
644}
645
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000646void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000647{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000648 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 +0000649 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000650
651 try
652 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000653 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000654 {
655 return error(GL_INVALID_VALUE);
656 }
657
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000658 if (data == NULL)
659 {
660 return;
661 }
662
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000663 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000664
665 if (context)
666 {
667 gl::Buffer *buffer;
668
669 switch (target)
670 {
671 case GL_ARRAY_BUFFER:
672 buffer = context->getArrayBuffer();
673 break;
674 case GL_ELEMENT_ARRAY_BUFFER:
675 buffer = context->getElementArrayBuffer();
676 break;
677 default:
678 return error(GL_INVALID_ENUM);
679 }
680
681 if (!buffer)
682 {
683 return error(GL_INVALID_OPERATION);
684 }
685
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000686 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000687 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000688 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000689 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000690
691 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000692 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000693 }
694 catch(std::bad_alloc&)
695 {
696 return error(GL_OUT_OF_MEMORY);
697 }
698}
699
700GLenum __stdcall glCheckFramebufferStatus(GLenum target)
701{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000702 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000703
704 try
705 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000706 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000707 {
708 return error(GL_INVALID_ENUM, 0);
709 }
710
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000711 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000712
713 if (context)
714 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000715 gl::Framebuffer *framebuffer = NULL;
716 if (target == GL_READ_FRAMEBUFFER_ANGLE)
717 {
718 framebuffer = context->getReadFramebuffer();
719 }
720 else
721 {
722 framebuffer = context->getDrawFramebuffer();
723 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000724
725 return framebuffer->completeness();
726 }
727 }
728 catch(std::bad_alloc&)
729 {
730 return error(GL_OUT_OF_MEMORY, 0);
731 }
732
733 return 0;
734}
735
736void __stdcall glClear(GLbitfield mask)
737{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000738 EVENT("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000739
740 try
741 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000742 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000743
744 if (context)
745 {
746 context->clear(mask);
747 }
748 }
749 catch(std::bad_alloc&)
750 {
751 return error(GL_OUT_OF_MEMORY);
752 }
753}
754
755void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
756{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000757 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000758 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000759
760 try
761 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000762 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000763
764 if (context)
765 {
766 context->setClearColor(red, green, blue, alpha);
767 }
768 }
769 catch(std::bad_alloc&)
770 {
771 return error(GL_OUT_OF_MEMORY);
772 }
773}
774
775void __stdcall glClearDepthf(GLclampf depth)
776{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000777 EVENT("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000778
779 try
780 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000781 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000782
783 if (context)
784 {
785 context->setClearDepth(depth);
786 }
787 }
788 catch(std::bad_alloc&)
789 {
790 return error(GL_OUT_OF_MEMORY);
791 }
792}
793
794void __stdcall glClearStencil(GLint s)
795{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000796 EVENT("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000797
798 try
799 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000800 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000801
802 if (context)
803 {
804 context->setClearStencil(s);
805 }
806 }
807 catch(std::bad_alloc&)
808 {
809 return error(GL_OUT_OF_MEMORY);
810 }
811}
812
813void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
814{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000815 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000816 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000817
818 try
819 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000820 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000821
822 if (context)
823 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000824 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000825 }
826 }
827 catch(std::bad_alloc&)
828 {
829 return error(GL_OUT_OF_MEMORY);
830 }
831}
832
833void __stdcall glCompileShader(GLuint shader)
834{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000835 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000836
837 try
838 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000839 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000840
841 if (context)
842 {
843 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000844
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000845 if (!shaderObject)
846 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000847 if (context->getProgram(shader))
848 {
849 return error(GL_INVALID_OPERATION);
850 }
851 else
852 {
853 return error(GL_INVALID_VALUE);
854 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000855 }
856
857 shaderObject->compile();
858 }
859 }
860 catch(std::bad_alloc&)
861 {
862 return error(GL_OUT_OF_MEMORY);
863 }
864}
865
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000866void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
867 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000868{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000869 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000870 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000871 target, level, internalformat, width, height, border, imageSize, data);
872
873 try
874 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000875 if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000876 {
877 return error(GL_INVALID_VALUE);
878 }
879
daniel@transgaming.com01868132010-08-24 19:21:17 +0000880 switch (internalformat)
881 {
882 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
883 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +0000884 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
885 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +0000886 break;
887 default:
888 return error(GL_INVALID_ENUM);
889 }
890
891 if (border != 0)
892 {
893 return error(GL_INVALID_VALUE);
894 }
895
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000896 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000897
898 if (context)
899 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000900 if (level > context->getMaximumTextureLevel())
901 {
902 return error(GL_INVALID_VALUE);
903 }
904
905 switch (target)
906 {
907 case GL_TEXTURE_2D:
908 if (width > (context->getMaximumTextureDimension() >> level) ||
909 height > (context->getMaximumTextureDimension() >> level))
910 {
911 return error(GL_INVALID_VALUE);
912 }
913 break;
914 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
915 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
916 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
917 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
918 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
919 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
920 if (width != height)
921 {
922 return error(GL_INVALID_VALUE);
923 }
924
925 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
926 height > (context->getMaximumCubeTextureDimension() >> level))
927 {
928 return error(GL_INVALID_VALUE);
929 }
930 break;
931 default:
932 return error(GL_INVALID_ENUM);
933 }
934
gman@chromium.org50c526d2011-08-10 05:19:44 +0000935 switch (internalformat) {
936 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
937 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
938 if (!context->supportsDXT1Textures())
939 {
940 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
941 }
942 break;
943 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
944 if (!context->supportsDXT3Textures())
945 {
946 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
947 }
948 break;
949 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
950 if (!context->supportsDXT5Textures())
951 {
952 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
953 }
954 break;
955 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000956 }
957
958 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
959 {
960 return error(GL_INVALID_VALUE);
961 }
962
963 if (target == GL_TEXTURE_2D)
964 {
965 gl::Texture2D *texture = context->getTexture2D();
966
967 if (!texture)
968 {
969 return error(GL_INVALID_OPERATION);
970 }
971
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +0000972 if (texture->isImmutable())
973 {
974 return error(GL_INVALID_OPERATION);
975 }
976
daniel@transgaming.com01868132010-08-24 19:21:17 +0000977 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
978 }
979 else
980 {
981 gl::TextureCubeMap *texture = context->getTextureCubeMap();
982
983 if (!texture)
984 {
985 return error(GL_INVALID_OPERATION);
986 }
987
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +0000988 if (texture->isImmutable())
989 {
990 return error(GL_INVALID_OPERATION);
991 }
992
daniel@transgaming.com01868132010-08-24 19:21:17 +0000993 switch (target)
994 {
995 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
996 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
997 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
998 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
999 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1000 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1001 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
1002 break;
1003 default: UNREACHABLE();
1004 }
1005 }
1006 }
1007
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001008 }
1009 catch(std::bad_alloc&)
1010 {
1011 return error(GL_OUT_OF_MEMORY);
1012 }
1013}
1014
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001015void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
1016 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001017{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001018 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001019 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001020 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001021 target, level, xoffset, yoffset, width, height, format, imageSize, data);
1022
1023 try
1024 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001025 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +00001026 {
1027 return error(GL_INVALID_ENUM);
1028 }
1029
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001030 if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001031 {
1032 return error(GL_INVALID_VALUE);
1033 }
1034
daniel@transgaming.com01868132010-08-24 19:21:17 +00001035 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001036 {
daniel@transgaming.com01868132010-08-24 19:21:17 +00001037 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1038 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001039 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1040 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001041 break;
1042 default:
1043 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +00001044 }
1045
daniel@transgaming.com01868132010-08-24 19:21:17 +00001046 if (width == 0 || height == 0 || data == NULL)
1047 {
1048 return;
1049 }
1050
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001051 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001052
1053 if (context)
1054 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001055 if (level > context->getMaximumTextureLevel())
1056 {
1057 return error(GL_INVALID_VALUE);
1058 }
1059
gman@chromium.org50c526d2011-08-10 05:19:44 +00001060 switch (format) {
1061 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1062 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1063 if (!context->supportsDXT1Textures())
1064 {
1065 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1066 }
1067 break;
1068 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1069 if (!context->supportsDXT3Textures())
1070 {
1071 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1072 }
1073 break;
1074 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1075 if (!context->supportsDXT5Textures())
1076 {
1077 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1078 }
1079 break;
1080 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001081 }
1082
1083 if (imageSize != gl::ComputeCompressedSize(width, height, format))
1084 {
1085 return error(GL_INVALID_VALUE);
1086 }
1087
1088 if (xoffset % 4 != 0 || yoffset % 4 != 0)
1089 {
1090 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 +00001091 // does not exist unless DXT textures are supported.
daniel@transgaming.com01868132010-08-24 19:21:17 +00001092 }
1093
1094 if (target == GL_TEXTURE_2D)
1095 {
1096 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001097 if (validateSubImageParams(true, width, height, xoffset, yoffset, level, GL_NONE, texture))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001098 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001099 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
daniel@transgaming.com01868132010-08-24 19:21:17 +00001100 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001101 }
1102 else if (gl::IsCubemapTextureTarget(target))
1103 {
1104 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001105 if (validateSubImageParams(true, width, height, xoffset, yoffset, level, GL_NONE, texture))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001106 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001107 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
daniel@transgaming.com01868132010-08-24 19:21:17 +00001108 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001109 }
1110 else
1111 {
1112 UNREACHABLE();
1113 }
1114 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001115 }
1116 catch(std::bad_alloc&)
1117 {
1118 return error(GL_OUT_OF_MEMORY);
1119 }
1120}
1121
1122void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1123{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001124 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001125 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001126 target, level, internalformat, x, y, width, height, border);
1127
1128 try
1129 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001130 if (!validImageSize(level, width, height))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001131 {
1132 return error(GL_INVALID_VALUE);
1133 }
1134
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001135 if (border != 0)
1136 {
1137 return error(GL_INVALID_VALUE);
1138 }
1139
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001140 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001141
1142 if (context)
1143 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00001144 if (level > context->getMaximumTextureLevel())
1145 {
1146 return error(GL_INVALID_VALUE);
1147 }
1148
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001149 switch (target)
1150 {
1151 case GL_TEXTURE_2D:
1152 if (width > (context->getMaximumTextureDimension() >> level) ||
1153 height > (context->getMaximumTextureDimension() >> level))
1154 {
1155 return error(GL_INVALID_VALUE);
1156 }
1157 break;
1158 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1159 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1160 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1161 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1162 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1163 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1164 if (width != height)
1165 {
1166 return error(GL_INVALID_VALUE);
1167 }
1168
1169 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1170 height > (context->getMaximumCubeTextureDimension() >> level))
1171 {
1172 return error(GL_INVALID_VALUE);
1173 }
1174 break;
1175 default:
1176 return error(GL_INVALID_ENUM);
1177 }
1178
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001179 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001180
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001181 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1182 {
1183 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1184 }
1185
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001186 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1187 {
1188 return error(GL_INVALID_OPERATION);
1189 }
1190
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001191 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001192 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001193
1194 // [OpenGL ES 2.0.24] table 3.9
1195 switch (internalformat)
1196 {
1197 case GL_ALPHA:
1198 if (colorbufferFormat != GL_ALPHA &&
1199 colorbufferFormat != GL_RGBA &&
1200 colorbufferFormat != GL_RGBA4 &&
1201 colorbufferFormat != GL_RGB5_A1 &&
1202 colorbufferFormat != GL_RGBA8_OES)
1203 {
1204 return error(GL_INVALID_OPERATION);
1205 }
1206 break;
1207 case GL_LUMINANCE:
1208 case GL_RGB:
1209 if (colorbufferFormat != GL_RGB &&
1210 colorbufferFormat != GL_RGB565 &&
1211 colorbufferFormat != GL_RGB8_OES &&
1212 colorbufferFormat != GL_RGBA &&
1213 colorbufferFormat != GL_RGBA4 &&
1214 colorbufferFormat != GL_RGB5_A1 &&
1215 colorbufferFormat != GL_RGBA8_OES)
1216 {
1217 return error(GL_INVALID_OPERATION);
1218 }
1219 break;
1220 case GL_LUMINANCE_ALPHA:
1221 case GL_RGBA:
1222 if (colorbufferFormat != GL_RGBA &&
1223 colorbufferFormat != GL_RGBA4 &&
1224 colorbufferFormat != GL_RGB5_A1 &&
1225 colorbufferFormat != GL_RGBA8_OES)
1226 {
1227 return error(GL_INVALID_OPERATION);
1228 }
1229 break;
1230 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1231 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001232 if (context->supportsDXT1Textures())
1233 {
1234 return error(GL_INVALID_OPERATION);
1235 }
1236 else
1237 {
1238 return error(GL_INVALID_ENUM);
1239 }
1240 break;
1241 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1242 if (context->supportsDXT3Textures())
1243 {
1244 return error(GL_INVALID_OPERATION);
1245 }
1246 else
1247 {
1248 return error(GL_INVALID_ENUM);
1249 }
1250 break;
1251 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1252 if (context->supportsDXT5Textures())
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001253 {
1254 return error(GL_INVALID_OPERATION);
1255 }
1256 else
1257 {
1258 return error(GL_INVALID_ENUM);
1259 }
1260 break;
1261 default:
1262 return error(GL_INVALID_ENUM);
1263 }
1264
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001265 if (target == GL_TEXTURE_2D)
1266 {
1267 gl::Texture2D *texture = context->getTexture2D();
1268
1269 if (!texture)
1270 {
1271 return error(GL_INVALID_OPERATION);
1272 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001273
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001274 if (texture->isImmutable())
1275 {
1276 return error(GL_INVALID_OPERATION);
1277 }
1278
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001279 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001280 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001281 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001282 {
1283 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1284
1285 if (!texture)
1286 {
1287 return error(GL_INVALID_OPERATION);
1288 }
1289
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001290 if (texture->isImmutable())
1291 {
1292 return error(GL_INVALID_OPERATION);
1293 }
1294
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001295 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001296 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001297 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001298 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001299 }
1300 catch(std::bad_alloc&)
1301 {
1302 return error(GL_OUT_OF_MEMORY);
1303 }
1304}
1305
1306void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1307{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001308 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001309 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001310 target, level, xoffset, yoffset, x, y, width, height);
1311
1312 try
1313 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001314 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001315 {
1316 return error(GL_INVALID_ENUM);
1317 }
1318
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001319 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001320 {
1321 return error(GL_INVALID_VALUE);
1322 }
1323
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001324 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1325 {
1326 return error(GL_INVALID_VALUE);
1327 }
1328
1329 if (width == 0 || height == 0)
1330 {
1331 return;
1332 }
1333
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001334 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001335
1336 if (context)
1337 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001338 if (level > context->getMaximumTextureLevel())
1339 {
1340 return error(GL_INVALID_VALUE);
1341 }
1342
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001343 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001344
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001345 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1346 {
1347 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1348 }
1349
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001350 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1351 {
1352 return error(GL_INVALID_OPERATION);
1353 }
1354
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001355 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001356 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001357 gl::Texture *texture = NULL;
1358
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001359 if (target == GL_TEXTURE_2D)
1360 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001361 texture = context->getTexture2D();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001362 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001363 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001364 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001365 texture = context->getTextureCubeMap();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001366 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001367 else UNREACHABLE();
1368
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001369 if (!validateSubImageParams(false, width, height, xoffset, yoffset, level, GL_NONE, texture))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001370 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001371 return; // error already registered by validateSubImageParams
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00001372 }
1373
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001374 GLenum textureFormat = texture->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001375
1376 // [OpenGL ES 2.0.24] table 3.9
1377 switch (textureFormat)
1378 {
1379 case GL_ALPHA:
1380 if (colorbufferFormat != GL_ALPHA &&
1381 colorbufferFormat != GL_RGBA &&
1382 colorbufferFormat != GL_RGBA4 &&
1383 colorbufferFormat != GL_RGB5_A1 &&
1384 colorbufferFormat != GL_RGBA8_OES)
1385 {
1386 return error(GL_INVALID_OPERATION);
1387 }
1388 break;
1389 case GL_LUMINANCE:
1390 case GL_RGB:
1391 if (colorbufferFormat != GL_RGB &&
1392 colorbufferFormat != GL_RGB565 &&
1393 colorbufferFormat != GL_RGB8_OES &&
1394 colorbufferFormat != GL_RGBA &&
1395 colorbufferFormat != GL_RGBA4 &&
1396 colorbufferFormat != GL_RGB5_A1 &&
1397 colorbufferFormat != GL_RGBA8_OES)
1398 {
1399 return error(GL_INVALID_OPERATION);
1400 }
1401 break;
1402 case GL_LUMINANCE_ALPHA:
1403 case GL_RGBA:
1404 if (colorbufferFormat != GL_RGBA &&
1405 colorbufferFormat != GL_RGBA4 &&
1406 colorbufferFormat != GL_RGB5_A1 &&
1407 colorbufferFormat != GL_RGBA8_OES)
1408 {
1409 return error(GL_INVALID_OPERATION);
1410 }
1411 break;
1412 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1413 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001414 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1415 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001416 return error(GL_INVALID_OPERATION);
1417 default:
1418 return error(GL_INVALID_OPERATION);
1419 }
1420
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001421 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001422 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001423 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001424
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001425 catch(std::bad_alloc&)
1426 {
1427 return error(GL_OUT_OF_MEMORY);
1428 }
1429}
1430
1431GLuint __stdcall glCreateProgram(void)
1432{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001433 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001434
1435 try
1436 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001437 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001438
1439 if (context)
1440 {
1441 return context->createProgram();
1442 }
1443 }
1444 catch(std::bad_alloc&)
1445 {
1446 return error(GL_OUT_OF_MEMORY, 0);
1447 }
1448
1449 return 0;
1450}
1451
1452GLuint __stdcall glCreateShader(GLenum type)
1453{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001454 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001455
1456 try
1457 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001458 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001459
1460 if (context)
1461 {
1462 switch (type)
1463 {
1464 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001465 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001466 return context->createShader(type);
1467 default:
1468 return error(GL_INVALID_ENUM, 0);
1469 }
1470 }
1471 }
1472 catch(std::bad_alloc&)
1473 {
1474 return error(GL_OUT_OF_MEMORY, 0);
1475 }
1476
1477 return 0;
1478}
1479
1480void __stdcall glCullFace(GLenum mode)
1481{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001482 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001483
1484 try
1485 {
1486 switch (mode)
1487 {
1488 case GL_FRONT:
1489 case GL_BACK:
1490 case GL_FRONT_AND_BACK:
1491 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001492 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001493
1494 if (context)
1495 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001496 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001497 }
1498 }
1499 break;
1500 default:
1501 return error(GL_INVALID_ENUM);
1502 }
1503 }
1504 catch(std::bad_alloc&)
1505 {
1506 return error(GL_OUT_OF_MEMORY);
1507 }
1508}
1509
1510void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1511{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001512 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001513
1514 try
1515 {
1516 if (n < 0)
1517 {
1518 return error(GL_INVALID_VALUE);
1519 }
1520
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001521 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001522
1523 if (context)
1524 {
1525 for (int i = 0; i < n; i++)
1526 {
1527 context->deleteBuffer(buffers[i]);
1528 }
1529 }
1530 }
1531 catch(std::bad_alloc&)
1532 {
1533 return error(GL_OUT_OF_MEMORY);
1534 }
1535}
1536
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001537void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1538{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001539 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001540
1541 try
1542 {
1543 if (n < 0)
1544 {
1545 return error(GL_INVALID_VALUE);
1546 }
1547
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001548 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001549
1550 if (context)
1551 {
1552 for (int i = 0; i < n; i++)
1553 {
1554 context->deleteFence(fences[i]);
1555 }
1556 }
1557 }
1558 catch(std::bad_alloc&)
1559 {
1560 return error(GL_OUT_OF_MEMORY);
1561 }
1562}
1563
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001564void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1565{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001566 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001567
1568 try
1569 {
1570 if (n < 0)
1571 {
1572 return error(GL_INVALID_VALUE);
1573 }
1574
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001575 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001576
1577 if (context)
1578 {
1579 for (int i = 0; i < n; i++)
1580 {
1581 if (framebuffers[i] != 0)
1582 {
1583 context->deleteFramebuffer(framebuffers[i]);
1584 }
1585 }
1586 }
1587 }
1588 catch(std::bad_alloc&)
1589 {
1590 return error(GL_OUT_OF_MEMORY);
1591 }
1592}
1593
1594void __stdcall glDeleteProgram(GLuint program)
1595{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001596 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001597
1598 try
1599 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001600 if (program == 0)
1601 {
1602 return;
1603 }
1604
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001605 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001606
1607 if (context)
1608 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001609 if (!context->getProgram(program))
1610 {
1611 if(context->getShader(program))
1612 {
1613 return error(GL_INVALID_OPERATION);
1614 }
1615 else
1616 {
1617 return error(GL_INVALID_VALUE);
1618 }
1619 }
1620
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001621 context->deleteProgram(program);
1622 }
1623 }
1624 catch(std::bad_alloc&)
1625 {
1626 return error(GL_OUT_OF_MEMORY);
1627 }
1628}
1629
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00001630void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
1631{
1632 EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
1633
1634 try
1635 {
1636 if (n < 0)
1637 {
1638 return error(GL_INVALID_VALUE);
1639 }
1640
1641 gl::Context *context = gl::getNonLostContext();
1642
1643 if (context)
1644 {
1645 for (int i = 0; i < n; i++)
1646 {
1647 context->deleteQuery(ids[i]);
1648 }
1649 }
1650 }
1651 catch(std::bad_alloc&)
1652 {
1653 return error(GL_OUT_OF_MEMORY);
1654 }
1655}
1656
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001657void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1658{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001659 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001660
1661 try
1662 {
1663 if (n < 0)
1664 {
1665 return error(GL_INVALID_VALUE);
1666 }
1667
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001668 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001669
1670 if (context)
1671 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001672 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001673 {
1674 context->deleteRenderbuffer(renderbuffers[i]);
1675 }
1676 }
1677 }
1678 catch(std::bad_alloc&)
1679 {
1680 return error(GL_OUT_OF_MEMORY);
1681 }
1682}
1683
1684void __stdcall glDeleteShader(GLuint shader)
1685{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001686 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001687
1688 try
1689 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001690 if (shader == 0)
1691 {
1692 return;
1693 }
1694
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001695 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001696
1697 if (context)
1698 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001699 if (!context->getShader(shader))
1700 {
1701 if(context->getProgram(shader))
1702 {
1703 return error(GL_INVALID_OPERATION);
1704 }
1705 else
1706 {
1707 return error(GL_INVALID_VALUE);
1708 }
1709 }
1710
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001711 context->deleteShader(shader);
1712 }
1713 }
1714 catch(std::bad_alloc&)
1715 {
1716 return error(GL_OUT_OF_MEMORY);
1717 }
1718}
1719
1720void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1721{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001722 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001723
1724 try
1725 {
1726 if (n < 0)
1727 {
1728 return error(GL_INVALID_VALUE);
1729 }
1730
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001731 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001732
1733 if (context)
1734 {
1735 for (int i = 0; i < n; i++)
1736 {
1737 if (textures[i] != 0)
1738 {
1739 context->deleteTexture(textures[i]);
1740 }
1741 }
1742 }
1743 }
1744 catch(std::bad_alloc&)
1745 {
1746 return error(GL_OUT_OF_MEMORY);
1747 }
1748}
1749
1750void __stdcall glDepthFunc(GLenum func)
1751{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001752 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001753
1754 try
1755 {
1756 switch (func)
1757 {
1758 case GL_NEVER:
1759 case GL_ALWAYS:
1760 case GL_LESS:
1761 case GL_LEQUAL:
1762 case GL_EQUAL:
1763 case GL_GREATER:
1764 case GL_GEQUAL:
1765 case GL_NOTEQUAL:
1766 break;
1767 default:
1768 return error(GL_INVALID_ENUM);
1769 }
1770
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001771 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001772
1773 if (context)
1774 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001775 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001776 }
1777 }
1778 catch(std::bad_alloc&)
1779 {
1780 return error(GL_OUT_OF_MEMORY);
1781 }
1782}
1783
1784void __stdcall glDepthMask(GLboolean flag)
1785{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001786 EVENT("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001787
1788 try
1789 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001790 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001791
1792 if (context)
1793 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001794 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001795 }
1796 }
1797 catch(std::bad_alloc&)
1798 {
1799 return error(GL_OUT_OF_MEMORY);
1800 }
1801}
1802
1803void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1804{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001805 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001806
1807 try
1808 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001809 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001810
1811 if (context)
1812 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001813 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001814 }
1815 }
1816 catch(std::bad_alloc&)
1817 {
1818 return error(GL_OUT_OF_MEMORY);
1819 }
1820}
1821
1822void __stdcall glDetachShader(GLuint program, GLuint shader)
1823{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001824 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001825
1826 try
1827 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001828 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001829
1830 if (context)
1831 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001832
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001833 gl::Program *programObject = context->getProgram(program);
1834 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001835
1836 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001837 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001838 gl::Shader *shaderByProgramHandle;
1839 shaderByProgramHandle = context->getShader(program);
1840 if (!shaderByProgramHandle)
1841 {
1842 return error(GL_INVALID_VALUE);
1843 }
1844 else
1845 {
1846 return error(GL_INVALID_OPERATION);
1847 }
1848 }
1849
1850 if (!shaderObject)
1851 {
1852 gl::Program *programByShaderHandle = context->getProgram(shader);
1853 if (!programByShaderHandle)
1854 {
1855 return error(GL_INVALID_VALUE);
1856 }
1857 else
1858 {
1859 return error(GL_INVALID_OPERATION);
1860 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001861 }
1862
1863 if (!programObject->detachShader(shaderObject))
1864 {
1865 return error(GL_INVALID_OPERATION);
1866 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001867 }
1868 }
1869 catch(std::bad_alloc&)
1870 {
1871 return error(GL_OUT_OF_MEMORY);
1872 }
1873}
1874
1875void __stdcall glDisable(GLenum cap)
1876{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001877 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001878
1879 try
1880 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001881 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001882
1883 if (context)
1884 {
1885 switch (cap)
1886 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001887 case GL_CULL_FACE: context->setCullFace(false); break;
1888 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1889 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1890 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1891 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1892 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1893 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1894 case GL_BLEND: context->setBlend(false); break;
1895 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001896 default:
1897 return error(GL_INVALID_ENUM);
1898 }
1899 }
1900 }
1901 catch(std::bad_alloc&)
1902 {
1903 return error(GL_OUT_OF_MEMORY);
1904 }
1905}
1906
1907void __stdcall glDisableVertexAttribArray(GLuint index)
1908{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001909 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001910
1911 try
1912 {
1913 if (index >= gl::MAX_VERTEX_ATTRIBS)
1914 {
1915 return error(GL_INVALID_VALUE);
1916 }
1917
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001918 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001919
1920 if (context)
1921 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001922 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001923 }
1924 }
1925 catch(std::bad_alloc&)
1926 {
1927 return error(GL_OUT_OF_MEMORY);
1928 }
1929}
1930
1931void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1932{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001933 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001934
1935 try
1936 {
1937 if (count < 0 || first < 0)
1938 {
1939 return error(GL_INVALID_VALUE);
1940 }
1941
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001942 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001943
1944 if (context)
1945 {
1946 context->drawArrays(mode, first, count);
1947 }
1948 }
1949 catch(std::bad_alloc&)
1950 {
1951 return error(GL_OUT_OF_MEMORY);
1952 }
1953}
1954
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001955void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001956{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001957 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 +00001958 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001959
1960 try
1961 {
1962 if (count < 0)
1963 {
1964 return error(GL_INVALID_VALUE);
1965 }
1966
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001967 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001968
1969 if (context)
1970 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001971 switch (type)
1972 {
1973 case GL_UNSIGNED_BYTE:
1974 case GL_UNSIGNED_SHORT:
1975 break;
1976 case GL_UNSIGNED_INT:
1977 if (!context->supports32bitIndices())
1978 {
1979 return error(GL_INVALID_ENUM);
1980 }
1981 break;
1982 default:
1983 return error(GL_INVALID_ENUM);
1984 }
1985
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001986 context->drawElements(mode, count, type, indices);
1987 }
1988 }
1989 catch(std::bad_alloc&)
1990 {
1991 return error(GL_OUT_OF_MEMORY);
1992 }
1993}
1994
1995void __stdcall glEnable(GLenum cap)
1996{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001997 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001998
1999 try
2000 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002001 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002002
2003 if (context)
2004 {
2005 switch (cap)
2006 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002007 case GL_CULL_FACE: context->setCullFace(true); break;
2008 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
2009 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
2010 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
2011 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
2012 case GL_STENCIL_TEST: context->setStencilTest(true); break;
2013 case GL_DEPTH_TEST: context->setDepthTest(true); break;
2014 case GL_BLEND: context->setBlend(true); break;
2015 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002016 default:
2017 return error(GL_INVALID_ENUM);
2018 }
2019 }
2020 }
2021 catch(std::bad_alloc&)
2022 {
2023 return error(GL_OUT_OF_MEMORY);
2024 }
2025}
2026
2027void __stdcall glEnableVertexAttribArray(GLuint index)
2028{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002029 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002030
2031 try
2032 {
2033 if (index >= gl::MAX_VERTEX_ATTRIBS)
2034 {
2035 return error(GL_INVALID_VALUE);
2036 }
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 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002042 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002043 }
2044 }
2045 catch(std::bad_alloc&)
2046 {
2047 return error(GL_OUT_OF_MEMORY);
2048 }
2049}
2050
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00002051void __stdcall glEndQueryEXT(GLenum target)
2052{
2053 EVENT("GLenum target = 0x%X)", target);
2054
2055 try
2056 {
2057 switch (target)
2058 {
2059 case GL_ANY_SAMPLES_PASSED_EXT:
2060 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
2061 break;
2062 default:
2063 return error(GL_INVALID_ENUM);
2064 }
2065
2066 gl::Context *context = gl::getNonLostContext();
2067
2068 if (context)
2069 {
2070 context->endQuery(target);
2071 }
2072 }
2073 catch(std::bad_alloc&)
2074 {
2075 return error(GL_OUT_OF_MEMORY);
2076 }
2077}
2078
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002079void __stdcall glFinishFenceNV(GLuint fence)
2080{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002081 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002082
2083 try
2084 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002085 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002086
2087 if (context)
2088 {
2089 gl::Fence* fenceObject = context->getFence(fence);
2090
2091 if (fenceObject == NULL)
2092 {
2093 return error(GL_INVALID_OPERATION);
2094 }
2095
2096 fenceObject->finishFence();
2097 }
2098 }
2099 catch(std::bad_alloc&)
2100 {
2101 return error(GL_OUT_OF_MEMORY);
2102 }
2103}
2104
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002105void __stdcall glFinish(void)
2106{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002107 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002108
2109 try
2110 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002111 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002112
2113 if (context)
2114 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002115 context->sync(true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002116 }
2117 }
2118 catch(std::bad_alloc&)
2119 {
2120 return error(GL_OUT_OF_MEMORY);
2121 }
2122}
2123
2124void __stdcall glFlush(void)
2125{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002126 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002127
2128 try
2129 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002130 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002131
2132 if (context)
2133 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002134 context->sync(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002135 }
2136 }
2137 catch(std::bad_alloc&)
2138 {
2139 return error(GL_OUT_OF_MEMORY);
2140 }
2141}
2142
2143void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2144{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002145 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002146 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002147
2148 try
2149 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002150 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002151 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002152 {
2153 return error(GL_INVALID_ENUM);
2154 }
2155
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002156 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002157
2158 if (context)
2159 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002160 gl::Framebuffer *framebuffer = NULL;
2161 GLuint framebufferHandle = 0;
2162 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2163 {
2164 framebuffer = context->getReadFramebuffer();
2165 framebufferHandle = context->getReadFramebufferHandle();
2166 }
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002167 else
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002168 {
2169 framebuffer = context->getDrawFramebuffer();
2170 framebufferHandle = context->getDrawFramebufferHandle();
2171 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002172
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002173 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002174 {
2175 return error(GL_INVALID_OPERATION);
2176 }
2177
2178 switch (attachment)
2179 {
2180 case GL_COLOR_ATTACHMENT0:
2181 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2182 break;
2183 case GL_DEPTH_ATTACHMENT:
2184 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2185 break;
2186 case GL_STENCIL_ATTACHMENT:
2187 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2188 break;
2189 default:
2190 return error(GL_INVALID_ENUM);
2191 }
2192 }
2193 }
2194 catch(std::bad_alloc&)
2195 {
2196 return error(GL_OUT_OF_MEMORY);
2197 }
2198}
2199
2200void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2201{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002202 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002203 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002204
2205 try
2206 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002207 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002208 {
2209 return error(GL_INVALID_ENUM);
2210 }
2211
2212 switch (attachment)
2213 {
2214 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002215 case GL_DEPTH_ATTACHMENT:
2216 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002217 break;
2218 default:
2219 return error(GL_INVALID_ENUM);
2220 }
2221
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002222 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002223
2224 if (context)
2225 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002226 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002227 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002228 textarget = GL_NONE;
2229 }
2230 else
2231 {
2232 gl::Texture *tex = context->getTexture(texture);
2233
2234 if (tex == NULL)
2235 {
2236 return error(GL_INVALID_OPERATION);
2237 }
2238
daniel@transgaming.com01868132010-08-24 19:21:17 +00002239 if (tex->isCompressed())
2240 {
2241 return error(GL_INVALID_OPERATION);
2242 }
2243
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002244 switch (textarget)
2245 {
2246 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002247 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002248 {
2249 return error(GL_INVALID_OPERATION);
2250 }
2251 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002252
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002253 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002254 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002255 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002256 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002257 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002258 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002259 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2260 {
2261 return error(GL_INVALID_OPERATION);
2262 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002263 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002264
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002265 default:
2266 return error(GL_INVALID_ENUM);
2267 }
2268
2269 if (level != 0)
2270 {
2271 return error(GL_INVALID_VALUE);
2272 }
2273 }
2274
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002275 gl::Framebuffer *framebuffer = NULL;
2276 GLuint framebufferHandle = 0;
2277 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2278 {
2279 framebuffer = context->getReadFramebuffer();
2280 framebufferHandle = context->getReadFramebufferHandle();
2281 }
2282 else
2283 {
2284 framebuffer = context->getDrawFramebuffer();
2285 framebufferHandle = context->getDrawFramebufferHandle();
2286 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002287
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002288 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002289 {
2290 return error(GL_INVALID_OPERATION);
2291 }
2292
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002293 switch (attachment)
2294 {
2295 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2296 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2297 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2298 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002299 }
2300 }
2301 catch(std::bad_alloc&)
2302 {
2303 return error(GL_OUT_OF_MEMORY);
2304 }
2305}
2306
2307void __stdcall glFrontFace(GLenum mode)
2308{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002309 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002310
2311 try
2312 {
2313 switch (mode)
2314 {
2315 case GL_CW:
2316 case GL_CCW:
2317 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002318 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002319
2320 if (context)
2321 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002322 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002323 }
2324 }
2325 break;
2326 default:
2327 return error(GL_INVALID_ENUM);
2328 }
2329 }
2330 catch(std::bad_alloc&)
2331 {
2332 return error(GL_OUT_OF_MEMORY);
2333 }
2334}
2335
2336void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2337{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002338 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002339
2340 try
2341 {
2342 if (n < 0)
2343 {
2344 return error(GL_INVALID_VALUE);
2345 }
2346
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002347 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002348
2349 if (context)
2350 {
2351 for (int i = 0; i < n; i++)
2352 {
2353 buffers[i] = context->createBuffer();
2354 }
2355 }
2356 }
2357 catch(std::bad_alloc&)
2358 {
2359 return error(GL_OUT_OF_MEMORY);
2360 }
2361}
2362
2363void __stdcall glGenerateMipmap(GLenum target)
2364{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002365 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002366
2367 try
2368 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002369 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002370
2371 if (context)
2372 {
2373 gl::Texture *texture;
2374
2375 switch (target)
2376 {
2377 case GL_TEXTURE_2D:
2378 texture = context->getTexture2D();
2379 break;
2380
2381 case GL_TEXTURE_CUBE_MAP:
2382 texture = context->getTextureCubeMap();
2383 break;
2384
2385 default:
2386 return error(GL_INVALID_ENUM);
2387 }
2388
daniel@transgaming.com01868132010-08-24 19:21:17 +00002389 if (texture->isCompressed())
2390 {
2391 return error(GL_INVALID_OPERATION);
2392 }
2393
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002394 texture->generateMipmaps();
2395 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002396 }
2397 catch(std::bad_alloc&)
2398 {
2399 return error(GL_OUT_OF_MEMORY);
2400 }
2401}
2402
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002403void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2404{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002405 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002406
2407 try
2408 {
2409 if (n < 0)
2410 {
2411 return error(GL_INVALID_VALUE);
2412 }
2413
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002414 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002415
2416 if (context)
2417 {
2418 for (int i = 0; i < n; i++)
2419 {
2420 fences[i] = context->createFence();
2421 }
2422 }
2423 }
2424 catch(std::bad_alloc&)
2425 {
2426 return error(GL_OUT_OF_MEMORY);
2427 }
2428}
2429
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002430void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2431{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002432 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002433
2434 try
2435 {
2436 if (n < 0)
2437 {
2438 return error(GL_INVALID_VALUE);
2439 }
2440
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002441 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002442
2443 if (context)
2444 {
2445 for (int i = 0; i < n; i++)
2446 {
2447 framebuffers[i] = context->createFramebuffer();
2448 }
2449 }
2450 }
2451 catch(std::bad_alloc&)
2452 {
2453 return error(GL_OUT_OF_MEMORY);
2454 }
2455}
2456
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00002457void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
2458{
2459 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
2460
2461 try
2462 {
2463 if (n < 0)
2464 {
2465 return error(GL_INVALID_VALUE);
2466 }
2467
2468 gl::Context *context = gl::getNonLostContext();
2469
2470 if (context)
2471 {
2472 for (int i = 0; i < n; i++)
2473 {
2474 ids[i] = context->createQuery();
2475 }
2476 }
2477 }
2478 catch(std::bad_alloc&)
2479 {
2480 return error(GL_OUT_OF_MEMORY);
2481 }
2482}
2483
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002484void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2485{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002486 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002487
2488 try
2489 {
2490 if (n < 0)
2491 {
2492 return error(GL_INVALID_VALUE);
2493 }
2494
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002495 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002496
2497 if (context)
2498 {
2499 for (int i = 0; i < n; i++)
2500 {
2501 renderbuffers[i] = context->createRenderbuffer();
2502 }
2503 }
2504 }
2505 catch(std::bad_alloc&)
2506 {
2507 return error(GL_OUT_OF_MEMORY);
2508 }
2509}
2510
2511void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2512{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002513 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002514
2515 try
2516 {
2517 if (n < 0)
2518 {
2519 return error(GL_INVALID_VALUE);
2520 }
2521
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002522 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002523
2524 if (context)
2525 {
2526 for (int i = 0; i < n; i++)
2527 {
2528 textures[i] = context->createTexture();
2529 }
2530 }
2531 }
2532 catch(std::bad_alloc&)
2533 {
2534 return error(GL_OUT_OF_MEMORY);
2535 }
2536}
2537
daniel@transgaming.com85423182010-04-22 13:35:27 +00002538void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002539{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002540 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002541 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002542 program, index, bufsize, length, size, type, name);
2543
2544 try
2545 {
2546 if (bufsize < 0)
2547 {
2548 return error(GL_INVALID_VALUE);
2549 }
2550
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002551 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com85423182010-04-22 13:35:27 +00002552
2553 if (context)
2554 {
2555 gl::Program *programObject = context->getProgram(program);
2556
2557 if (!programObject)
2558 {
2559 if (context->getShader(program))
2560 {
2561 return error(GL_INVALID_OPERATION);
2562 }
2563 else
2564 {
2565 return error(GL_INVALID_VALUE);
2566 }
2567 }
2568
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002569 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002570 {
2571 return error(GL_INVALID_VALUE);
2572 }
2573
2574 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2575 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002576 }
2577 catch(std::bad_alloc&)
2578 {
2579 return error(GL_OUT_OF_MEMORY);
2580 }
2581}
2582
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002583void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002584{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002585 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002586 "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 +00002587 program, index, bufsize, length, size, type, name);
2588
2589 try
2590 {
2591 if (bufsize < 0)
2592 {
2593 return error(GL_INVALID_VALUE);
2594 }
2595
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002596 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002597
2598 if (context)
2599 {
2600 gl::Program *programObject = context->getProgram(program);
2601
2602 if (!programObject)
2603 {
2604 if (context->getShader(program))
2605 {
2606 return error(GL_INVALID_OPERATION);
2607 }
2608 else
2609 {
2610 return error(GL_INVALID_VALUE);
2611 }
2612 }
2613
2614 if (index >= (GLuint)programObject->getActiveUniformCount())
2615 {
2616 return error(GL_INVALID_VALUE);
2617 }
2618
2619 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2620 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002621 }
2622 catch(std::bad_alloc&)
2623 {
2624 return error(GL_OUT_OF_MEMORY);
2625 }
2626}
2627
2628void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2629{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002630 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 +00002631 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002632
2633 try
2634 {
2635 if (maxcount < 0)
2636 {
2637 return error(GL_INVALID_VALUE);
2638 }
2639
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002640 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002641
2642 if (context)
2643 {
2644 gl::Program *programObject = context->getProgram(program);
2645
2646 if (!programObject)
2647 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002648 if (context->getShader(program))
2649 {
2650 return error(GL_INVALID_OPERATION);
2651 }
2652 else
2653 {
2654 return error(GL_INVALID_VALUE);
2655 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002656 }
2657
2658 return programObject->getAttachedShaders(maxcount, count, shaders);
2659 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002660 }
2661 catch(std::bad_alloc&)
2662 {
2663 return error(GL_OUT_OF_MEMORY);
2664 }
2665}
2666
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002667int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002668{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002669 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002670
2671 try
2672 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002673 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002674
2675 if (context)
2676 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002677
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002678 gl::Program *programObject = context->getProgram(program);
2679
2680 if (!programObject)
2681 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002682 if (context->getShader(program))
2683 {
2684 return error(GL_INVALID_OPERATION, -1);
2685 }
2686 else
2687 {
2688 return error(GL_INVALID_VALUE, -1);
2689 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002690 }
2691
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002692 if (!programObject->isLinked())
2693 {
2694 return error(GL_INVALID_OPERATION, -1);
2695 }
2696
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002697 return programObject->getAttributeLocation(name);
2698 }
2699 }
2700 catch(std::bad_alloc&)
2701 {
2702 return error(GL_OUT_OF_MEMORY, -1);
2703 }
2704
2705 return -1;
2706}
2707
2708void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2709{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002710 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002711
2712 try
2713 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002714 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002715
2716 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002717 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002718 if (!(context->getBooleanv(pname, params)))
2719 {
2720 GLenum nativeType;
2721 unsigned int numParams = 0;
2722 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2723 return error(GL_INVALID_ENUM);
2724
2725 if (numParams == 0)
2726 return; // it is known that the pname is valid, but there are no parameters to return
2727
2728 if (nativeType == GL_FLOAT)
2729 {
2730 GLfloat *floatParams = NULL;
2731 floatParams = new GLfloat[numParams];
2732
2733 context->getFloatv(pname, floatParams);
2734
2735 for (unsigned int i = 0; i < numParams; ++i)
2736 {
2737 if (floatParams[i] == 0.0f)
2738 params[i] = GL_FALSE;
2739 else
2740 params[i] = GL_TRUE;
2741 }
2742
2743 delete [] floatParams;
2744 }
2745 else if (nativeType == GL_INT)
2746 {
2747 GLint *intParams = NULL;
2748 intParams = new GLint[numParams];
2749
2750 context->getIntegerv(pname, intParams);
2751
2752 for (unsigned int i = 0; i < numParams; ++i)
2753 {
2754 if (intParams[i] == 0)
2755 params[i] = GL_FALSE;
2756 else
2757 params[i] = GL_TRUE;
2758 }
2759
2760 delete [] intParams;
2761 }
2762 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002763 }
2764 }
2765 catch(std::bad_alloc&)
2766 {
2767 return error(GL_OUT_OF_MEMORY);
2768 }
2769}
2770
2771void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2772{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002773 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 +00002774
2775 try
2776 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002777 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002778
2779 if (context)
2780 {
2781 gl::Buffer *buffer;
2782
2783 switch (target)
2784 {
2785 case GL_ARRAY_BUFFER:
2786 buffer = context->getArrayBuffer();
2787 break;
2788 case GL_ELEMENT_ARRAY_BUFFER:
2789 buffer = context->getElementArrayBuffer();
2790 break;
2791 default: return error(GL_INVALID_ENUM);
2792 }
2793
2794 if (!buffer)
2795 {
2796 // A null buffer means that "0" is bound to the requested buffer target
2797 return error(GL_INVALID_OPERATION);
2798 }
2799
2800 switch (pname)
2801 {
2802 case GL_BUFFER_USAGE:
2803 *params = buffer->usage();
2804 break;
2805 case GL_BUFFER_SIZE:
2806 *params = buffer->size();
2807 break;
2808 default: return error(GL_INVALID_ENUM);
2809 }
2810 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002811 }
2812 catch(std::bad_alloc&)
2813 {
2814 return error(GL_OUT_OF_MEMORY);
2815 }
2816}
2817
2818GLenum __stdcall glGetError(void)
2819{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002820 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002821
2822 gl::Context *context = gl::getContext();
2823
2824 if (context)
2825 {
daniel@transgaming.com82b28912011-12-12 21:01:35 +00002826 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002827 }
2828
2829 return GL_NO_ERROR;
2830}
2831
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002832void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2833{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002834 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002835
2836 try
2837 {
2838
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002839 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002840
2841 if (context)
2842 {
2843 gl::Fence *fenceObject = context->getFence(fence);
2844
2845 if (fenceObject == NULL)
2846 {
2847 return error(GL_INVALID_OPERATION);
2848 }
2849
2850 fenceObject->getFenceiv(pname, params);
2851 }
2852 }
2853 catch(std::bad_alloc&)
2854 {
2855 return error(GL_OUT_OF_MEMORY);
2856 }
2857}
2858
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002859void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2860{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002861 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002862
2863 try
2864 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002865 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002866
2867 if (context)
2868 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002869 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002870 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002871 GLenum nativeType;
2872 unsigned int numParams = 0;
2873 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2874 return error(GL_INVALID_ENUM);
2875
2876 if (numParams == 0)
2877 return; // it is known that the pname is valid, but that there are no parameters to return.
2878
2879 if (nativeType == GL_BOOL)
2880 {
2881 GLboolean *boolParams = NULL;
2882 boolParams = new GLboolean[numParams];
2883
2884 context->getBooleanv(pname, boolParams);
2885
2886 for (unsigned int i = 0; i < numParams; ++i)
2887 {
2888 if (boolParams[i] == GL_FALSE)
2889 params[i] = 0.0f;
2890 else
2891 params[i] = 1.0f;
2892 }
2893
2894 delete [] boolParams;
2895 }
2896 else if (nativeType == GL_INT)
2897 {
2898 GLint *intParams = NULL;
2899 intParams = new GLint[numParams];
2900
2901 context->getIntegerv(pname, intParams);
2902
2903 for (unsigned int i = 0; i < numParams; ++i)
2904 {
2905 params[i] = (GLfloat)intParams[i];
2906 }
2907
2908 delete [] intParams;
2909 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002910 }
2911 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002912 }
2913 catch(std::bad_alloc&)
2914 {
2915 return error(GL_OUT_OF_MEMORY);
2916 }
2917}
2918
2919void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2920{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002921 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 +00002922 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002923
2924 try
2925 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002926 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002927
2928 if (context)
2929 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002930 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002931 {
2932 return error(GL_INVALID_ENUM);
2933 }
2934
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002935 gl::Framebuffer *framebuffer = NULL;
2936 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2937 {
2938 if(context->getReadFramebufferHandle() == 0)
2939 {
2940 return error(GL_INVALID_OPERATION);
2941 }
2942
2943 framebuffer = context->getReadFramebuffer();
2944 }
2945 else
2946 {
2947 if (context->getDrawFramebufferHandle() == 0)
2948 {
2949 return error(GL_INVALID_OPERATION);
2950 }
2951
2952 framebuffer = context->getDrawFramebuffer();
2953 }
2954
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002955 GLenum attachmentType;
2956 GLuint attachmentHandle;
2957 switch (attachment)
2958 {
2959 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002960 attachmentType = framebuffer->getColorbufferType();
2961 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002962 break;
2963 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002964 attachmentType = framebuffer->getDepthbufferType();
2965 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002966 break;
2967 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002968 attachmentType = framebuffer->getStencilbufferType();
2969 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002970 break;
2971 default: return error(GL_INVALID_ENUM);
2972 }
2973
2974 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002975 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002976 {
2977 attachmentObjectType = attachmentType;
2978 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002979 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002980 {
2981 attachmentObjectType = GL_TEXTURE;
2982 }
2983 else UNREACHABLE();
2984
2985 switch (pname)
2986 {
2987 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2988 *params = attachmentObjectType;
2989 break;
2990 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2991 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2992 {
2993 *params = attachmentHandle;
2994 }
2995 else
2996 {
2997 return error(GL_INVALID_ENUM);
2998 }
2999 break;
3000 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3001 if (attachmentObjectType == GL_TEXTURE)
3002 {
3003 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
3004 }
3005 else
3006 {
3007 return error(GL_INVALID_ENUM);
3008 }
3009 break;
3010 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3011 if (attachmentObjectType == GL_TEXTURE)
3012 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00003013 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003014 {
3015 *params = attachmentType;
3016 }
3017 else
3018 {
3019 *params = 0;
3020 }
3021 }
3022 else
3023 {
3024 return error(GL_INVALID_ENUM);
3025 }
3026 break;
3027 default:
3028 return error(GL_INVALID_ENUM);
3029 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003030 }
3031 }
3032 catch(std::bad_alloc&)
3033 {
3034 return error(GL_OUT_OF_MEMORY);
3035 }
3036}
3037
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00003038GLenum __stdcall glGetGraphicsResetStatusEXT(void)
3039{
3040 EVENT("()");
3041
3042 try
3043 {
3044 gl::Context *context = gl::getContext();
3045
3046 if (context)
3047 {
3048 return context->getResetStatus();
3049 }
3050
3051 return GL_NO_ERROR;
3052 }
3053 catch(std::bad_alloc&)
3054 {
3055 return GL_OUT_OF_MEMORY;
3056 }
3057}
3058
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003059void __stdcall glGetIntegerv(GLenum pname, GLint* params)
3060{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003061 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003062
3063 try
3064 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003065 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003066
3067 if (context)
3068 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003069 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003070 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003071 GLenum nativeType;
3072 unsigned int numParams = 0;
3073 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3074 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003075
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003076 if (numParams == 0)
3077 return; // it is known that pname is valid, but there are no parameters to return
3078
3079 if (nativeType == GL_BOOL)
3080 {
3081 GLboolean *boolParams = NULL;
3082 boolParams = new GLboolean[numParams];
3083
3084 context->getBooleanv(pname, boolParams);
3085
3086 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003087 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003088 if (boolParams[i] == GL_FALSE)
3089 params[i] = 0;
3090 else
3091 params[i] = 1;
3092 }
3093
3094 delete [] boolParams;
3095 }
3096 else if (nativeType == GL_FLOAT)
3097 {
3098 GLfloat *floatParams = NULL;
3099 floatParams = new GLfloat[numParams];
3100
3101 context->getFloatv(pname, floatParams);
3102
3103 for (unsigned int i = 0; i < numParams; ++i)
3104 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00003105 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 +00003106 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003107 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003108 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003109 else
3110 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 +00003111 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003112
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003113 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003114 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003115 }
3116 }
3117 }
3118 catch(std::bad_alloc&)
3119 {
3120 return error(GL_OUT_OF_MEMORY);
3121 }
3122}
3123
3124void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3125{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003126 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003127
3128 try
3129 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003130 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003131
3132 if (context)
3133 {
3134 gl::Program *programObject = context->getProgram(program);
3135
3136 if (!programObject)
3137 {
3138 return error(GL_INVALID_VALUE);
3139 }
3140
3141 switch (pname)
3142 {
3143 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003144 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003145 return;
3146 case GL_LINK_STATUS:
3147 *params = programObject->isLinked();
3148 return;
3149 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003150 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003151 return;
3152 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003153 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003154 return;
3155 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003156 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003157 return;
3158 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003159 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003160 return;
3161 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003162 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003163 return;
3164 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003165 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003166 return;
3167 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003168 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003169 return;
3170 default:
3171 return error(GL_INVALID_ENUM);
3172 }
3173 }
3174 }
3175 catch(std::bad_alloc&)
3176 {
3177 return error(GL_OUT_OF_MEMORY);
3178 }
3179}
3180
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003181void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003182{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003183 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 +00003184 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003185
3186 try
3187 {
3188 if (bufsize < 0)
3189 {
3190 return error(GL_INVALID_VALUE);
3191 }
3192
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003193 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003194
3195 if (context)
3196 {
3197 gl::Program *programObject = context->getProgram(program);
3198
3199 if (!programObject)
3200 {
3201 return error(GL_INVALID_VALUE);
3202 }
3203
3204 programObject->getInfoLog(bufsize, length, infolog);
3205 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003206 }
3207 catch(std::bad_alloc&)
3208 {
3209 return error(GL_OUT_OF_MEMORY);
3210 }
3211}
3212
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003213void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3214{
3215 EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
3216
3217 try
3218 {
3219 switch (pname)
3220 {
3221 case GL_CURRENT_QUERY_EXT:
3222 break;
3223 default:
3224 return error(GL_INVALID_ENUM);
3225 }
3226
3227 gl::Context *context = gl::getNonLostContext();
3228
3229 if (context)
3230 {
3231 params[0] = context->getActiveQuery(target);
3232 }
3233 }
3234 catch(std::bad_alloc&)
3235 {
3236 return error(GL_OUT_OF_MEMORY);
3237 }
3238}
3239
3240void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
3241{
3242 EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
3243
3244 try
3245 {
3246 switch (pname)
3247 {
3248 case GL_QUERY_RESULT_EXT:
3249 case GL_QUERY_RESULT_AVAILABLE_EXT:
3250 break;
3251 default:
3252 return error(GL_INVALID_ENUM);
3253 }
3254 gl::Context *context = gl::getNonLostContext();
3255
3256 if (context)
3257 {
3258
3259 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
3260
3261 if (!queryObject)
3262 {
3263 return error(GL_INVALID_OPERATION);
3264 }
3265
3266 if (context->getActiveQuery(queryObject->getType()) == id)
3267 {
3268 return error(GL_INVALID_OPERATION);
3269 }
3270
3271 switch(pname)
3272 {
3273 case GL_QUERY_RESULT_EXT:
3274 params[0] = queryObject->getResult();
3275 break;
3276 case GL_QUERY_RESULT_AVAILABLE_EXT:
3277 params[0] = queryObject->isResultAvailable();
3278 break;
3279 default:
3280 ASSERT(false);
3281 }
3282 }
3283 }
3284 catch(std::bad_alloc&)
3285 {
3286 return error(GL_OUT_OF_MEMORY);
3287 }
3288}
3289
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003290void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3291{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003292 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 +00003293
3294 try
3295 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003296 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003297
3298 if (context)
3299 {
3300 if (target != GL_RENDERBUFFER)
3301 {
3302 return error(GL_INVALID_ENUM);
3303 }
3304
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003305 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003306 {
3307 return error(GL_INVALID_OPERATION);
3308 }
3309
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003310 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003311
3312 switch (pname)
3313 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003314 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3315 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3316 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3317 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3318 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3319 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3320 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3321 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3322 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003323 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003324 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003325 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003326 *params = renderbuffer->getSamples();
3327 }
3328 else
3329 {
3330 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003331 }
3332 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003333 default:
3334 return error(GL_INVALID_ENUM);
3335 }
3336 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003337 }
3338 catch(std::bad_alloc&)
3339 {
3340 return error(GL_OUT_OF_MEMORY);
3341 }
3342}
3343
3344void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3345{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003346 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003347
3348 try
3349 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003350 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003351
3352 if (context)
3353 {
3354 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003355
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003356 if (!shaderObject)
3357 {
3358 return error(GL_INVALID_VALUE);
3359 }
3360
3361 switch (pname)
3362 {
3363 case GL_SHADER_TYPE:
3364 *params = shaderObject->getType();
3365 return;
3366 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003367 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003368 return;
3369 case GL_COMPILE_STATUS:
3370 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3371 return;
3372 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003373 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003374 return;
3375 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003376 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003377 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003378 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3379 *params = shaderObject->getTranslatedSourceLength();
3380 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003381 default:
3382 return error(GL_INVALID_ENUM);
3383 }
3384 }
3385 }
3386 catch(std::bad_alloc&)
3387 {
3388 return error(GL_OUT_OF_MEMORY);
3389 }
3390}
3391
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003392void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003393{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003394 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 +00003395 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003396
3397 try
3398 {
3399 if (bufsize < 0)
3400 {
3401 return error(GL_INVALID_VALUE);
3402 }
3403
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003404 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003405
3406 if (context)
3407 {
3408 gl::Shader *shaderObject = context->getShader(shader);
3409
3410 if (!shaderObject)
3411 {
3412 return error(GL_INVALID_VALUE);
3413 }
3414
3415 shaderObject->getInfoLog(bufsize, length, infolog);
3416 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003417 }
3418 catch(std::bad_alloc&)
3419 {
3420 return error(GL_OUT_OF_MEMORY);
3421 }
3422}
3423
3424void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3425{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003426 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 +00003427 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003428
3429 try
3430 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003431 switch (shadertype)
3432 {
3433 case GL_VERTEX_SHADER:
3434 case GL_FRAGMENT_SHADER:
3435 break;
3436 default:
3437 return error(GL_INVALID_ENUM);
3438 }
3439
3440 switch (precisiontype)
3441 {
3442 case GL_LOW_FLOAT:
3443 case GL_MEDIUM_FLOAT:
3444 case GL_HIGH_FLOAT:
3445 // Assume IEEE 754 precision
3446 range[0] = 127;
3447 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003448 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003449 break;
3450 case GL_LOW_INT:
3451 case GL_MEDIUM_INT:
3452 case GL_HIGH_INT:
3453 // Some (most) hardware only supports single-precision floating-point numbers,
3454 // which can accurately represent integers up to +/-16777216
3455 range[0] = 24;
3456 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003457 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003458 break;
3459 default:
3460 return error(GL_INVALID_ENUM);
3461 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003462 }
3463 catch(std::bad_alloc&)
3464 {
3465 return error(GL_OUT_OF_MEMORY);
3466 }
3467}
3468
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003469void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003470{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003471 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 +00003472 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003473
3474 try
3475 {
3476 if (bufsize < 0)
3477 {
3478 return error(GL_INVALID_VALUE);
3479 }
3480
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003481 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003482
3483 if (context)
3484 {
3485 gl::Shader *shaderObject = context->getShader(shader);
3486
3487 if (!shaderObject)
3488 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003489 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003490 }
3491
3492 shaderObject->getSource(bufsize, length, source);
3493 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003494 }
3495 catch(std::bad_alloc&)
3496 {
3497 return error(GL_OUT_OF_MEMORY);
3498 }
3499}
3500
zmo@google.coma574f782011-10-03 21:45:23 +00003501void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3502{
3503 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3504 shader, bufsize, length, source);
3505
3506 try
3507 {
3508 if (bufsize < 0)
3509 {
3510 return error(GL_INVALID_VALUE);
3511 }
3512
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003513 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003514
3515 if (context)
3516 {
3517 gl::Shader *shaderObject = context->getShader(shader);
3518
3519 if (!shaderObject)
3520 {
3521 return error(GL_INVALID_OPERATION);
3522 }
3523
3524 shaderObject->getTranslatedSource(bufsize, length, source);
3525 }
3526 }
3527 catch(std::bad_alloc&)
3528 {
3529 return error(GL_OUT_OF_MEMORY);
3530 }
3531}
3532
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003533const GLubyte* __stdcall glGetString(GLenum name)
3534{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003535 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003536
3537 try
3538 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003539 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003540
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003541 switch (name)
3542 {
3543 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003544 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003545 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003546 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003547 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003548 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003549 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003550 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003551 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003552 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003553 default:
3554 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3555 }
3556 }
3557 catch(std::bad_alloc&)
3558 {
3559 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3560 }
3561
3562 return NULL;
3563}
3564
3565void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3566{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003567 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 +00003568
3569 try
3570 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003571 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003572
3573 if (context)
3574 {
3575 gl::Texture *texture;
3576
3577 switch (target)
3578 {
3579 case GL_TEXTURE_2D:
3580 texture = context->getTexture2D();
3581 break;
3582 case GL_TEXTURE_CUBE_MAP:
3583 texture = context->getTextureCubeMap();
3584 break;
3585 default:
3586 return error(GL_INVALID_ENUM);
3587 }
3588
3589 switch (pname)
3590 {
3591 case GL_TEXTURE_MAG_FILTER:
3592 *params = (GLfloat)texture->getMagFilter();
3593 break;
3594 case GL_TEXTURE_MIN_FILTER:
3595 *params = (GLfloat)texture->getMinFilter();
3596 break;
3597 case GL_TEXTURE_WRAP_S:
3598 *params = (GLfloat)texture->getWrapS();
3599 break;
3600 case GL_TEXTURE_WRAP_T:
3601 *params = (GLfloat)texture->getWrapT();
3602 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003603 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3604 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3605 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003606 case GL_TEXTURE_USAGE_ANGLE:
3607 *params = (GLfloat)texture->getUsage();
3608 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003609 default:
3610 return error(GL_INVALID_ENUM);
3611 }
3612 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003613 }
3614 catch(std::bad_alloc&)
3615 {
3616 return error(GL_OUT_OF_MEMORY);
3617 }
3618}
3619
3620void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3621{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003622 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 +00003623
3624 try
3625 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003626 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003627
3628 if (context)
3629 {
3630 gl::Texture *texture;
3631
3632 switch (target)
3633 {
3634 case GL_TEXTURE_2D:
3635 texture = context->getTexture2D();
3636 break;
3637 case GL_TEXTURE_CUBE_MAP:
3638 texture = context->getTextureCubeMap();
3639 break;
3640 default:
3641 return error(GL_INVALID_ENUM);
3642 }
3643
3644 switch (pname)
3645 {
3646 case GL_TEXTURE_MAG_FILTER:
3647 *params = texture->getMagFilter();
3648 break;
3649 case GL_TEXTURE_MIN_FILTER:
3650 *params = texture->getMinFilter();
3651 break;
3652 case GL_TEXTURE_WRAP_S:
3653 *params = texture->getWrapS();
3654 break;
3655 case GL_TEXTURE_WRAP_T:
3656 *params = texture->getWrapT();
3657 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003658 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3659 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3660 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003661 case GL_TEXTURE_USAGE_ANGLE:
3662 *params = texture->getUsage();
3663 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003664 default:
3665 return error(GL_INVALID_ENUM);
3666 }
3667 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003668 }
3669 catch(std::bad_alloc&)
3670 {
3671 return error(GL_OUT_OF_MEMORY);
3672 }
3673}
3674
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003675void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3676{
3677 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3678 program, location, bufSize, params);
3679
3680 try
3681 {
3682 if (bufSize < 0)
3683 {
3684 return error(GL_INVALID_VALUE);
3685 }
3686
3687 gl::Context *context = gl::getNonLostContext();
3688
3689 if (context)
3690 {
3691 if (program == 0)
3692 {
3693 return error(GL_INVALID_VALUE);
3694 }
3695
3696 gl::Program *programObject = context->getProgram(program);
3697
3698 if (!programObject || !programObject->isLinked())
3699 {
3700 return error(GL_INVALID_OPERATION);
3701 }
3702
3703 if (!programObject->getUniformfv(location, &bufSize, params))
3704 {
3705 return error(GL_INVALID_OPERATION);
3706 }
3707 }
3708 }
3709 catch(std::bad_alloc&)
3710 {
3711 return error(GL_OUT_OF_MEMORY);
3712 }
3713}
3714
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003715void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3716{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003717 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003718
3719 try
3720 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003721 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003722
3723 if (context)
3724 {
3725 if (program == 0)
3726 {
3727 return error(GL_INVALID_VALUE);
3728 }
3729
3730 gl::Program *programObject = context->getProgram(program);
3731
3732 if (!programObject || !programObject->isLinked())
3733 {
3734 return error(GL_INVALID_OPERATION);
3735 }
3736
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003737 if (!programObject->getUniformfv(location, NULL, params))
3738 {
3739 return error(GL_INVALID_OPERATION);
3740 }
3741 }
3742 }
3743 catch(std::bad_alloc&)
3744 {
3745 return error(GL_OUT_OF_MEMORY);
3746 }
3747}
3748
3749void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3750{
3751 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3752 program, location, bufSize, params);
3753
3754 try
3755 {
3756 if (bufSize < 0)
3757 {
3758 return error(GL_INVALID_VALUE);
3759 }
3760
3761 gl::Context *context = gl::getNonLostContext();
3762
3763 if (context)
3764 {
3765 if (program == 0)
3766 {
3767 return error(GL_INVALID_VALUE);
3768 }
3769
3770 gl::Program *programObject = context->getProgram(program);
3771
3772 if (!programObject || !programObject->isLinked())
3773 {
3774 return error(GL_INVALID_OPERATION);
3775 }
3776
3777 if (!programObject)
3778 {
3779 return error(GL_INVALID_OPERATION);
3780 }
3781
3782 if (!programObject->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003783 {
3784 return error(GL_INVALID_OPERATION);
3785 }
3786 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003787 }
3788 catch(std::bad_alloc&)
3789 {
3790 return error(GL_OUT_OF_MEMORY);
3791 }
3792}
3793
3794void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3795{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003796 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003797
3798 try
3799 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003800 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003801
3802 if (context)
3803 {
3804 if (program == 0)
3805 {
3806 return error(GL_INVALID_VALUE);
3807 }
3808
3809 gl::Program *programObject = context->getProgram(program);
3810
3811 if (!programObject || !programObject->isLinked())
3812 {
3813 return error(GL_INVALID_OPERATION);
3814 }
3815
3816 if (!programObject)
3817 {
3818 return error(GL_INVALID_OPERATION);
3819 }
3820
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003821 if (!programObject->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003822 {
3823 return error(GL_INVALID_OPERATION);
3824 }
3825 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003826 }
3827 catch(std::bad_alloc&)
3828 {
3829 return error(GL_OUT_OF_MEMORY);
3830 }
3831}
3832
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003833int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003834{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003835 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003836
3837 try
3838 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003839 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003840
3841 if (strstr(name, "gl_") == name)
3842 {
3843 return -1;
3844 }
3845
3846 if (context)
3847 {
3848 gl::Program *programObject = context->getProgram(program);
3849
3850 if (!programObject)
3851 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003852 if (context->getShader(program))
3853 {
3854 return error(GL_INVALID_OPERATION, -1);
3855 }
3856 else
3857 {
3858 return error(GL_INVALID_VALUE, -1);
3859 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003860 }
3861
3862 if (!programObject->isLinked())
3863 {
3864 return error(GL_INVALID_OPERATION, -1);
3865 }
3866
daniel@transgaming.com024f1a92011-09-20 16:06:25 +00003867 return programObject->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003868 }
3869 }
3870 catch(std::bad_alloc&)
3871 {
3872 return error(GL_OUT_OF_MEMORY, -1);
3873 }
3874
3875 return -1;
3876}
3877
3878void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3879{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003880 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003881
3882 try
3883 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003884 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003885
daniel@transgaming.come0078962010-04-15 20:45:08 +00003886 if (context)
3887 {
3888 if (index >= gl::MAX_VERTEX_ATTRIBS)
3889 {
3890 return error(GL_INVALID_VALUE);
3891 }
3892
daniel@transgaming.com83921382011-01-08 05:46:00 +00003893 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003894
daniel@transgaming.come0078962010-04-15 20:45:08 +00003895 switch (pname)
3896 {
3897 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003898 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003899 break;
3900 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003901 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003902 break;
3903 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003904 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003905 break;
3906 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003907 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003908 break;
3909 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003910 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003911 break;
3912 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003913 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003914 break;
3915 case GL_CURRENT_VERTEX_ATTRIB:
3916 for (int i = 0; i < 4; ++i)
3917 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003918 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003919 }
3920 break;
3921 default: return error(GL_INVALID_ENUM);
3922 }
3923 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003924 }
3925 catch(std::bad_alloc&)
3926 {
3927 return error(GL_OUT_OF_MEMORY);
3928 }
3929}
3930
3931void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3932{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003933 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003934
3935 try
3936 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003937 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003938
daniel@transgaming.come0078962010-04-15 20:45:08 +00003939 if (context)
3940 {
3941 if (index >= gl::MAX_VERTEX_ATTRIBS)
3942 {
3943 return error(GL_INVALID_VALUE);
3944 }
3945
daniel@transgaming.com83921382011-01-08 05:46:00 +00003946 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003947
daniel@transgaming.come0078962010-04-15 20:45:08 +00003948 switch (pname)
3949 {
3950 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003951 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003952 break;
3953 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003954 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003955 break;
3956 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003957 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003958 break;
3959 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003960 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003961 break;
3962 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003963 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003964 break;
3965 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003966 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003967 break;
3968 case GL_CURRENT_VERTEX_ATTRIB:
3969 for (int i = 0; i < 4; ++i)
3970 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003971 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003972 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3973 }
3974 break;
3975 default: return error(GL_INVALID_ENUM);
3976 }
3977 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003978 }
3979 catch(std::bad_alloc&)
3980 {
3981 return error(GL_OUT_OF_MEMORY);
3982 }
3983}
3984
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003985void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003986{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003987 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003988
3989 try
3990 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003991 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003992
daniel@transgaming.come0078962010-04-15 20:45:08 +00003993 if (context)
3994 {
3995 if (index >= gl::MAX_VERTEX_ATTRIBS)
3996 {
3997 return error(GL_INVALID_VALUE);
3998 }
3999
4000 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4001 {
4002 return error(GL_INVALID_ENUM);
4003 }
4004
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004005 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00004006 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004007 }
4008 catch(std::bad_alloc&)
4009 {
4010 return error(GL_OUT_OF_MEMORY);
4011 }
4012}
4013
4014void __stdcall glHint(GLenum target, GLenum mode)
4015{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004016 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004017
4018 try
4019 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004020 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004021 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004022 case GL_FASTEST:
4023 case GL_NICEST:
4024 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004025 break;
4026 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004027 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004028 }
4029
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004030 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004031 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004032 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004033 case GL_GENERATE_MIPMAP_HINT:
4034 if (context) context->setGenerateMipmapHint(mode);
4035 break;
4036 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4037 if (context) context->setFragmentShaderDerivativeHint(mode);
4038 break;
4039 default:
4040 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004041 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004042 }
4043 catch(std::bad_alloc&)
4044 {
4045 return error(GL_OUT_OF_MEMORY);
4046 }
4047}
4048
4049GLboolean __stdcall glIsBuffer(GLuint buffer)
4050{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004051 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004052
4053 try
4054 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004055 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004056
4057 if (context && buffer)
4058 {
4059 gl::Buffer *bufferObject = context->getBuffer(buffer);
4060
4061 if (bufferObject)
4062 {
4063 return GL_TRUE;
4064 }
4065 }
4066 }
4067 catch(std::bad_alloc&)
4068 {
4069 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4070 }
4071
4072 return GL_FALSE;
4073}
4074
4075GLboolean __stdcall glIsEnabled(GLenum cap)
4076{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004077 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004078
4079 try
4080 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004081 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004082
4083 if (context)
4084 {
4085 switch (cap)
4086 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004087 case GL_CULL_FACE: return context->isCullFaceEnabled();
4088 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4089 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4090 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4091 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4092 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4093 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4094 case GL_BLEND: return context->isBlendEnabled();
4095 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004096 default:
4097 return error(GL_INVALID_ENUM, false);
4098 }
4099 }
4100 }
4101 catch(std::bad_alloc&)
4102 {
4103 return error(GL_OUT_OF_MEMORY, false);
4104 }
4105
4106 return false;
4107}
4108
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004109GLboolean __stdcall glIsFenceNV(GLuint fence)
4110{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004111 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004112
4113 try
4114 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004115 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004116
4117 if (context)
4118 {
4119 gl::Fence *fenceObject = context->getFence(fence);
4120
4121 if (fenceObject == NULL)
4122 {
4123 return GL_FALSE;
4124 }
4125
4126 return fenceObject->isFence();
4127 }
4128 }
4129 catch(std::bad_alloc&)
4130 {
4131 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4132 }
4133
4134 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004135}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004136
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004137GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
4138{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004139 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004140
4141 try
4142 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004143 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004144
4145 if (context && framebuffer)
4146 {
4147 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4148
4149 if (framebufferObject)
4150 {
4151 return GL_TRUE;
4152 }
4153 }
4154 }
4155 catch(std::bad_alloc&)
4156 {
4157 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4158 }
4159
4160 return GL_FALSE;
4161}
4162
4163GLboolean __stdcall glIsProgram(GLuint program)
4164{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004165 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004166
4167 try
4168 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004169 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004170
4171 if (context && program)
4172 {
4173 gl::Program *programObject = context->getProgram(program);
4174
4175 if (programObject)
4176 {
4177 return GL_TRUE;
4178 }
4179 }
4180 }
4181 catch(std::bad_alloc&)
4182 {
4183 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4184 }
4185
4186 return GL_FALSE;
4187}
4188
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00004189GLboolean __stdcall glIsQueryEXT(GLuint id)
4190{
4191 EVENT("(GLuint id = %d)", id);
4192
4193 try
4194 {
4195 if (id == 0)
4196 {
4197 return GL_FALSE;
4198 }
4199
4200 gl::Context *context = gl::getNonLostContext();
4201
4202 if (context)
4203 {
4204 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
4205
4206 if (queryObject)
4207 {
4208 return GL_TRUE;
4209 }
4210 }
4211 }
4212 catch(std::bad_alloc&)
4213 {
4214 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4215 }
4216
4217 return GL_FALSE;
4218}
4219
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004220GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
4221{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004222 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004223
4224 try
4225 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004226 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004227
4228 if (context && renderbuffer)
4229 {
4230 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4231
4232 if (renderbufferObject)
4233 {
4234 return GL_TRUE;
4235 }
4236 }
4237 }
4238 catch(std::bad_alloc&)
4239 {
4240 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4241 }
4242
4243 return GL_FALSE;
4244}
4245
4246GLboolean __stdcall glIsShader(GLuint shader)
4247{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004248 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004249
4250 try
4251 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004252 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004253
4254 if (context && shader)
4255 {
4256 gl::Shader *shaderObject = context->getShader(shader);
4257
4258 if (shaderObject)
4259 {
4260 return GL_TRUE;
4261 }
4262 }
4263 }
4264 catch(std::bad_alloc&)
4265 {
4266 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4267 }
4268
4269 return GL_FALSE;
4270}
4271
4272GLboolean __stdcall glIsTexture(GLuint texture)
4273{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004274 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004275
4276 try
4277 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004278 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004279
4280 if (context && texture)
4281 {
4282 gl::Texture *textureObject = context->getTexture(texture);
4283
4284 if (textureObject)
4285 {
4286 return GL_TRUE;
4287 }
4288 }
4289 }
4290 catch(std::bad_alloc&)
4291 {
4292 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4293 }
4294
4295 return GL_FALSE;
4296}
4297
4298void __stdcall glLineWidth(GLfloat width)
4299{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004300 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004301
4302 try
4303 {
4304 if (width <= 0.0f)
4305 {
4306 return error(GL_INVALID_VALUE);
4307 }
4308
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004309 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004310
4311 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004312 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004313 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004314 }
4315 }
4316 catch(std::bad_alloc&)
4317 {
4318 return error(GL_OUT_OF_MEMORY);
4319 }
4320}
4321
4322void __stdcall glLinkProgram(GLuint program)
4323{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004324 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004325
4326 try
4327 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004328 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004329
4330 if (context)
4331 {
4332 gl::Program *programObject = context->getProgram(program);
4333
4334 if (!programObject)
4335 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004336 if (context->getShader(program))
4337 {
4338 return error(GL_INVALID_OPERATION);
4339 }
4340 else
4341 {
4342 return error(GL_INVALID_VALUE);
4343 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004344 }
4345
4346 programObject->link();
4347 }
4348 }
4349 catch(std::bad_alloc&)
4350 {
4351 return error(GL_OUT_OF_MEMORY);
4352 }
4353}
4354
4355void __stdcall glPixelStorei(GLenum pname, GLint param)
4356{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004357 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004358
4359 try
4360 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004361 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004362
4363 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004364 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004365 switch (pname)
4366 {
4367 case GL_UNPACK_ALIGNMENT:
4368 if (param != 1 && param != 2 && param != 4 && param != 8)
4369 {
4370 return error(GL_INVALID_VALUE);
4371 }
4372
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004373 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004374 break;
4375
4376 case GL_PACK_ALIGNMENT:
4377 if (param != 1 && param != 2 && param != 4 && param != 8)
4378 {
4379 return error(GL_INVALID_VALUE);
4380 }
4381
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004382 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004383 break;
4384
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004385 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4386 context->setPackReverseRowOrder(param != 0);
4387 break;
4388
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004389 default:
4390 return error(GL_INVALID_ENUM);
4391 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004392 }
4393 }
4394 catch(std::bad_alloc&)
4395 {
4396 return error(GL_OUT_OF_MEMORY);
4397 }
4398}
4399
4400void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4401{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004402 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004403
4404 try
4405 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004406 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004407
4408 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004409 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004410 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004411 }
4412 }
4413 catch(std::bad_alloc&)
4414 {
4415 return error(GL_OUT_OF_MEMORY);
4416 }
4417}
4418
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004419void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4420 GLenum format, GLenum type, GLsizei bufSize,
4421 GLvoid *data)
4422{
4423 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4424 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4425 x, y, width, height, format, type, bufSize, data);
4426
4427 try
4428 {
4429 if (width < 0 || height < 0 || bufSize < 0)
4430 {
4431 return error(GL_INVALID_VALUE);
4432 }
4433
4434 if (!validReadFormatType(format, type))
4435 {
4436 return error(GL_INVALID_OPERATION);
4437 }
4438
4439 gl::Context *context = gl::getNonLostContext();
4440
4441 if (context)
4442 {
4443 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4444 }
4445 }
4446 catch(std::bad_alloc&)
4447 {
4448 return error(GL_OUT_OF_MEMORY);
4449 }
4450}
4451
4452void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4453 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004454{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004455 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004456 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004457 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004458
4459 try
4460 {
4461 if (width < 0 || height < 0)
4462 {
4463 return error(GL_INVALID_VALUE);
4464 }
4465
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004466 if (!validReadFormatType(format, type))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004467 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004468 return error(GL_INVALID_OPERATION);
4469 }
4470
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004471 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004472
4473 if (context)
4474 {
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004475 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004476 }
4477 }
4478 catch(std::bad_alloc&)
4479 {
4480 return error(GL_OUT_OF_MEMORY);
4481 }
4482}
4483
4484void __stdcall glReleaseShaderCompiler(void)
4485{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004486 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004487
4488 try
4489 {
4490 gl::Shader::releaseCompiler();
4491 }
4492 catch(std::bad_alloc&)
4493 {
4494 return error(GL_OUT_OF_MEMORY);
4495 }
4496}
4497
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004498void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004499{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004500 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 +00004501 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004502
4503 try
4504 {
4505 switch (target)
4506 {
4507 case GL_RENDERBUFFER:
4508 break;
4509 default:
4510 return error(GL_INVALID_ENUM);
4511 }
4512
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004513 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004514 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004515 return error(GL_INVALID_ENUM);
4516 }
4517
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004518 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004519 {
4520 return error(GL_INVALID_VALUE);
4521 }
4522
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004523 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004524
4525 if (context)
4526 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004527 if (width > context->getMaximumRenderbufferDimension() ||
4528 height > context->getMaximumRenderbufferDimension() ||
4529 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004530 {
4531 return error(GL_INVALID_VALUE);
4532 }
4533
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004534 GLuint handle = context->getRenderbufferHandle();
4535 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004536 {
4537 return error(GL_INVALID_OPERATION);
4538 }
4539
4540 switch (internalformat)
4541 {
4542 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004543 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004544 break;
4545 case GL_RGBA4:
4546 case GL_RGB5_A1:
4547 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004548 case GL_RGB8_OES:
4549 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004550 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004551 break;
4552 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004553 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004554 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004555 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004556 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004557 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004558 default:
4559 return error(GL_INVALID_ENUM);
4560 }
4561 }
4562 }
4563 catch(std::bad_alloc&)
4564 {
4565 return error(GL_OUT_OF_MEMORY);
4566 }
4567}
4568
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004569void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4570{
4571 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4572}
4573
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004574void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4575{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004576 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004577
4578 try
4579 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004580 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004581
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004582 if (context)
4583 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004584 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004585 }
4586 }
4587 catch(std::bad_alloc&)
4588 {
4589 return error(GL_OUT_OF_MEMORY);
4590 }
4591}
4592
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004593void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4594{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004595 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004596
4597 try
4598 {
4599 if (condition != GL_ALL_COMPLETED_NV)
4600 {
4601 return error(GL_INVALID_ENUM);
4602 }
4603
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004604 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004605
4606 if (context)
4607 {
4608 gl::Fence *fenceObject = context->getFence(fence);
4609
4610 if (fenceObject == NULL)
4611 {
4612 return error(GL_INVALID_OPERATION);
4613 }
4614
4615 fenceObject->setFence(condition);
4616 }
4617 }
4618 catch(std::bad_alloc&)
4619 {
4620 return error(GL_OUT_OF_MEMORY);
4621 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004622}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004623
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004624void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4625{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004626 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 +00004627
4628 try
4629 {
4630 if (width < 0 || height < 0)
4631 {
4632 return error(GL_INVALID_VALUE);
4633 }
4634
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004635 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004636
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004637 if (context)
4638 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004639 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004640 }
4641 }
4642 catch(std::bad_alloc&)
4643 {
4644 return error(GL_OUT_OF_MEMORY);
4645 }
4646}
4647
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004648void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004649{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004650 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004651 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004652 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004653
4654 try
4655 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004656 // No binary shader formats are supported.
4657 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004658 }
4659 catch(std::bad_alloc&)
4660 {
4661 return error(GL_OUT_OF_MEMORY);
4662 }
4663}
4664
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004665void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004666{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004667 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 +00004668 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004669
4670 try
4671 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004672 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004673 {
4674 return error(GL_INVALID_VALUE);
4675 }
4676
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004677 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004678
4679 if (context)
4680 {
4681 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004682
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004683 if (!shaderObject)
4684 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004685 if (context->getProgram(shader))
4686 {
4687 return error(GL_INVALID_OPERATION);
4688 }
4689 else
4690 {
4691 return error(GL_INVALID_VALUE);
4692 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004693 }
4694
4695 shaderObject->setSource(count, string, length);
4696 }
4697 }
4698 catch(std::bad_alloc&)
4699 {
4700 return error(GL_OUT_OF_MEMORY);
4701 }
4702}
4703
4704void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4705{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004706 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004707}
4708
4709void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4710{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004711 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 +00004712
4713 try
4714 {
4715 switch (face)
4716 {
4717 case GL_FRONT:
4718 case GL_BACK:
4719 case GL_FRONT_AND_BACK:
4720 break;
4721 default:
4722 return error(GL_INVALID_ENUM);
4723 }
4724
4725 switch (func)
4726 {
4727 case GL_NEVER:
4728 case GL_ALWAYS:
4729 case GL_LESS:
4730 case GL_LEQUAL:
4731 case GL_EQUAL:
4732 case GL_GEQUAL:
4733 case GL_GREATER:
4734 case GL_NOTEQUAL:
4735 break;
4736 default:
4737 return error(GL_INVALID_ENUM);
4738 }
4739
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004740 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004741
4742 if (context)
4743 {
4744 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4745 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004746 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004747 }
4748
4749 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4750 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004751 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004752 }
4753 }
4754 }
4755 catch(std::bad_alloc&)
4756 {
4757 return error(GL_OUT_OF_MEMORY);
4758 }
4759}
4760
4761void __stdcall glStencilMask(GLuint mask)
4762{
4763 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4764}
4765
4766void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4767{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004768 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004769
4770 try
4771 {
4772 switch (face)
4773 {
4774 case GL_FRONT:
4775 case GL_BACK:
4776 case GL_FRONT_AND_BACK:
4777 break;
4778 default:
4779 return error(GL_INVALID_ENUM);
4780 }
4781
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004782 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004783
4784 if (context)
4785 {
4786 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4787 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004788 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004789 }
4790
4791 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4792 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004793 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004794 }
4795 }
4796 }
4797 catch(std::bad_alloc&)
4798 {
4799 return error(GL_OUT_OF_MEMORY);
4800 }
4801}
4802
4803void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4804{
4805 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4806}
4807
4808void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4809{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004810 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 +00004811 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004812
4813 try
4814 {
4815 switch (face)
4816 {
4817 case GL_FRONT:
4818 case GL_BACK:
4819 case GL_FRONT_AND_BACK:
4820 break;
4821 default:
4822 return error(GL_INVALID_ENUM);
4823 }
4824
4825 switch (fail)
4826 {
4827 case GL_ZERO:
4828 case GL_KEEP:
4829 case GL_REPLACE:
4830 case GL_INCR:
4831 case GL_DECR:
4832 case GL_INVERT:
4833 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004834 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004835 break;
4836 default:
4837 return error(GL_INVALID_ENUM);
4838 }
4839
4840 switch (zfail)
4841 {
4842 case GL_ZERO:
4843 case GL_KEEP:
4844 case GL_REPLACE:
4845 case GL_INCR:
4846 case GL_DECR:
4847 case GL_INVERT:
4848 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004849 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004850 break;
4851 default:
4852 return error(GL_INVALID_ENUM);
4853 }
4854
4855 switch (zpass)
4856 {
4857 case GL_ZERO:
4858 case GL_KEEP:
4859 case GL_REPLACE:
4860 case GL_INCR:
4861 case GL_DECR:
4862 case GL_INVERT:
4863 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004864 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004865 break;
4866 default:
4867 return error(GL_INVALID_ENUM);
4868 }
4869
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004870 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004871
4872 if (context)
4873 {
4874 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4875 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004876 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004877 }
4878
4879 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4880 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004881 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004882 }
4883 }
4884 }
4885 catch(std::bad_alloc&)
4886 {
4887 return error(GL_OUT_OF_MEMORY);
4888 }
4889}
4890
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004891GLboolean __stdcall glTestFenceNV(GLuint fence)
4892{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004893 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004894
4895 try
4896 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004897 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004898
4899 if (context)
4900 {
4901 gl::Fence *fenceObject = context->getFence(fence);
4902
4903 if (fenceObject == NULL)
4904 {
4905 return error(GL_INVALID_OPERATION, GL_TRUE);
4906 }
4907
4908 return fenceObject->testFence();
4909 }
4910 }
4911 catch(std::bad_alloc&)
4912 {
4913 error(GL_OUT_OF_MEMORY);
4914 }
4915
4916 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004917}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004918
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004919void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4920 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004921{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004922 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 +00004923 "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 +00004924 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004925
4926 try
4927 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00004928 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004929 {
4930 return error(GL_INVALID_VALUE);
4931 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004932
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004933 if (internalformat != format)
4934 {
4935 return error(GL_INVALID_OPERATION);
4936 }
4937
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004938 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004939 {
4940 case GL_ALPHA:
4941 case GL_LUMINANCE:
4942 case GL_LUMINANCE_ALPHA:
4943 switch (type)
4944 {
4945 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004946 case GL_FLOAT:
4947 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004948 break;
4949 default:
4950 return error(GL_INVALID_ENUM);
4951 }
4952 break;
4953 case GL_RGB:
4954 switch (type)
4955 {
4956 case GL_UNSIGNED_BYTE:
4957 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004958 case GL_FLOAT:
4959 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004960 break;
4961 default:
4962 return error(GL_INVALID_ENUM);
4963 }
4964 break;
4965 case GL_RGBA:
4966 switch (type)
4967 {
4968 case GL_UNSIGNED_BYTE:
4969 case GL_UNSIGNED_SHORT_4_4_4_4:
4970 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004971 case GL_FLOAT:
4972 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004973 break;
4974 default:
4975 return error(GL_INVALID_ENUM);
4976 }
4977 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004978 case GL_BGRA_EXT:
4979 switch (type)
4980 {
4981 case GL_UNSIGNED_BYTE:
4982 break;
4983 default:
4984 return error(GL_INVALID_ENUM);
4985 }
4986 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004987 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4988 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00004989 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4990 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00004991 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004992 default:
4993 return error(GL_INVALID_VALUE);
4994 }
4995
4996 if (border != 0)
4997 {
4998 return error(GL_INVALID_VALUE);
4999 }
5000
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005001 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005002
5003 if (context)
5004 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00005005 if (level > context->getMaximumTextureLevel())
5006 {
5007 return error(GL_INVALID_VALUE);
5008 }
5009
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005010 switch (target)
5011 {
5012 case GL_TEXTURE_2D:
5013 if (width > (context->getMaximumTextureDimension() >> level) ||
5014 height > (context->getMaximumTextureDimension() >> level))
5015 {
5016 return error(GL_INVALID_VALUE);
5017 }
5018 break;
5019 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5020 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5021 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5022 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5023 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5024 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5025 if (width != height)
5026 {
5027 return error(GL_INVALID_VALUE);
5028 }
5029
5030 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
5031 height > (context->getMaximumCubeTextureDimension() >> level))
5032 {
5033 return error(GL_INVALID_VALUE);
5034 }
5035 break;
5036 default:
5037 return error(GL_INVALID_ENUM);
5038 }
5039
gman@chromium.org50c526d2011-08-10 05:19:44 +00005040 switch (format) {
5041 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5042 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5043 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00005044 {
5045 return error(GL_INVALID_OPERATION);
5046 }
5047 else
5048 {
5049 return error(GL_INVALID_ENUM);
5050 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00005051 break;
5052 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5053 if (context->supportsDXT3Textures())
5054 {
5055 return error(GL_INVALID_OPERATION);
5056 }
5057 else
5058 {
5059 return error(GL_INVALID_ENUM);
5060 }
5061 break;
5062 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5063 if (context->supportsDXT5Textures())
5064 {
5065 return error(GL_INVALID_OPERATION);
5066 }
5067 else
5068 {
5069 return error(GL_INVALID_ENUM);
5070 }
5071 break;
5072 default:
5073 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005074 }
5075
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005076 if (type == GL_FLOAT)
5077 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005078 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005079 {
5080 return error(GL_INVALID_ENUM);
5081 }
5082 }
5083 else if (type == GL_HALF_FLOAT_OES)
5084 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005085 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005086 {
5087 return error(GL_INVALID_ENUM);
5088 }
5089 }
5090
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005091 if (target == GL_TEXTURE_2D)
5092 {
5093 gl::Texture2D *texture = context->getTexture2D();
5094
5095 if (!texture)
5096 {
5097 return error(GL_INVALID_OPERATION);
5098 }
5099
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005100 if (texture->isImmutable())
5101 {
5102 return error(GL_INVALID_OPERATION);
5103 }
5104
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005105 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005106 }
5107 else
5108 {
5109 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5110
5111 if (!texture)
5112 {
5113 return error(GL_INVALID_OPERATION);
5114 }
5115
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005116 if (texture->isImmutable())
5117 {
5118 return error(GL_INVALID_OPERATION);
5119 }
5120
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005121 switch (target)
5122 {
5123 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005124 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005125 break;
5126 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005127 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005128 break;
5129 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005130 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005131 break;
5132 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005133 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005134 break;
5135 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005136 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005137 break;
5138 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005139 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005140 break;
5141 default: UNREACHABLE();
5142 }
5143 }
5144 }
5145 }
5146 catch(std::bad_alloc&)
5147 {
5148 return error(GL_OUT_OF_MEMORY);
5149 }
5150}
5151
5152void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5153{
5154 glTexParameteri(target, pname, (GLint)param);
5155}
5156
5157void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5158{
5159 glTexParameteri(target, pname, (GLint)*params);
5160}
5161
5162void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
5163{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005164 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005165
5166 try
5167 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005168 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005169
5170 if (context)
5171 {
5172 gl::Texture *texture;
5173
5174 switch (target)
5175 {
5176 case GL_TEXTURE_2D:
5177 texture = context->getTexture2D();
5178 break;
5179 case GL_TEXTURE_CUBE_MAP:
5180 texture = context->getTextureCubeMap();
5181 break;
5182 default:
5183 return error(GL_INVALID_ENUM);
5184 }
5185
5186 switch (pname)
5187 {
5188 case GL_TEXTURE_WRAP_S:
5189 if (!texture->setWrapS((GLenum)param))
5190 {
5191 return error(GL_INVALID_ENUM);
5192 }
5193 break;
5194 case GL_TEXTURE_WRAP_T:
5195 if (!texture->setWrapT((GLenum)param))
5196 {
5197 return error(GL_INVALID_ENUM);
5198 }
5199 break;
5200 case GL_TEXTURE_MIN_FILTER:
5201 if (!texture->setMinFilter((GLenum)param))
5202 {
5203 return error(GL_INVALID_ENUM);
5204 }
5205 break;
5206 case GL_TEXTURE_MAG_FILTER:
5207 if (!texture->setMagFilter((GLenum)param))
5208 {
5209 return error(GL_INVALID_ENUM);
5210 }
5211 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00005212 case GL_TEXTURE_USAGE_ANGLE:
5213 if (!texture->setUsage((GLenum)param))
5214 {
5215 return error(GL_INVALID_ENUM);
5216 }
5217 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005218 default:
5219 return error(GL_INVALID_ENUM);
5220 }
5221 }
5222 }
5223 catch(std::bad_alloc&)
5224 {
5225 return error(GL_OUT_OF_MEMORY);
5226 }
5227}
5228
5229void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5230{
5231 glTexParameteri(target, pname, *params);
5232}
5233
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005234void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5235{
5236 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5237 target, levels, internalformat, width, height);
5238
5239 try
5240 {
5241 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5242 {
5243 return error(GL_INVALID_ENUM);
5244 }
5245
5246 if (width < 1 || height < 1 || levels < 1)
5247 {
5248 return error(GL_INVALID_VALUE);
5249 }
5250
5251 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5252 {
5253 return error(GL_INVALID_VALUE);
5254 }
5255
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005256 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005257 {
5258 return error(GL_INVALID_OPERATION);
5259 }
5260
5261 GLenum format = gl::ExtractFormat(internalformat);
5262 GLenum type = gl::ExtractType(internalformat);
5263
5264 if (format == GL_NONE || type == GL_NONE)
5265 {
5266 return error(GL_INVALID_ENUM);
5267 }
5268
5269 gl::Context *context = gl::getNonLostContext();
5270
5271 if (context)
5272 {
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005273 switch (target)
5274 {
5275 case GL_TEXTURE_2D:
5276 if (width > context->getMaximumTextureDimension() ||
5277 height > context->getMaximumTextureDimension())
5278 {
5279 return error(GL_INVALID_VALUE);
5280 }
5281 break;
5282 case GL_TEXTURE_CUBE_MAP:
5283 if (width > context->getMaximumCubeTextureDimension() ||
5284 height > context->getMaximumCubeTextureDimension())
5285 {
5286 return error(GL_INVALID_VALUE);
5287 }
5288 break;
5289 default:
5290 return error(GL_INVALID_ENUM);
5291 }
5292
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005293 if (levels != 1 && !context->supportsNonPower2Texture())
5294 {
5295 if (!gl::isPow2(width) || !gl::isPow2(height))
5296 {
5297 return error(GL_INVALID_OPERATION);
5298 }
5299 }
5300
daniel@transgaming.come1077362011-11-11 04:16:50 +00005301 switch (internalformat)
5302 {
5303 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5304 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5305 if (!context->supportsDXT1Textures())
5306 {
5307 return error(GL_INVALID_ENUM);
5308 }
5309 break;
5310 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5311 if (!context->supportsDXT3Textures())
5312 {
5313 return error(GL_INVALID_ENUM);
5314 }
5315 break;
5316 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5317 if (!context->supportsDXT5Textures())
5318 {
5319 return error(GL_INVALID_ENUM);
5320 }
5321 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005322 case GL_RGBA32F_EXT:
5323 case GL_RGB32F_EXT:
5324 case GL_ALPHA32F_EXT:
5325 case GL_LUMINANCE32F_EXT:
5326 case GL_LUMINANCE_ALPHA32F_EXT:
5327 if (!context->supportsFloat32Textures())
5328 {
5329 return error(GL_INVALID_ENUM);
5330 }
5331 break;
5332 case GL_RGBA16F_EXT:
5333 case GL_RGB16F_EXT:
5334 case GL_ALPHA16F_EXT:
5335 case GL_LUMINANCE16F_EXT:
5336 case GL_LUMINANCE_ALPHA16F_EXT:
5337 if (!context->supportsFloat16Textures())
5338 {
5339 return error(GL_INVALID_ENUM);
5340 }
5341 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005342 }
5343
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005344 if (target == GL_TEXTURE_2D)
5345 {
5346 gl::Texture2D *texture = context->getTexture2D();
5347
5348 if (!texture || texture->id() == 0)
5349 {
5350 return error(GL_INVALID_OPERATION);
5351 }
5352
5353 if (texture->isImmutable())
5354 {
5355 return error(GL_INVALID_OPERATION);
5356 }
5357
5358 texture->storage(levels, internalformat, width, height);
5359 }
5360 else if (target == GL_TEXTURE_CUBE_MAP)
5361 {
5362 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5363
5364 if (!texture || texture->id() == 0)
5365 {
5366 return error(GL_INVALID_OPERATION);
5367 }
5368
5369 if (texture->isImmutable())
5370 {
5371 return error(GL_INVALID_OPERATION);
5372 }
5373
5374 texture->storage(levels, internalformat, width);
5375 }
5376 else UNREACHABLE();
5377 }
5378 }
5379 catch(std::bad_alloc&)
5380 {
5381 return error(GL_OUT_OF_MEMORY);
5382 }
5383}
5384
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005385void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5386 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005387{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005388 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005389 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005390 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005391 target, level, xoffset, yoffset, width, height, format, type, pixels);
5392
5393 try
5394 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005395 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005396 {
5397 return error(GL_INVALID_ENUM);
5398 }
5399
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005400 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005401 {
5402 return error(GL_INVALID_VALUE);
5403 }
5404
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005405 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5406 {
5407 return error(GL_INVALID_VALUE);
5408 }
5409
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005410 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005411 {
5412 return error(GL_INVALID_ENUM);
5413 }
5414
5415 if (width == 0 || height == 0 || pixels == NULL)
5416 {
5417 return;
5418 }
5419
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005420 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005421
5422 if (context)
5423 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005424 if (level > context->getMaximumTextureLevel())
5425 {
5426 return error(GL_INVALID_VALUE);
5427 }
5428
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005429 if (format == GL_FLOAT)
5430 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005431 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005432 {
5433 return error(GL_INVALID_ENUM);
5434 }
5435 }
5436 else if (format == GL_HALF_FLOAT_OES)
5437 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005438 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005439 {
5440 return error(GL_INVALID_ENUM);
5441 }
5442 }
5443
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005444 if (target == GL_TEXTURE_2D)
5445 {
5446 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005447 if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005448 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005449 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005450 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005451 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005452 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005453 {
5454 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005455 if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005456 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005457 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005458 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005459 }
5460 else
5461 {
5462 UNREACHABLE();
5463 }
5464 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005465 }
5466 catch(std::bad_alloc&)
5467 {
5468 return error(GL_OUT_OF_MEMORY);
5469 }
5470}
5471
5472void __stdcall glUniform1f(GLint location, GLfloat x)
5473{
5474 glUniform1fv(location, 1, &x);
5475}
5476
5477void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5478{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005479 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005480
5481 try
5482 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005483 if (count < 0)
5484 {
5485 return error(GL_INVALID_VALUE);
5486 }
5487
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005488 if (location == -1)
5489 {
5490 return;
5491 }
5492
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005493 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005494
5495 if (context)
5496 {
5497 gl::Program *program = context->getCurrentProgram();
5498
5499 if (!program)
5500 {
5501 return error(GL_INVALID_OPERATION);
5502 }
5503
5504 if (!program->setUniform1fv(location, count, v))
5505 {
5506 return error(GL_INVALID_OPERATION);
5507 }
5508 }
5509 }
5510 catch(std::bad_alloc&)
5511 {
5512 return error(GL_OUT_OF_MEMORY);
5513 }
5514}
5515
5516void __stdcall glUniform1i(GLint location, GLint x)
5517{
5518 glUniform1iv(location, 1, &x);
5519}
5520
5521void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5522{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005523 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005524
5525 try
5526 {
5527 if (count < 0)
5528 {
5529 return error(GL_INVALID_VALUE);
5530 }
5531
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005532 if (location == -1)
5533 {
5534 return;
5535 }
5536
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005537 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005538
5539 if (context)
5540 {
5541 gl::Program *program = context->getCurrentProgram();
5542
5543 if (!program)
5544 {
5545 return error(GL_INVALID_OPERATION);
5546 }
5547
5548 if (!program->setUniform1iv(location, count, v))
5549 {
5550 return error(GL_INVALID_OPERATION);
5551 }
5552 }
5553 }
5554 catch(std::bad_alloc&)
5555 {
5556 return error(GL_OUT_OF_MEMORY);
5557 }
5558}
5559
5560void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5561{
5562 GLfloat xy[2] = {x, y};
5563
5564 glUniform2fv(location, 1, (GLfloat*)&xy);
5565}
5566
5567void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5568{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005569 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005570
5571 try
5572 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005573 if (count < 0)
5574 {
5575 return error(GL_INVALID_VALUE);
5576 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005577
5578 if (location == -1)
5579 {
5580 return;
5581 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005582
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005583 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005584
5585 if (context)
5586 {
5587 gl::Program *program = context->getCurrentProgram();
5588
5589 if (!program)
5590 {
5591 return error(GL_INVALID_OPERATION);
5592 }
5593
5594 if (!program->setUniform2fv(location, count, v))
5595 {
5596 return error(GL_INVALID_OPERATION);
5597 }
5598 }
5599 }
5600 catch(std::bad_alloc&)
5601 {
5602 return error(GL_OUT_OF_MEMORY);
5603 }
5604}
5605
5606void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5607{
5608 GLint xy[4] = {x, y};
5609
5610 glUniform2iv(location, 1, (GLint*)&xy);
5611}
5612
5613void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5614{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005615 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005616
5617 try
5618 {
5619 if (count < 0)
5620 {
5621 return error(GL_INVALID_VALUE);
5622 }
5623
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005624 if (location == -1)
5625 {
5626 return;
5627 }
5628
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005629 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005630
5631 if (context)
5632 {
5633 gl::Program *program = context->getCurrentProgram();
5634
5635 if (!program)
5636 {
5637 return error(GL_INVALID_OPERATION);
5638 }
5639
5640 if (!program->setUniform2iv(location, count, v))
5641 {
5642 return error(GL_INVALID_OPERATION);
5643 }
5644 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005645 }
5646 catch(std::bad_alloc&)
5647 {
5648 return error(GL_OUT_OF_MEMORY);
5649 }
5650}
5651
5652void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5653{
5654 GLfloat xyz[3] = {x, y, z};
5655
5656 glUniform3fv(location, 1, (GLfloat*)&xyz);
5657}
5658
5659void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5660{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005661 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005662
5663 try
5664 {
5665 if (count < 0)
5666 {
5667 return error(GL_INVALID_VALUE);
5668 }
5669
5670 if (location == -1)
5671 {
5672 return;
5673 }
5674
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005675 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005676
5677 if (context)
5678 {
5679 gl::Program *program = context->getCurrentProgram();
5680
5681 if (!program)
5682 {
5683 return error(GL_INVALID_OPERATION);
5684 }
5685
5686 if (!program->setUniform3fv(location, count, v))
5687 {
5688 return error(GL_INVALID_OPERATION);
5689 }
5690 }
5691 }
5692 catch(std::bad_alloc&)
5693 {
5694 return error(GL_OUT_OF_MEMORY);
5695 }
5696}
5697
5698void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5699{
5700 GLint xyz[3] = {x, y, z};
5701
5702 glUniform3iv(location, 1, (GLint*)&xyz);
5703}
5704
5705void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5706{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005707 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005708
5709 try
5710 {
5711 if (count < 0)
5712 {
5713 return error(GL_INVALID_VALUE);
5714 }
5715
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005716 if (location == -1)
5717 {
5718 return;
5719 }
5720
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005721 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005722
5723 if (context)
5724 {
5725 gl::Program *program = context->getCurrentProgram();
5726
5727 if (!program)
5728 {
5729 return error(GL_INVALID_OPERATION);
5730 }
5731
5732 if (!program->setUniform3iv(location, count, v))
5733 {
5734 return error(GL_INVALID_OPERATION);
5735 }
5736 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005737 }
5738 catch(std::bad_alloc&)
5739 {
5740 return error(GL_OUT_OF_MEMORY);
5741 }
5742}
5743
5744void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5745{
5746 GLfloat xyzw[4] = {x, y, z, w};
5747
5748 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5749}
5750
5751void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5752{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005753 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005754
5755 try
5756 {
5757 if (count < 0)
5758 {
5759 return error(GL_INVALID_VALUE);
5760 }
5761
5762 if (location == -1)
5763 {
5764 return;
5765 }
5766
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005767 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005768
5769 if (context)
5770 {
5771 gl::Program *program = context->getCurrentProgram();
5772
5773 if (!program)
5774 {
5775 return error(GL_INVALID_OPERATION);
5776 }
5777
5778 if (!program->setUniform4fv(location, count, v))
5779 {
5780 return error(GL_INVALID_OPERATION);
5781 }
5782 }
5783 }
5784 catch(std::bad_alloc&)
5785 {
5786 return error(GL_OUT_OF_MEMORY);
5787 }
5788}
5789
5790void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5791{
5792 GLint xyzw[4] = {x, y, z, w};
5793
5794 glUniform4iv(location, 1, (GLint*)&xyzw);
5795}
5796
5797void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5798{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005799 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005800
5801 try
5802 {
5803 if (count < 0)
5804 {
5805 return error(GL_INVALID_VALUE);
5806 }
5807
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005808 if (location == -1)
5809 {
5810 return;
5811 }
5812
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005813 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005814
5815 if (context)
5816 {
5817 gl::Program *program = context->getCurrentProgram();
5818
5819 if (!program)
5820 {
5821 return error(GL_INVALID_OPERATION);
5822 }
5823
5824 if (!program->setUniform4iv(location, count, v))
5825 {
5826 return error(GL_INVALID_OPERATION);
5827 }
5828 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005829 }
5830 catch(std::bad_alloc&)
5831 {
5832 return error(GL_OUT_OF_MEMORY);
5833 }
5834}
5835
5836void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5837{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005838 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005839 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005840
5841 try
5842 {
5843 if (count < 0 || transpose != GL_FALSE)
5844 {
5845 return error(GL_INVALID_VALUE);
5846 }
5847
5848 if (location == -1)
5849 {
5850 return;
5851 }
5852
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005853 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005854
5855 if (context)
5856 {
5857 gl::Program *program = context->getCurrentProgram();
5858
5859 if (!program)
5860 {
5861 return error(GL_INVALID_OPERATION);
5862 }
5863
5864 if (!program->setUniformMatrix2fv(location, count, value))
5865 {
5866 return error(GL_INVALID_OPERATION);
5867 }
5868 }
5869 }
5870 catch(std::bad_alloc&)
5871 {
5872 return error(GL_OUT_OF_MEMORY);
5873 }
5874}
5875
5876void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5877{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005878 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005879 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005880
5881 try
5882 {
5883 if (count < 0 || transpose != GL_FALSE)
5884 {
5885 return error(GL_INVALID_VALUE);
5886 }
5887
5888 if (location == -1)
5889 {
5890 return;
5891 }
5892
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005893 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005894
5895 if (context)
5896 {
5897 gl::Program *program = context->getCurrentProgram();
5898
5899 if (!program)
5900 {
5901 return error(GL_INVALID_OPERATION);
5902 }
5903
5904 if (!program->setUniformMatrix3fv(location, count, value))
5905 {
5906 return error(GL_INVALID_OPERATION);
5907 }
5908 }
5909 }
5910 catch(std::bad_alloc&)
5911 {
5912 return error(GL_OUT_OF_MEMORY);
5913 }
5914}
5915
5916void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5917{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005918 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005919 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005920
5921 try
5922 {
5923 if (count < 0 || transpose != GL_FALSE)
5924 {
5925 return error(GL_INVALID_VALUE);
5926 }
5927
5928 if (location == -1)
5929 {
5930 return;
5931 }
5932
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005933 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005934
5935 if (context)
5936 {
5937 gl::Program *program = context->getCurrentProgram();
5938
5939 if (!program)
5940 {
5941 return error(GL_INVALID_OPERATION);
5942 }
5943
5944 if (!program->setUniformMatrix4fv(location, count, value))
5945 {
5946 return error(GL_INVALID_OPERATION);
5947 }
5948 }
5949 }
5950 catch(std::bad_alloc&)
5951 {
5952 return error(GL_OUT_OF_MEMORY);
5953 }
5954}
5955
5956void __stdcall glUseProgram(GLuint program)
5957{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005958 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005959
5960 try
5961 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005962 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005963
5964 if (context)
5965 {
5966 gl::Program *programObject = context->getProgram(program);
5967
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005968 if (!programObject && program != 0)
5969 {
5970 if (context->getShader(program))
5971 {
5972 return error(GL_INVALID_OPERATION);
5973 }
5974 else
5975 {
5976 return error(GL_INVALID_VALUE);
5977 }
5978 }
5979
5980 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005981 {
5982 return error(GL_INVALID_OPERATION);
5983 }
5984
5985 context->useProgram(program);
5986 }
5987 }
5988 catch(std::bad_alloc&)
5989 {
5990 return error(GL_OUT_OF_MEMORY);
5991 }
5992}
5993
5994void __stdcall glValidateProgram(GLuint program)
5995{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005996 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005997
5998 try
5999 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006000 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006001
6002 if (context)
6003 {
6004 gl::Program *programObject = context->getProgram(program);
6005
6006 if (!programObject)
6007 {
6008 if (context->getShader(program))
6009 {
6010 return error(GL_INVALID_OPERATION);
6011 }
6012 else
6013 {
6014 return error(GL_INVALID_VALUE);
6015 }
6016 }
6017
6018 programObject->validate();
6019 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006020 }
6021 catch(std::bad_alloc&)
6022 {
6023 return error(GL_OUT_OF_MEMORY);
6024 }
6025}
6026
6027void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
6028{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006029 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006030
6031 try
6032 {
6033 if (index >= gl::MAX_VERTEX_ATTRIBS)
6034 {
6035 return error(GL_INVALID_VALUE);
6036 }
6037
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006038 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006039
6040 if (context)
6041 {
6042 GLfloat vals[4] = { x, 0, 0, 1 };
6043 context->setVertexAttrib(index, vals);
6044 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006045 }
6046 catch(std::bad_alloc&)
6047 {
6048 return error(GL_OUT_OF_MEMORY);
6049 }
6050}
6051
6052void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
6053{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006054 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006055
6056 try
6057 {
6058 if (index >= gl::MAX_VERTEX_ATTRIBS)
6059 {
6060 return error(GL_INVALID_VALUE);
6061 }
6062
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006063 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006064
6065 if (context)
6066 {
6067 GLfloat vals[4] = { values[0], 0, 0, 1 };
6068 context->setVertexAttrib(index, vals);
6069 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006070 }
6071 catch(std::bad_alloc&)
6072 {
6073 return error(GL_OUT_OF_MEMORY);
6074 }
6075}
6076
6077void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6078{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006079 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006080
6081 try
6082 {
6083 if (index >= gl::MAX_VERTEX_ATTRIBS)
6084 {
6085 return error(GL_INVALID_VALUE);
6086 }
6087
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006088 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006089
6090 if (context)
6091 {
6092 GLfloat vals[4] = { x, y, 0, 1 };
6093 context->setVertexAttrib(index, vals);
6094 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006095 }
6096 catch(std::bad_alloc&)
6097 {
6098 return error(GL_OUT_OF_MEMORY);
6099 }
6100}
6101
6102void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
6103{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006104 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006105
6106 try
6107 {
6108 if (index >= gl::MAX_VERTEX_ATTRIBS)
6109 {
6110 return error(GL_INVALID_VALUE);
6111 }
6112
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006113 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006114
6115 if (context)
6116 {
6117 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6118 context->setVertexAttrib(index, vals);
6119 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006120 }
6121 catch(std::bad_alloc&)
6122 {
6123 return error(GL_OUT_OF_MEMORY);
6124 }
6125}
6126
6127void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6128{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006129 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 +00006130
6131 try
6132 {
6133 if (index >= gl::MAX_VERTEX_ATTRIBS)
6134 {
6135 return error(GL_INVALID_VALUE);
6136 }
6137
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006138 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006139
6140 if (context)
6141 {
6142 GLfloat vals[4] = { x, y, z, 1 };
6143 context->setVertexAttrib(index, vals);
6144 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006145 }
6146 catch(std::bad_alloc&)
6147 {
6148 return error(GL_OUT_OF_MEMORY);
6149 }
6150}
6151
6152void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
6153{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006154 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006155
6156 try
6157 {
6158 if (index >= gl::MAX_VERTEX_ATTRIBS)
6159 {
6160 return error(GL_INVALID_VALUE);
6161 }
6162
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006163 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006164
6165 if (context)
6166 {
6167 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6168 context->setVertexAttrib(index, vals);
6169 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006170 }
6171 catch(std::bad_alloc&)
6172 {
6173 return error(GL_OUT_OF_MEMORY);
6174 }
6175}
6176
6177void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6178{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006179 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 +00006180
6181 try
6182 {
6183 if (index >= gl::MAX_VERTEX_ATTRIBS)
6184 {
6185 return error(GL_INVALID_VALUE);
6186 }
6187
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006188 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006189
6190 if (context)
6191 {
6192 GLfloat vals[4] = { x, y, z, w };
6193 context->setVertexAttrib(index, vals);
6194 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006195 }
6196 catch(std::bad_alloc&)
6197 {
6198 return error(GL_OUT_OF_MEMORY);
6199 }
6200}
6201
6202void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
6203{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006204 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006205
6206 try
6207 {
6208 if (index >= gl::MAX_VERTEX_ATTRIBS)
6209 {
6210 return error(GL_INVALID_VALUE);
6211 }
6212
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006213 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006214
6215 if (context)
6216 {
6217 context->setVertexAttrib(index, values);
6218 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006219 }
6220 catch(std::bad_alloc&)
6221 {
6222 return error(GL_OUT_OF_MEMORY);
6223 }
6224}
6225
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006226void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006227{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006228 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006229 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006230 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006231
6232 try
6233 {
6234 if (index >= gl::MAX_VERTEX_ATTRIBS)
6235 {
6236 return error(GL_INVALID_VALUE);
6237 }
6238
6239 if (size < 1 || size > 4)
6240 {
6241 return error(GL_INVALID_VALUE);
6242 }
6243
6244 switch (type)
6245 {
6246 case GL_BYTE:
6247 case GL_UNSIGNED_BYTE:
6248 case GL_SHORT:
6249 case GL_UNSIGNED_SHORT:
6250 case GL_FIXED:
6251 case GL_FLOAT:
6252 break;
6253 default:
6254 return error(GL_INVALID_ENUM);
6255 }
6256
6257 if (stride < 0)
6258 {
6259 return error(GL_INVALID_VALUE);
6260 }
6261
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006262 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006263
6264 if (context)
6265 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006266 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006267 }
6268 }
6269 catch(std::bad_alloc&)
6270 {
6271 return error(GL_OUT_OF_MEMORY);
6272 }
6273}
6274
6275void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6276{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006277 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 +00006278
6279 try
6280 {
6281 if (width < 0 || height < 0)
6282 {
6283 return error(GL_INVALID_VALUE);
6284 }
6285
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006286 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006287
6288 if (context)
6289 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006290 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006291 }
6292 }
6293 catch(std::bad_alloc&)
6294 {
6295 return error(GL_OUT_OF_MEMORY);
6296 }
6297}
6298
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006299void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6300 GLbitfield mask, GLenum filter)
6301{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006302 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006303 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6304 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6305 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6306
6307 try
6308 {
6309 switch (filter)
6310 {
6311 case GL_NEAREST:
6312 break;
6313 default:
6314 return error(GL_INVALID_ENUM);
6315 }
6316
6317 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6318 {
6319 return error(GL_INVALID_VALUE);
6320 }
6321
6322 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6323 {
6324 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6325 return error(GL_INVALID_OPERATION);
6326 }
6327
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006328 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006329
6330 if (context)
6331 {
6332 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6333 {
6334 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6335 return error(GL_INVALID_OPERATION);
6336 }
6337
6338 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6339 }
6340 }
6341 catch(std::bad_alloc&)
6342 {
6343 return error(GL_OUT_OF_MEMORY);
6344 }
6345}
6346
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006347void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6348 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006349{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006350 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006351 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006352 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006353 target, level, internalformat, width, height, depth, border, format, type, pixels);
6354
6355 try
6356 {
6357 UNIMPLEMENTED(); // FIXME
6358 }
6359 catch(std::bad_alloc&)
6360 {
6361 return error(GL_OUT_OF_MEMORY);
6362 }
6363}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006364
6365__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6366{
6367 struct Extension
6368 {
6369 const char *name;
6370 __eglMustCastToProperFunctionPointerType address;
6371 };
6372
6373 static const Extension glExtensions[] =
6374 {
6375 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006376 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006377 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006378 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6379 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6380 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6381 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6382 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6383 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6384 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006385 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006386 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006387 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6388 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6389 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6390 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00006391 {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT},
6392 {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT},
6393 {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT},
6394 {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT},
6395 {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
6396 {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
6397 {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006398 };
6399
6400 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6401 {
6402 if (strcmp(procname, glExtensions[ext].name) == 0)
6403 {
6404 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6405 }
6406 }
6407
6408 return NULL;
6409}
6410
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006411// Non-public functions used by EGL
6412
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006413bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006414{
6415 EVENT("(egl::Surface* surface = 0x%0.8p)",
6416 surface);
6417
6418 try
6419 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006420 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006421
6422 if (context)
6423 {
6424 gl::Texture2D *textureObject = context->getTexture2D();
6425
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006426 if (textureObject->isImmutable())
6427 {
6428 return false;
6429 }
6430
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006431 if (textureObject)
6432 {
6433 textureObject->bindTexImage(surface);
6434 }
6435 }
6436 }
6437 catch(std::bad_alloc&)
6438 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006439 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006440 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006441
6442 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006443}
6444
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006445}