blob: 73b7a2b44ee281f1830ff590e773528dc7b1e316 [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 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00001025 if (!gl::IsInternalTextureTarget(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 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00001314 if (!gl::IsInternalTextureTarget(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 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +00002979 else if (gl::IsInternalTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002980 {
2981 attachmentObjectType = GL_TEXTURE;
2982 }
apatrick@chromium.orga1d80592012-01-25 21:52:10 +00002983 else
2984 {
2985 UNREACHABLE();
2986 return;
2987 }
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002988
2989 switch (pname)
2990 {
2991 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2992 *params = attachmentObjectType;
2993 break;
2994 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2995 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2996 {
2997 *params = attachmentHandle;
2998 }
2999 else
3000 {
3001 return error(GL_INVALID_ENUM);
3002 }
3003 break;
3004 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3005 if (attachmentObjectType == GL_TEXTURE)
3006 {
3007 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
3008 }
3009 else
3010 {
3011 return error(GL_INVALID_ENUM);
3012 }
3013 break;
3014 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3015 if (attachmentObjectType == GL_TEXTURE)
3016 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00003017 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003018 {
3019 *params = attachmentType;
3020 }
3021 else
3022 {
3023 *params = 0;
3024 }
3025 }
3026 else
3027 {
3028 return error(GL_INVALID_ENUM);
3029 }
3030 break;
3031 default:
3032 return error(GL_INVALID_ENUM);
3033 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003034 }
3035 }
3036 catch(std::bad_alloc&)
3037 {
3038 return error(GL_OUT_OF_MEMORY);
3039 }
3040}
3041
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00003042GLenum __stdcall glGetGraphicsResetStatusEXT(void)
3043{
3044 EVENT("()");
3045
3046 try
3047 {
3048 gl::Context *context = gl::getContext();
3049
3050 if (context)
3051 {
3052 return context->getResetStatus();
3053 }
3054
3055 return GL_NO_ERROR;
3056 }
3057 catch(std::bad_alloc&)
3058 {
3059 return GL_OUT_OF_MEMORY;
3060 }
3061}
3062
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003063void __stdcall glGetIntegerv(GLenum pname, GLint* params)
3064{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003065 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003066
3067 try
3068 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003069 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003070
3071 if (context)
3072 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003073 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003074 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003075 GLenum nativeType;
3076 unsigned int numParams = 0;
3077 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3078 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003079
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003080 if (numParams == 0)
3081 return; // it is known that pname is valid, but there are no parameters to return
3082
3083 if (nativeType == GL_BOOL)
3084 {
3085 GLboolean *boolParams = NULL;
3086 boolParams = new GLboolean[numParams];
3087
3088 context->getBooleanv(pname, boolParams);
3089
3090 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003091 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003092 if (boolParams[i] == GL_FALSE)
3093 params[i] = 0;
3094 else
3095 params[i] = 1;
3096 }
3097
3098 delete [] boolParams;
3099 }
3100 else if (nativeType == GL_FLOAT)
3101 {
3102 GLfloat *floatParams = NULL;
3103 floatParams = new GLfloat[numParams];
3104
3105 context->getFloatv(pname, floatParams);
3106
3107 for (unsigned int i = 0; i < numParams; ++i)
3108 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00003109 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 +00003110 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003111 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003112 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003113 else
3114 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 +00003115 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003116
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003117 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003118 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003119 }
3120 }
3121 }
3122 catch(std::bad_alloc&)
3123 {
3124 return error(GL_OUT_OF_MEMORY);
3125 }
3126}
3127
3128void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3129{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003130 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003131
3132 try
3133 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003134 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003135
3136 if (context)
3137 {
3138 gl::Program *programObject = context->getProgram(program);
3139
3140 if (!programObject)
3141 {
3142 return error(GL_INVALID_VALUE);
3143 }
3144
3145 switch (pname)
3146 {
3147 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003148 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003149 return;
3150 case GL_LINK_STATUS:
3151 *params = programObject->isLinked();
3152 return;
3153 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003154 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003155 return;
3156 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003157 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003158 return;
3159 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003160 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003161 return;
3162 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003163 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003164 return;
3165 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003166 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003167 return;
3168 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003169 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003170 return;
3171 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003172 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003173 return;
3174 default:
3175 return error(GL_INVALID_ENUM);
3176 }
3177 }
3178 }
3179 catch(std::bad_alloc&)
3180 {
3181 return error(GL_OUT_OF_MEMORY);
3182 }
3183}
3184
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003185void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003186{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003187 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 +00003188 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003189
3190 try
3191 {
3192 if (bufsize < 0)
3193 {
3194 return error(GL_INVALID_VALUE);
3195 }
3196
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003197 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003198
3199 if (context)
3200 {
3201 gl::Program *programObject = context->getProgram(program);
3202
3203 if (!programObject)
3204 {
3205 return error(GL_INVALID_VALUE);
3206 }
3207
3208 programObject->getInfoLog(bufsize, length, infolog);
3209 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003210 }
3211 catch(std::bad_alloc&)
3212 {
3213 return error(GL_OUT_OF_MEMORY);
3214 }
3215}
3216
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003217void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3218{
3219 EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
3220
3221 try
3222 {
3223 switch (pname)
3224 {
3225 case GL_CURRENT_QUERY_EXT:
3226 break;
3227 default:
3228 return error(GL_INVALID_ENUM);
3229 }
3230
3231 gl::Context *context = gl::getNonLostContext();
3232
3233 if (context)
3234 {
3235 params[0] = context->getActiveQuery(target);
3236 }
3237 }
3238 catch(std::bad_alloc&)
3239 {
3240 return error(GL_OUT_OF_MEMORY);
3241 }
3242}
3243
3244void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
3245{
3246 EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
3247
3248 try
3249 {
3250 switch (pname)
3251 {
3252 case GL_QUERY_RESULT_EXT:
3253 case GL_QUERY_RESULT_AVAILABLE_EXT:
3254 break;
3255 default:
3256 return error(GL_INVALID_ENUM);
3257 }
3258 gl::Context *context = gl::getNonLostContext();
3259
3260 if (context)
3261 {
3262
3263 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
3264
3265 if (!queryObject)
3266 {
3267 return error(GL_INVALID_OPERATION);
3268 }
3269
3270 if (context->getActiveQuery(queryObject->getType()) == id)
3271 {
3272 return error(GL_INVALID_OPERATION);
3273 }
3274
3275 switch(pname)
3276 {
3277 case GL_QUERY_RESULT_EXT:
3278 params[0] = queryObject->getResult();
3279 break;
3280 case GL_QUERY_RESULT_AVAILABLE_EXT:
3281 params[0] = queryObject->isResultAvailable();
3282 break;
3283 default:
3284 ASSERT(false);
3285 }
3286 }
3287 }
3288 catch(std::bad_alloc&)
3289 {
3290 return error(GL_OUT_OF_MEMORY);
3291 }
3292}
3293
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003294void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3295{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003296 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 +00003297
3298 try
3299 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003300 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003301
3302 if (context)
3303 {
3304 if (target != GL_RENDERBUFFER)
3305 {
3306 return error(GL_INVALID_ENUM);
3307 }
3308
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003309 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003310 {
3311 return error(GL_INVALID_OPERATION);
3312 }
3313
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003314 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003315
3316 switch (pname)
3317 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003318 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3319 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3320 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3321 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3322 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3323 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3324 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3325 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3326 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003327 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003328 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003329 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003330 *params = renderbuffer->getSamples();
3331 }
3332 else
3333 {
3334 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003335 }
3336 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003337 default:
3338 return error(GL_INVALID_ENUM);
3339 }
3340 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003341 }
3342 catch(std::bad_alloc&)
3343 {
3344 return error(GL_OUT_OF_MEMORY);
3345 }
3346}
3347
3348void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3349{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003350 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003351
3352 try
3353 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003354 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003355
3356 if (context)
3357 {
3358 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003359
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003360 if (!shaderObject)
3361 {
3362 return error(GL_INVALID_VALUE);
3363 }
3364
3365 switch (pname)
3366 {
3367 case GL_SHADER_TYPE:
3368 *params = shaderObject->getType();
3369 return;
3370 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003371 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003372 return;
3373 case GL_COMPILE_STATUS:
3374 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3375 return;
3376 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003377 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003378 return;
3379 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003380 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003381 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003382 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3383 *params = shaderObject->getTranslatedSourceLength();
3384 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003385 default:
3386 return error(GL_INVALID_ENUM);
3387 }
3388 }
3389 }
3390 catch(std::bad_alloc&)
3391 {
3392 return error(GL_OUT_OF_MEMORY);
3393 }
3394}
3395
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003396void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003397{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003398 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 +00003399 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003400
3401 try
3402 {
3403 if (bufsize < 0)
3404 {
3405 return error(GL_INVALID_VALUE);
3406 }
3407
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003408 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003409
3410 if (context)
3411 {
3412 gl::Shader *shaderObject = context->getShader(shader);
3413
3414 if (!shaderObject)
3415 {
3416 return error(GL_INVALID_VALUE);
3417 }
3418
3419 shaderObject->getInfoLog(bufsize, length, infolog);
3420 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003421 }
3422 catch(std::bad_alloc&)
3423 {
3424 return error(GL_OUT_OF_MEMORY);
3425 }
3426}
3427
3428void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3429{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003430 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 +00003431 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003432
3433 try
3434 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003435 switch (shadertype)
3436 {
3437 case GL_VERTEX_SHADER:
3438 case GL_FRAGMENT_SHADER:
3439 break;
3440 default:
3441 return error(GL_INVALID_ENUM);
3442 }
3443
3444 switch (precisiontype)
3445 {
3446 case GL_LOW_FLOAT:
3447 case GL_MEDIUM_FLOAT:
3448 case GL_HIGH_FLOAT:
3449 // Assume IEEE 754 precision
3450 range[0] = 127;
3451 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003452 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003453 break;
3454 case GL_LOW_INT:
3455 case GL_MEDIUM_INT:
3456 case GL_HIGH_INT:
3457 // Some (most) hardware only supports single-precision floating-point numbers,
3458 // which can accurately represent integers up to +/-16777216
3459 range[0] = 24;
3460 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003461 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003462 break;
3463 default:
3464 return error(GL_INVALID_ENUM);
3465 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003466 }
3467 catch(std::bad_alloc&)
3468 {
3469 return error(GL_OUT_OF_MEMORY);
3470 }
3471}
3472
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003473void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003474{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003475 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 +00003476 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003477
3478 try
3479 {
3480 if (bufsize < 0)
3481 {
3482 return error(GL_INVALID_VALUE);
3483 }
3484
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003485 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003486
3487 if (context)
3488 {
3489 gl::Shader *shaderObject = context->getShader(shader);
3490
3491 if (!shaderObject)
3492 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003493 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003494 }
3495
3496 shaderObject->getSource(bufsize, length, source);
3497 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003498 }
3499 catch(std::bad_alloc&)
3500 {
3501 return error(GL_OUT_OF_MEMORY);
3502 }
3503}
3504
zmo@google.coma574f782011-10-03 21:45:23 +00003505void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3506{
3507 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3508 shader, bufsize, length, source);
3509
3510 try
3511 {
3512 if (bufsize < 0)
3513 {
3514 return error(GL_INVALID_VALUE);
3515 }
3516
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003517 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003518
3519 if (context)
3520 {
3521 gl::Shader *shaderObject = context->getShader(shader);
3522
3523 if (!shaderObject)
3524 {
3525 return error(GL_INVALID_OPERATION);
3526 }
3527
3528 shaderObject->getTranslatedSource(bufsize, length, source);
3529 }
3530 }
3531 catch(std::bad_alloc&)
3532 {
3533 return error(GL_OUT_OF_MEMORY);
3534 }
3535}
3536
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003537const GLubyte* __stdcall glGetString(GLenum name)
3538{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003539 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003540
3541 try
3542 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003543 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003544
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003545 switch (name)
3546 {
3547 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003548 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003549 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003550 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003551 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003552 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003553 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003554 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003555 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003556 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003557 default:
3558 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3559 }
3560 }
3561 catch(std::bad_alloc&)
3562 {
3563 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3564 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003565}
3566
3567void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3568{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003569 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 +00003570
3571 try
3572 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003573 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003574
3575 if (context)
3576 {
3577 gl::Texture *texture;
3578
3579 switch (target)
3580 {
3581 case GL_TEXTURE_2D:
3582 texture = context->getTexture2D();
3583 break;
3584 case GL_TEXTURE_CUBE_MAP:
3585 texture = context->getTextureCubeMap();
3586 break;
3587 default:
3588 return error(GL_INVALID_ENUM);
3589 }
3590
3591 switch (pname)
3592 {
3593 case GL_TEXTURE_MAG_FILTER:
3594 *params = (GLfloat)texture->getMagFilter();
3595 break;
3596 case GL_TEXTURE_MIN_FILTER:
3597 *params = (GLfloat)texture->getMinFilter();
3598 break;
3599 case GL_TEXTURE_WRAP_S:
3600 *params = (GLfloat)texture->getWrapS();
3601 break;
3602 case GL_TEXTURE_WRAP_T:
3603 *params = (GLfloat)texture->getWrapT();
3604 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003605 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3606 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3607 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003608 case GL_TEXTURE_USAGE_ANGLE:
3609 *params = (GLfloat)texture->getUsage();
3610 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003611 default:
3612 return error(GL_INVALID_ENUM);
3613 }
3614 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003615 }
3616 catch(std::bad_alloc&)
3617 {
3618 return error(GL_OUT_OF_MEMORY);
3619 }
3620}
3621
3622void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3623{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003624 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 +00003625
3626 try
3627 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003628 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003629
3630 if (context)
3631 {
3632 gl::Texture *texture;
3633
3634 switch (target)
3635 {
3636 case GL_TEXTURE_2D:
3637 texture = context->getTexture2D();
3638 break;
3639 case GL_TEXTURE_CUBE_MAP:
3640 texture = context->getTextureCubeMap();
3641 break;
3642 default:
3643 return error(GL_INVALID_ENUM);
3644 }
3645
3646 switch (pname)
3647 {
3648 case GL_TEXTURE_MAG_FILTER:
3649 *params = texture->getMagFilter();
3650 break;
3651 case GL_TEXTURE_MIN_FILTER:
3652 *params = texture->getMinFilter();
3653 break;
3654 case GL_TEXTURE_WRAP_S:
3655 *params = texture->getWrapS();
3656 break;
3657 case GL_TEXTURE_WRAP_T:
3658 *params = texture->getWrapT();
3659 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003660 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3661 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3662 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003663 case GL_TEXTURE_USAGE_ANGLE:
3664 *params = texture->getUsage();
3665 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003666 default:
3667 return error(GL_INVALID_ENUM);
3668 }
3669 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003670 }
3671 catch(std::bad_alloc&)
3672 {
3673 return error(GL_OUT_OF_MEMORY);
3674 }
3675}
3676
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003677void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3678{
3679 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3680 program, location, bufSize, params);
3681
3682 try
3683 {
3684 if (bufSize < 0)
3685 {
3686 return error(GL_INVALID_VALUE);
3687 }
3688
3689 gl::Context *context = gl::getNonLostContext();
3690
3691 if (context)
3692 {
3693 if (program == 0)
3694 {
3695 return error(GL_INVALID_VALUE);
3696 }
3697
3698 gl::Program *programObject = context->getProgram(program);
3699
3700 if (!programObject || !programObject->isLinked())
3701 {
3702 return error(GL_INVALID_OPERATION);
3703 }
3704
3705 if (!programObject->getUniformfv(location, &bufSize, params))
3706 {
3707 return error(GL_INVALID_OPERATION);
3708 }
3709 }
3710 }
3711 catch(std::bad_alloc&)
3712 {
3713 return error(GL_OUT_OF_MEMORY);
3714 }
3715}
3716
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003717void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3718{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003719 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003720
3721 try
3722 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003723 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003724
3725 if (context)
3726 {
3727 if (program == 0)
3728 {
3729 return error(GL_INVALID_VALUE);
3730 }
3731
3732 gl::Program *programObject = context->getProgram(program);
3733
3734 if (!programObject || !programObject->isLinked())
3735 {
3736 return error(GL_INVALID_OPERATION);
3737 }
3738
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003739 if (!programObject->getUniformfv(location, NULL, params))
3740 {
3741 return error(GL_INVALID_OPERATION);
3742 }
3743 }
3744 }
3745 catch(std::bad_alloc&)
3746 {
3747 return error(GL_OUT_OF_MEMORY);
3748 }
3749}
3750
3751void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3752{
3753 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3754 program, location, bufSize, params);
3755
3756 try
3757 {
3758 if (bufSize < 0)
3759 {
3760 return error(GL_INVALID_VALUE);
3761 }
3762
3763 gl::Context *context = gl::getNonLostContext();
3764
3765 if (context)
3766 {
3767 if (program == 0)
3768 {
3769 return error(GL_INVALID_VALUE);
3770 }
3771
3772 gl::Program *programObject = context->getProgram(program);
3773
3774 if (!programObject || !programObject->isLinked())
3775 {
3776 return error(GL_INVALID_OPERATION);
3777 }
3778
3779 if (!programObject)
3780 {
3781 return error(GL_INVALID_OPERATION);
3782 }
3783
3784 if (!programObject->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003785 {
3786 return error(GL_INVALID_OPERATION);
3787 }
3788 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003789 }
3790 catch(std::bad_alloc&)
3791 {
3792 return error(GL_OUT_OF_MEMORY);
3793 }
3794}
3795
3796void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3797{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003798 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003799
3800 try
3801 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003802 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003803
3804 if (context)
3805 {
3806 if (program == 0)
3807 {
3808 return error(GL_INVALID_VALUE);
3809 }
3810
3811 gl::Program *programObject = context->getProgram(program);
3812
3813 if (!programObject || !programObject->isLinked())
3814 {
3815 return error(GL_INVALID_OPERATION);
3816 }
3817
3818 if (!programObject)
3819 {
3820 return error(GL_INVALID_OPERATION);
3821 }
3822
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003823 if (!programObject->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003824 {
3825 return error(GL_INVALID_OPERATION);
3826 }
3827 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003828 }
3829 catch(std::bad_alloc&)
3830 {
3831 return error(GL_OUT_OF_MEMORY);
3832 }
3833}
3834
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003835int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003836{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003837 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003838
3839 try
3840 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003841 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003842
3843 if (strstr(name, "gl_") == name)
3844 {
3845 return -1;
3846 }
3847
3848 if (context)
3849 {
3850 gl::Program *programObject = context->getProgram(program);
3851
3852 if (!programObject)
3853 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003854 if (context->getShader(program))
3855 {
3856 return error(GL_INVALID_OPERATION, -1);
3857 }
3858 else
3859 {
3860 return error(GL_INVALID_VALUE, -1);
3861 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003862 }
3863
3864 if (!programObject->isLinked())
3865 {
3866 return error(GL_INVALID_OPERATION, -1);
3867 }
3868
daniel@transgaming.com024f1a92011-09-20 16:06:25 +00003869 return programObject->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003870 }
3871 }
3872 catch(std::bad_alloc&)
3873 {
3874 return error(GL_OUT_OF_MEMORY, -1);
3875 }
3876
3877 return -1;
3878}
3879
3880void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3881{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003882 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003883
3884 try
3885 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003886 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003887
daniel@transgaming.come0078962010-04-15 20:45:08 +00003888 if (context)
3889 {
3890 if (index >= gl::MAX_VERTEX_ATTRIBS)
3891 {
3892 return error(GL_INVALID_VALUE);
3893 }
3894
daniel@transgaming.com83921382011-01-08 05:46:00 +00003895 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003896
daniel@transgaming.come0078962010-04-15 20:45:08 +00003897 switch (pname)
3898 {
3899 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003900 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003901 break;
3902 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003903 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003904 break;
3905 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003906 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003907 break;
3908 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003909 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003910 break;
3911 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003912 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003913 break;
3914 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003915 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003916 break;
3917 case GL_CURRENT_VERTEX_ATTRIB:
3918 for (int i = 0; i < 4; ++i)
3919 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003920 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003921 }
3922 break;
3923 default: return error(GL_INVALID_ENUM);
3924 }
3925 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003926 }
3927 catch(std::bad_alloc&)
3928 {
3929 return error(GL_OUT_OF_MEMORY);
3930 }
3931}
3932
3933void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3934{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003935 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003936
3937 try
3938 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003939 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003940
daniel@transgaming.come0078962010-04-15 20:45:08 +00003941 if (context)
3942 {
3943 if (index >= gl::MAX_VERTEX_ATTRIBS)
3944 {
3945 return error(GL_INVALID_VALUE);
3946 }
3947
daniel@transgaming.com83921382011-01-08 05:46:00 +00003948 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003949
daniel@transgaming.come0078962010-04-15 20:45:08 +00003950 switch (pname)
3951 {
3952 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003953 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003954 break;
3955 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003956 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003957 break;
3958 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003959 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003960 break;
3961 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003962 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003963 break;
3964 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003965 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003966 break;
3967 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003968 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003969 break;
3970 case GL_CURRENT_VERTEX_ATTRIB:
3971 for (int i = 0; i < 4; ++i)
3972 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003973 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003974 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3975 }
3976 break;
3977 default: return error(GL_INVALID_ENUM);
3978 }
3979 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003980 }
3981 catch(std::bad_alloc&)
3982 {
3983 return error(GL_OUT_OF_MEMORY);
3984 }
3985}
3986
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003987void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003988{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003989 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003990
3991 try
3992 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003993 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003994
daniel@transgaming.come0078962010-04-15 20:45:08 +00003995 if (context)
3996 {
3997 if (index >= gl::MAX_VERTEX_ATTRIBS)
3998 {
3999 return error(GL_INVALID_VALUE);
4000 }
4001
4002 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4003 {
4004 return error(GL_INVALID_ENUM);
4005 }
4006
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004007 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00004008 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004009 }
4010 catch(std::bad_alloc&)
4011 {
4012 return error(GL_OUT_OF_MEMORY);
4013 }
4014}
4015
4016void __stdcall glHint(GLenum target, GLenum mode)
4017{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004018 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004019
4020 try
4021 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004022 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004023 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004024 case GL_FASTEST:
4025 case GL_NICEST:
4026 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004027 break;
4028 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004029 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004030 }
4031
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004032 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004033 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004034 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004035 case GL_GENERATE_MIPMAP_HINT:
4036 if (context) context->setGenerateMipmapHint(mode);
4037 break;
4038 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4039 if (context) context->setFragmentShaderDerivativeHint(mode);
4040 break;
4041 default:
4042 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004043 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004044 }
4045 catch(std::bad_alloc&)
4046 {
4047 return error(GL_OUT_OF_MEMORY);
4048 }
4049}
4050
4051GLboolean __stdcall glIsBuffer(GLuint buffer)
4052{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004053 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004054
4055 try
4056 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004057 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004058
4059 if (context && buffer)
4060 {
4061 gl::Buffer *bufferObject = context->getBuffer(buffer);
4062
4063 if (bufferObject)
4064 {
4065 return GL_TRUE;
4066 }
4067 }
4068 }
4069 catch(std::bad_alloc&)
4070 {
4071 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4072 }
4073
4074 return GL_FALSE;
4075}
4076
4077GLboolean __stdcall glIsEnabled(GLenum cap)
4078{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004079 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004080
4081 try
4082 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004083 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004084
4085 if (context)
4086 {
4087 switch (cap)
4088 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004089 case GL_CULL_FACE: return context->isCullFaceEnabled();
4090 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4091 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4092 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4093 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4094 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4095 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4096 case GL_BLEND: return context->isBlendEnabled();
4097 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004098 default:
4099 return error(GL_INVALID_ENUM, false);
4100 }
4101 }
4102 }
4103 catch(std::bad_alloc&)
4104 {
4105 return error(GL_OUT_OF_MEMORY, false);
4106 }
4107
4108 return false;
4109}
4110
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004111GLboolean __stdcall glIsFenceNV(GLuint fence)
4112{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004113 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004114
4115 try
4116 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004117 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004118
4119 if (context)
4120 {
4121 gl::Fence *fenceObject = context->getFence(fence);
4122
4123 if (fenceObject == NULL)
4124 {
4125 return GL_FALSE;
4126 }
4127
4128 return fenceObject->isFence();
4129 }
4130 }
4131 catch(std::bad_alloc&)
4132 {
4133 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4134 }
4135
4136 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004137}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004138
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004139GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
4140{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004141 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004142
4143 try
4144 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004145 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004146
4147 if (context && framebuffer)
4148 {
4149 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4150
4151 if (framebufferObject)
4152 {
4153 return GL_TRUE;
4154 }
4155 }
4156 }
4157 catch(std::bad_alloc&)
4158 {
4159 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4160 }
4161
4162 return GL_FALSE;
4163}
4164
4165GLboolean __stdcall glIsProgram(GLuint program)
4166{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004167 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004168
4169 try
4170 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004171 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004172
4173 if (context && program)
4174 {
4175 gl::Program *programObject = context->getProgram(program);
4176
4177 if (programObject)
4178 {
4179 return GL_TRUE;
4180 }
4181 }
4182 }
4183 catch(std::bad_alloc&)
4184 {
4185 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4186 }
4187
4188 return GL_FALSE;
4189}
4190
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00004191GLboolean __stdcall glIsQueryEXT(GLuint id)
4192{
4193 EVENT("(GLuint id = %d)", id);
4194
4195 try
4196 {
4197 if (id == 0)
4198 {
4199 return GL_FALSE;
4200 }
4201
4202 gl::Context *context = gl::getNonLostContext();
4203
4204 if (context)
4205 {
4206 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
4207
4208 if (queryObject)
4209 {
4210 return GL_TRUE;
4211 }
4212 }
4213 }
4214 catch(std::bad_alloc&)
4215 {
4216 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4217 }
4218
4219 return GL_FALSE;
4220}
4221
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004222GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
4223{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004224 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004225
4226 try
4227 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004228 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004229
4230 if (context && renderbuffer)
4231 {
4232 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4233
4234 if (renderbufferObject)
4235 {
4236 return GL_TRUE;
4237 }
4238 }
4239 }
4240 catch(std::bad_alloc&)
4241 {
4242 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4243 }
4244
4245 return GL_FALSE;
4246}
4247
4248GLboolean __stdcall glIsShader(GLuint shader)
4249{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004250 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004251
4252 try
4253 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004254 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004255
4256 if (context && shader)
4257 {
4258 gl::Shader *shaderObject = context->getShader(shader);
4259
4260 if (shaderObject)
4261 {
4262 return GL_TRUE;
4263 }
4264 }
4265 }
4266 catch(std::bad_alloc&)
4267 {
4268 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4269 }
4270
4271 return GL_FALSE;
4272}
4273
4274GLboolean __stdcall glIsTexture(GLuint texture)
4275{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004276 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004277
4278 try
4279 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004280 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004281
4282 if (context && texture)
4283 {
4284 gl::Texture *textureObject = context->getTexture(texture);
4285
4286 if (textureObject)
4287 {
4288 return GL_TRUE;
4289 }
4290 }
4291 }
4292 catch(std::bad_alloc&)
4293 {
4294 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4295 }
4296
4297 return GL_FALSE;
4298}
4299
4300void __stdcall glLineWidth(GLfloat width)
4301{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004302 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004303
4304 try
4305 {
4306 if (width <= 0.0f)
4307 {
4308 return error(GL_INVALID_VALUE);
4309 }
4310
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004311 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004312
4313 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004314 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004315 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004316 }
4317 }
4318 catch(std::bad_alloc&)
4319 {
4320 return error(GL_OUT_OF_MEMORY);
4321 }
4322}
4323
4324void __stdcall glLinkProgram(GLuint program)
4325{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004326 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004327
4328 try
4329 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004330 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004331
4332 if (context)
4333 {
4334 gl::Program *programObject = context->getProgram(program);
4335
4336 if (!programObject)
4337 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004338 if (context->getShader(program))
4339 {
4340 return error(GL_INVALID_OPERATION);
4341 }
4342 else
4343 {
4344 return error(GL_INVALID_VALUE);
4345 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004346 }
4347
4348 programObject->link();
4349 }
4350 }
4351 catch(std::bad_alloc&)
4352 {
4353 return error(GL_OUT_OF_MEMORY);
4354 }
4355}
4356
4357void __stdcall glPixelStorei(GLenum pname, GLint param)
4358{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004359 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004360
4361 try
4362 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004363 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004364
4365 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004366 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004367 switch (pname)
4368 {
4369 case GL_UNPACK_ALIGNMENT:
4370 if (param != 1 && param != 2 && param != 4 && param != 8)
4371 {
4372 return error(GL_INVALID_VALUE);
4373 }
4374
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004375 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004376 break;
4377
4378 case GL_PACK_ALIGNMENT:
4379 if (param != 1 && param != 2 && param != 4 && param != 8)
4380 {
4381 return error(GL_INVALID_VALUE);
4382 }
4383
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004384 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004385 break;
4386
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004387 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4388 context->setPackReverseRowOrder(param != 0);
4389 break;
4390
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004391 default:
4392 return error(GL_INVALID_ENUM);
4393 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004394 }
4395 }
4396 catch(std::bad_alloc&)
4397 {
4398 return error(GL_OUT_OF_MEMORY);
4399 }
4400}
4401
4402void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4403{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004404 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004405
4406 try
4407 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004408 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004409
4410 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004411 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004412 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004413 }
4414 }
4415 catch(std::bad_alloc&)
4416 {
4417 return error(GL_OUT_OF_MEMORY);
4418 }
4419}
4420
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004421void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4422 GLenum format, GLenum type, GLsizei bufSize,
4423 GLvoid *data)
4424{
4425 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4426 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4427 x, y, width, height, format, type, bufSize, data);
4428
4429 try
4430 {
4431 if (width < 0 || height < 0 || bufSize < 0)
4432 {
4433 return error(GL_INVALID_VALUE);
4434 }
4435
4436 if (!validReadFormatType(format, type))
4437 {
4438 return error(GL_INVALID_OPERATION);
4439 }
4440
4441 gl::Context *context = gl::getNonLostContext();
4442
4443 if (context)
4444 {
4445 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4446 }
4447 }
4448 catch(std::bad_alloc&)
4449 {
4450 return error(GL_OUT_OF_MEMORY);
4451 }
4452}
4453
4454void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4455 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004456{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004457 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004458 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004459 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004460
4461 try
4462 {
4463 if (width < 0 || height < 0)
4464 {
4465 return error(GL_INVALID_VALUE);
4466 }
4467
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004468 if (!validReadFormatType(format, type))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004469 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004470 return error(GL_INVALID_OPERATION);
4471 }
4472
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004473 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004474
4475 if (context)
4476 {
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004477 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004478 }
4479 }
4480 catch(std::bad_alloc&)
4481 {
4482 return error(GL_OUT_OF_MEMORY);
4483 }
4484}
4485
4486void __stdcall glReleaseShaderCompiler(void)
4487{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004488 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004489
4490 try
4491 {
4492 gl::Shader::releaseCompiler();
4493 }
4494 catch(std::bad_alloc&)
4495 {
4496 return error(GL_OUT_OF_MEMORY);
4497 }
4498}
4499
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004500void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004501{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004502 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 +00004503 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004504
4505 try
4506 {
4507 switch (target)
4508 {
4509 case GL_RENDERBUFFER:
4510 break;
4511 default:
4512 return error(GL_INVALID_ENUM);
4513 }
4514
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004515 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004516 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004517 return error(GL_INVALID_ENUM);
4518 }
4519
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004520 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004521 {
4522 return error(GL_INVALID_VALUE);
4523 }
4524
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004525 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004526
4527 if (context)
4528 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004529 if (width > context->getMaximumRenderbufferDimension() ||
4530 height > context->getMaximumRenderbufferDimension() ||
4531 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004532 {
4533 return error(GL_INVALID_VALUE);
4534 }
4535
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004536 GLuint handle = context->getRenderbufferHandle();
4537 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004538 {
4539 return error(GL_INVALID_OPERATION);
4540 }
4541
4542 switch (internalformat)
4543 {
4544 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004545 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004546 break;
4547 case GL_RGBA4:
4548 case GL_RGB5_A1:
4549 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004550 case GL_RGB8_OES:
4551 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004552 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004553 break;
4554 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004555 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004556 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004557 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004558 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004559 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004560 default:
4561 return error(GL_INVALID_ENUM);
4562 }
4563 }
4564 }
4565 catch(std::bad_alloc&)
4566 {
4567 return error(GL_OUT_OF_MEMORY);
4568 }
4569}
4570
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004571void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4572{
4573 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4574}
4575
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004576void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4577{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004578 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004579
4580 try
4581 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004582 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004583
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004584 if (context)
4585 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004586 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004587 }
4588 }
4589 catch(std::bad_alloc&)
4590 {
4591 return error(GL_OUT_OF_MEMORY);
4592 }
4593}
4594
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004595void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4596{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004597 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004598
4599 try
4600 {
4601 if (condition != GL_ALL_COMPLETED_NV)
4602 {
4603 return error(GL_INVALID_ENUM);
4604 }
4605
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004606 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004607
4608 if (context)
4609 {
4610 gl::Fence *fenceObject = context->getFence(fence);
4611
4612 if (fenceObject == NULL)
4613 {
4614 return error(GL_INVALID_OPERATION);
4615 }
4616
4617 fenceObject->setFence(condition);
4618 }
4619 }
4620 catch(std::bad_alloc&)
4621 {
4622 return error(GL_OUT_OF_MEMORY);
4623 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004624}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004625
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004626void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4627{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004628 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 +00004629
4630 try
4631 {
4632 if (width < 0 || height < 0)
4633 {
4634 return error(GL_INVALID_VALUE);
4635 }
4636
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004637 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004638
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004639 if (context)
4640 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004641 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004642 }
4643 }
4644 catch(std::bad_alloc&)
4645 {
4646 return error(GL_OUT_OF_MEMORY);
4647 }
4648}
4649
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004650void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004651{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004652 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004653 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004654 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004655
4656 try
4657 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004658 // No binary shader formats are supported.
4659 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004660 }
4661 catch(std::bad_alloc&)
4662 {
4663 return error(GL_OUT_OF_MEMORY);
4664 }
4665}
4666
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004667void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004668{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004669 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 +00004670 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004671
4672 try
4673 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004674 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004675 {
4676 return error(GL_INVALID_VALUE);
4677 }
4678
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004679 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004680
4681 if (context)
4682 {
4683 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004684
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004685 if (!shaderObject)
4686 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004687 if (context->getProgram(shader))
4688 {
4689 return error(GL_INVALID_OPERATION);
4690 }
4691 else
4692 {
4693 return error(GL_INVALID_VALUE);
4694 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004695 }
4696
4697 shaderObject->setSource(count, string, length);
4698 }
4699 }
4700 catch(std::bad_alloc&)
4701 {
4702 return error(GL_OUT_OF_MEMORY);
4703 }
4704}
4705
4706void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4707{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004708 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004709}
4710
4711void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4712{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004713 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 +00004714
4715 try
4716 {
4717 switch (face)
4718 {
4719 case GL_FRONT:
4720 case GL_BACK:
4721 case GL_FRONT_AND_BACK:
4722 break;
4723 default:
4724 return error(GL_INVALID_ENUM);
4725 }
4726
4727 switch (func)
4728 {
4729 case GL_NEVER:
4730 case GL_ALWAYS:
4731 case GL_LESS:
4732 case GL_LEQUAL:
4733 case GL_EQUAL:
4734 case GL_GEQUAL:
4735 case GL_GREATER:
4736 case GL_NOTEQUAL:
4737 break;
4738 default:
4739 return error(GL_INVALID_ENUM);
4740 }
4741
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004742 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004743
4744 if (context)
4745 {
4746 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4747 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004748 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004749 }
4750
4751 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4752 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004753 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004754 }
4755 }
4756 }
4757 catch(std::bad_alloc&)
4758 {
4759 return error(GL_OUT_OF_MEMORY);
4760 }
4761}
4762
4763void __stdcall glStencilMask(GLuint mask)
4764{
4765 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4766}
4767
4768void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4769{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004770 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004771
4772 try
4773 {
4774 switch (face)
4775 {
4776 case GL_FRONT:
4777 case GL_BACK:
4778 case GL_FRONT_AND_BACK:
4779 break;
4780 default:
4781 return error(GL_INVALID_ENUM);
4782 }
4783
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004784 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004785
4786 if (context)
4787 {
4788 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4789 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004790 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004791 }
4792
4793 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4794 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004795 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004796 }
4797 }
4798 }
4799 catch(std::bad_alloc&)
4800 {
4801 return error(GL_OUT_OF_MEMORY);
4802 }
4803}
4804
4805void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4806{
4807 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4808}
4809
4810void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4811{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004812 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 +00004813 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004814
4815 try
4816 {
4817 switch (face)
4818 {
4819 case GL_FRONT:
4820 case GL_BACK:
4821 case GL_FRONT_AND_BACK:
4822 break;
4823 default:
4824 return error(GL_INVALID_ENUM);
4825 }
4826
4827 switch (fail)
4828 {
4829 case GL_ZERO:
4830 case GL_KEEP:
4831 case GL_REPLACE:
4832 case GL_INCR:
4833 case GL_DECR:
4834 case GL_INVERT:
4835 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004836 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004837 break;
4838 default:
4839 return error(GL_INVALID_ENUM);
4840 }
4841
4842 switch (zfail)
4843 {
4844 case GL_ZERO:
4845 case GL_KEEP:
4846 case GL_REPLACE:
4847 case GL_INCR:
4848 case GL_DECR:
4849 case GL_INVERT:
4850 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004851 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004852 break;
4853 default:
4854 return error(GL_INVALID_ENUM);
4855 }
4856
4857 switch (zpass)
4858 {
4859 case GL_ZERO:
4860 case GL_KEEP:
4861 case GL_REPLACE:
4862 case GL_INCR:
4863 case GL_DECR:
4864 case GL_INVERT:
4865 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004866 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004867 break;
4868 default:
4869 return error(GL_INVALID_ENUM);
4870 }
4871
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004872 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004873
4874 if (context)
4875 {
4876 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4877 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004878 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004879 }
4880
4881 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4882 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004883 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004884 }
4885 }
4886 }
4887 catch(std::bad_alloc&)
4888 {
4889 return error(GL_OUT_OF_MEMORY);
4890 }
4891}
4892
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004893GLboolean __stdcall glTestFenceNV(GLuint fence)
4894{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004895 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004896
4897 try
4898 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004899 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004900
4901 if (context)
4902 {
4903 gl::Fence *fenceObject = context->getFence(fence);
4904
4905 if (fenceObject == NULL)
4906 {
4907 return error(GL_INVALID_OPERATION, GL_TRUE);
4908 }
4909
4910 return fenceObject->testFence();
4911 }
4912 }
4913 catch(std::bad_alloc&)
4914 {
4915 error(GL_OUT_OF_MEMORY);
4916 }
4917
4918 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004919}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004920
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004921void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4922 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004923{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004924 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 +00004925 "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 +00004926 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004927
4928 try
4929 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00004930 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004931 {
4932 return error(GL_INVALID_VALUE);
4933 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004934
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004935 if (internalformat != format)
4936 {
4937 return error(GL_INVALID_OPERATION);
4938 }
4939
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004940 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004941 {
4942 case GL_ALPHA:
4943 case GL_LUMINANCE:
4944 case GL_LUMINANCE_ALPHA:
4945 switch (type)
4946 {
4947 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004948 case GL_FLOAT:
4949 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004950 break;
4951 default:
4952 return error(GL_INVALID_ENUM);
4953 }
4954 break;
4955 case GL_RGB:
4956 switch (type)
4957 {
4958 case GL_UNSIGNED_BYTE:
4959 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004960 case GL_FLOAT:
4961 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004962 break;
4963 default:
4964 return error(GL_INVALID_ENUM);
4965 }
4966 break;
4967 case GL_RGBA:
4968 switch (type)
4969 {
4970 case GL_UNSIGNED_BYTE:
4971 case GL_UNSIGNED_SHORT_4_4_4_4:
4972 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004973 case GL_FLOAT:
4974 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004975 break;
4976 default:
4977 return error(GL_INVALID_ENUM);
4978 }
4979 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004980 case GL_BGRA_EXT:
4981 switch (type)
4982 {
4983 case GL_UNSIGNED_BYTE:
4984 break;
4985 default:
4986 return error(GL_INVALID_ENUM);
4987 }
4988 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004989 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4990 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00004991 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4992 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00004993 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004994 default:
4995 return error(GL_INVALID_VALUE);
4996 }
4997
4998 if (border != 0)
4999 {
5000 return error(GL_INVALID_VALUE);
5001 }
5002
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005003 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005004
5005 if (context)
5006 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00005007 if (level > context->getMaximumTextureLevel())
5008 {
5009 return error(GL_INVALID_VALUE);
5010 }
5011
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005012 switch (target)
5013 {
5014 case GL_TEXTURE_2D:
5015 if (width > (context->getMaximumTextureDimension() >> level) ||
5016 height > (context->getMaximumTextureDimension() >> level))
5017 {
5018 return error(GL_INVALID_VALUE);
5019 }
5020 break;
5021 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5022 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5023 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5024 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5025 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5026 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5027 if (width != height)
5028 {
5029 return error(GL_INVALID_VALUE);
5030 }
5031
5032 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
5033 height > (context->getMaximumCubeTextureDimension() >> level))
5034 {
5035 return error(GL_INVALID_VALUE);
5036 }
5037 break;
5038 default:
5039 return error(GL_INVALID_ENUM);
5040 }
5041
gman@chromium.org50c526d2011-08-10 05:19:44 +00005042 switch (format) {
5043 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5044 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5045 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00005046 {
5047 return error(GL_INVALID_OPERATION);
5048 }
5049 else
5050 {
5051 return error(GL_INVALID_ENUM);
5052 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00005053 break;
5054 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5055 if (context->supportsDXT3Textures())
5056 {
5057 return error(GL_INVALID_OPERATION);
5058 }
5059 else
5060 {
5061 return error(GL_INVALID_ENUM);
5062 }
5063 break;
5064 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5065 if (context->supportsDXT5Textures())
5066 {
5067 return error(GL_INVALID_OPERATION);
5068 }
5069 else
5070 {
5071 return error(GL_INVALID_ENUM);
5072 }
5073 break;
5074 default:
5075 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005076 }
5077
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005078 if (type == GL_FLOAT)
5079 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005080 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005081 {
5082 return error(GL_INVALID_ENUM);
5083 }
5084 }
5085 else if (type == GL_HALF_FLOAT_OES)
5086 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005087 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005088 {
5089 return error(GL_INVALID_ENUM);
5090 }
5091 }
5092
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005093 if (target == GL_TEXTURE_2D)
5094 {
5095 gl::Texture2D *texture = context->getTexture2D();
5096
5097 if (!texture)
5098 {
5099 return error(GL_INVALID_OPERATION);
5100 }
5101
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005102 if (texture->isImmutable())
5103 {
5104 return error(GL_INVALID_OPERATION);
5105 }
5106
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005107 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005108 }
5109 else
5110 {
5111 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5112
5113 if (!texture)
5114 {
5115 return error(GL_INVALID_OPERATION);
5116 }
5117
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005118 if (texture->isImmutable())
5119 {
5120 return error(GL_INVALID_OPERATION);
5121 }
5122
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005123 switch (target)
5124 {
5125 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005126 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005127 break;
5128 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005129 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005130 break;
5131 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005132 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005133 break;
5134 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005135 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005136 break;
5137 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005138 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005139 break;
5140 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005141 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005142 break;
5143 default: UNREACHABLE();
5144 }
5145 }
5146 }
5147 }
5148 catch(std::bad_alloc&)
5149 {
5150 return error(GL_OUT_OF_MEMORY);
5151 }
5152}
5153
5154void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5155{
5156 glTexParameteri(target, pname, (GLint)param);
5157}
5158
5159void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5160{
5161 glTexParameteri(target, pname, (GLint)*params);
5162}
5163
5164void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
5165{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005166 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005167
5168 try
5169 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005170 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005171
5172 if (context)
5173 {
5174 gl::Texture *texture;
5175
5176 switch (target)
5177 {
5178 case GL_TEXTURE_2D:
5179 texture = context->getTexture2D();
5180 break;
5181 case GL_TEXTURE_CUBE_MAP:
5182 texture = context->getTextureCubeMap();
5183 break;
5184 default:
5185 return error(GL_INVALID_ENUM);
5186 }
5187
5188 switch (pname)
5189 {
5190 case GL_TEXTURE_WRAP_S:
5191 if (!texture->setWrapS((GLenum)param))
5192 {
5193 return error(GL_INVALID_ENUM);
5194 }
5195 break;
5196 case GL_TEXTURE_WRAP_T:
5197 if (!texture->setWrapT((GLenum)param))
5198 {
5199 return error(GL_INVALID_ENUM);
5200 }
5201 break;
5202 case GL_TEXTURE_MIN_FILTER:
5203 if (!texture->setMinFilter((GLenum)param))
5204 {
5205 return error(GL_INVALID_ENUM);
5206 }
5207 break;
5208 case GL_TEXTURE_MAG_FILTER:
5209 if (!texture->setMagFilter((GLenum)param))
5210 {
5211 return error(GL_INVALID_ENUM);
5212 }
5213 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00005214 case GL_TEXTURE_USAGE_ANGLE:
5215 if (!texture->setUsage((GLenum)param))
5216 {
5217 return error(GL_INVALID_ENUM);
5218 }
5219 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005220 default:
5221 return error(GL_INVALID_ENUM);
5222 }
5223 }
5224 }
5225 catch(std::bad_alloc&)
5226 {
5227 return error(GL_OUT_OF_MEMORY);
5228 }
5229}
5230
5231void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5232{
5233 glTexParameteri(target, pname, *params);
5234}
5235
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005236void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5237{
5238 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5239 target, levels, internalformat, width, height);
5240
5241 try
5242 {
5243 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5244 {
5245 return error(GL_INVALID_ENUM);
5246 }
5247
5248 if (width < 1 || height < 1 || levels < 1)
5249 {
5250 return error(GL_INVALID_VALUE);
5251 }
5252
5253 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5254 {
5255 return error(GL_INVALID_VALUE);
5256 }
5257
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005258 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005259 {
5260 return error(GL_INVALID_OPERATION);
5261 }
5262
5263 GLenum format = gl::ExtractFormat(internalformat);
5264 GLenum type = gl::ExtractType(internalformat);
5265
5266 if (format == GL_NONE || type == GL_NONE)
5267 {
5268 return error(GL_INVALID_ENUM);
5269 }
5270
5271 gl::Context *context = gl::getNonLostContext();
5272
5273 if (context)
5274 {
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005275 switch (target)
5276 {
5277 case GL_TEXTURE_2D:
5278 if (width > context->getMaximumTextureDimension() ||
5279 height > context->getMaximumTextureDimension())
5280 {
5281 return error(GL_INVALID_VALUE);
5282 }
5283 break;
5284 case GL_TEXTURE_CUBE_MAP:
5285 if (width > context->getMaximumCubeTextureDimension() ||
5286 height > context->getMaximumCubeTextureDimension())
5287 {
5288 return error(GL_INVALID_VALUE);
5289 }
5290 break;
5291 default:
5292 return error(GL_INVALID_ENUM);
5293 }
5294
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005295 if (levels != 1 && !context->supportsNonPower2Texture())
5296 {
5297 if (!gl::isPow2(width) || !gl::isPow2(height))
5298 {
5299 return error(GL_INVALID_OPERATION);
5300 }
5301 }
5302
daniel@transgaming.come1077362011-11-11 04:16:50 +00005303 switch (internalformat)
5304 {
5305 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5306 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5307 if (!context->supportsDXT1Textures())
5308 {
5309 return error(GL_INVALID_ENUM);
5310 }
5311 break;
5312 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5313 if (!context->supportsDXT3Textures())
5314 {
5315 return error(GL_INVALID_ENUM);
5316 }
5317 break;
5318 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5319 if (!context->supportsDXT5Textures())
5320 {
5321 return error(GL_INVALID_ENUM);
5322 }
5323 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005324 case GL_RGBA32F_EXT:
5325 case GL_RGB32F_EXT:
5326 case GL_ALPHA32F_EXT:
5327 case GL_LUMINANCE32F_EXT:
5328 case GL_LUMINANCE_ALPHA32F_EXT:
5329 if (!context->supportsFloat32Textures())
5330 {
5331 return error(GL_INVALID_ENUM);
5332 }
5333 break;
5334 case GL_RGBA16F_EXT:
5335 case GL_RGB16F_EXT:
5336 case GL_ALPHA16F_EXT:
5337 case GL_LUMINANCE16F_EXT:
5338 case GL_LUMINANCE_ALPHA16F_EXT:
5339 if (!context->supportsFloat16Textures())
5340 {
5341 return error(GL_INVALID_ENUM);
5342 }
5343 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005344 }
5345
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005346 if (target == GL_TEXTURE_2D)
5347 {
5348 gl::Texture2D *texture = context->getTexture2D();
5349
5350 if (!texture || texture->id() == 0)
5351 {
5352 return error(GL_INVALID_OPERATION);
5353 }
5354
5355 if (texture->isImmutable())
5356 {
5357 return error(GL_INVALID_OPERATION);
5358 }
5359
5360 texture->storage(levels, internalformat, width, height);
5361 }
5362 else if (target == GL_TEXTURE_CUBE_MAP)
5363 {
5364 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5365
5366 if (!texture || texture->id() == 0)
5367 {
5368 return error(GL_INVALID_OPERATION);
5369 }
5370
5371 if (texture->isImmutable())
5372 {
5373 return error(GL_INVALID_OPERATION);
5374 }
5375
5376 texture->storage(levels, internalformat, width);
5377 }
5378 else UNREACHABLE();
5379 }
5380 }
5381 catch(std::bad_alloc&)
5382 {
5383 return error(GL_OUT_OF_MEMORY);
5384 }
5385}
5386
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005387void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5388 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005389{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005390 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005391 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005392 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005393 target, level, xoffset, yoffset, width, height, format, type, pixels);
5394
5395 try
5396 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00005397 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005398 {
5399 return error(GL_INVALID_ENUM);
5400 }
5401
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005402 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005403 {
5404 return error(GL_INVALID_VALUE);
5405 }
5406
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005407 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5408 {
5409 return error(GL_INVALID_VALUE);
5410 }
5411
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005412 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005413 {
5414 return error(GL_INVALID_ENUM);
5415 }
5416
5417 if (width == 0 || height == 0 || pixels == NULL)
5418 {
5419 return;
5420 }
5421
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005422 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005423
5424 if (context)
5425 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005426 if (level > context->getMaximumTextureLevel())
5427 {
5428 return error(GL_INVALID_VALUE);
5429 }
5430
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005431 if (format == GL_FLOAT)
5432 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005433 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005434 {
5435 return error(GL_INVALID_ENUM);
5436 }
5437 }
5438 else if (format == GL_HALF_FLOAT_OES)
5439 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005440 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005441 {
5442 return error(GL_INVALID_ENUM);
5443 }
5444 }
5445
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005446 if (target == GL_TEXTURE_2D)
5447 {
5448 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005449 if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005450 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005451 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005452 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005453 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005454 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005455 {
5456 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005457 if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005458 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005459 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005460 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005461 }
5462 else
5463 {
5464 UNREACHABLE();
5465 }
5466 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005467 }
5468 catch(std::bad_alloc&)
5469 {
5470 return error(GL_OUT_OF_MEMORY);
5471 }
5472}
5473
5474void __stdcall glUniform1f(GLint location, GLfloat x)
5475{
5476 glUniform1fv(location, 1, &x);
5477}
5478
5479void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5480{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005481 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005482
5483 try
5484 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005485 if (count < 0)
5486 {
5487 return error(GL_INVALID_VALUE);
5488 }
5489
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005490 if (location == -1)
5491 {
5492 return;
5493 }
5494
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005495 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005496
5497 if (context)
5498 {
5499 gl::Program *program = context->getCurrentProgram();
5500
5501 if (!program)
5502 {
5503 return error(GL_INVALID_OPERATION);
5504 }
5505
5506 if (!program->setUniform1fv(location, count, v))
5507 {
5508 return error(GL_INVALID_OPERATION);
5509 }
5510 }
5511 }
5512 catch(std::bad_alloc&)
5513 {
5514 return error(GL_OUT_OF_MEMORY);
5515 }
5516}
5517
5518void __stdcall glUniform1i(GLint location, GLint x)
5519{
5520 glUniform1iv(location, 1, &x);
5521}
5522
5523void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5524{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005525 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005526
5527 try
5528 {
5529 if (count < 0)
5530 {
5531 return error(GL_INVALID_VALUE);
5532 }
5533
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005534 if (location == -1)
5535 {
5536 return;
5537 }
5538
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005539 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005540
5541 if (context)
5542 {
5543 gl::Program *program = context->getCurrentProgram();
5544
5545 if (!program)
5546 {
5547 return error(GL_INVALID_OPERATION);
5548 }
5549
5550 if (!program->setUniform1iv(location, count, v))
5551 {
5552 return error(GL_INVALID_OPERATION);
5553 }
5554 }
5555 }
5556 catch(std::bad_alloc&)
5557 {
5558 return error(GL_OUT_OF_MEMORY);
5559 }
5560}
5561
5562void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5563{
5564 GLfloat xy[2] = {x, y};
5565
5566 glUniform2fv(location, 1, (GLfloat*)&xy);
5567}
5568
5569void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5570{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005571 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005572
5573 try
5574 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005575 if (count < 0)
5576 {
5577 return error(GL_INVALID_VALUE);
5578 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005579
5580 if (location == -1)
5581 {
5582 return;
5583 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005584
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005585 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005586
5587 if (context)
5588 {
5589 gl::Program *program = context->getCurrentProgram();
5590
5591 if (!program)
5592 {
5593 return error(GL_INVALID_OPERATION);
5594 }
5595
5596 if (!program->setUniform2fv(location, count, v))
5597 {
5598 return error(GL_INVALID_OPERATION);
5599 }
5600 }
5601 }
5602 catch(std::bad_alloc&)
5603 {
5604 return error(GL_OUT_OF_MEMORY);
5605 }
5606}
5607
5608void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5609{
5610 GLint xy[4] = {x, y};
5611
5612 glUniform2iv(location, 1, (GLint*)&xy);
5613}
5614
5615void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5616{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005617 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005618
5619 try
5620 {
5621 if (count < 0)
5622 {
5623 return error(GL_INVALID_VALUE);
5624 }
5625
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005626 if (location == -1)
5627 {
5628 return;
5629 }
5630
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005631 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005632
5633 if (context)
5634 {
5635 gl::Program *program = context->getCurrentProgram();
5636
5637 if (!program)
5638 {
5639 return error(GL_INVALID_OPERATION);
5640 }
5641
5642 if (!program->setUniform2iv(location, count, v))
5643 {
5644 return error(GL_INVALID_OPERATION);
5645 }
5646 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005647 }
5648 catch(std::bad_alloc&)
5649 {
5650 return error(GL_OUT_OF_MEMORY);
5651 }
5652}
5653
5654void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5655{
5656 GLfloat xyz[3] = {x, y, z};
5657
5658 glUniform3fv(location, 1, (GLfloat*)&xyz);
5659}
5660
5661void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5662{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005663 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005664
5665 try
5666 {
5667 if (count < 0)
5668 {
5669 return error(GL_INVALID_VALUE);
5670 }
5671
5672 if (location == -1)
5673 {
5674 return;
5675 }
5676
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005677 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005678
5679 if (context)
5680 {
5681 gl::Program *program = context->getCurrentProgram();
5682
5683 if (!program)
5684 {
5685 return error(GL_INVALID_OPERATION);
5686 }
5687
5688 if (!program->setUniform3fv(location, count, v))
5689 {
5690 return error(GL_INVALID_OPERATION);
5691 }
5692 }
5693 }
5694 catch(std::bad_alloc&)
5695 {
5696 return error(GL_OUT_OF_MEMORY);
5697 }
5698}
5699
5700void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5701{
5702 GLint xyz[3] = {x, y, z};
5703
5704 glUniform3iv(location, 1, (GLint*)&xyz);
5705}
5706
5707void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5708{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005709 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005710
5711 try
5712 {
5713 if (count < 0)
5714 {
5715 return error(GL_INVALID_VALUE);
5716 }
5717
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005718 if (location == -1)
5719 {
5720 return;
5721 }
5722
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005723 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005724
5725 if (context)
5726 {
5727 gl::Program *program = context->getCurrentProgram();
5728
5729 if (!program)
5730 {
5731 return error(GL_INVALID_OPERATION);
5732 }
5733
5734 if (!program->setUniform3iv(location, count, v))
5735 {
5736 return error(GL_INVALID_OPERATION);
5737 }
5738 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005739 }
5740 catch(std::bad_alloc&)
5741 {
5742 return error(GL_OUT_OF_MEMORY);
5743 }
5744}
5745
5746void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5747{
5748 GLfloat xyzw[4] = {x, y, z, w};
5749
5750 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5751}
5752
5753void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5754{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005755 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005756
5757 try
5758 {
5759 if (count < 0)
5760 {
5761 return error(GL_INVALID_VALUE);
5762 }
5763
5764 if (location == -1)
5765 {
5766 return;
5767 }
5768
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005769 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005770
5771 if (context)
5772 {
5773 gl::Program *program = context->getCurrentProgram();
5774
5775 if (!program)
5776 {
5777 return error(GL_INVALID_OPERATION);
5778 }
5779
5780 if (!program->setUniform4fv(location, count, v))
5781 {
5782 return error(GL_INVALID_OPERATION);
5783 }
5784 }
5785 }
5786 catch(std::bad_alloc&)
5787 {
5788 return error(GL_OUT_OF_MEMORY);
5789 }
5790}
5791
5792void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5793{
5794 GLint xyzw[4] = {x, y, z, w};
5795
5796 glUniform4iv(location, 1, (GLint*)&xyzw);
5797}
5798
5799void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5800{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005801 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005802
5803 try
5804 {
5805 if (count < 0)
5806 {
5807 return error(GL_INVALID_VALUE);
5808 }
5809
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005810 if (location == -1)
5811 {
5812 return;
5813 }
5814
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005815 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005816
5817 if (context)
5818 {
5819 gl::Program *program = context->getCurrentProgram();
5820
5821 if (!program)
5822 {
5823 return error(GL_INVALID_OPERATION);
5824 }
5825
5826 if (!program->setUniform4iv(location, count, v))
5827 {
5828 return error(GL_INVALID_OPERATION);
5829 }
5830 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005831 }
5832 catch(std::bad_alloc&)
5833 {
5834 return error(GL_OUT_OF_MEMORY);
5835 }
5836}
5837
5838void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5839{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005840 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005841 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005842
5843 try
5844 {
5845 if (count < 0 || transpose != GL_FALSE)
5846 {
5847 return error(GL_INVALID_VALUE);
5848 }
5849
5850 if (location == -1)
5851 {
5852 return;
5853 }
5854
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005855 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005856
5857 if (context)
5858 {
5859 gl::Program *program = context->getCurrentProgram();
5860
5861 if (!program)
5862 {
5863 return error(GL_INVALID_OPERATION);
5864 }
5865
5866 if (!program->setUniformMatrix2fv(location, count, value))
5867 {
5868 return error(GL_INVALID_OPERATION);
5869 }
5870 }
5871 }
5872 catch(std::bad_alloc&)
5873 {
5874 return error(GL_OUT_OF_MEMORY);
5875 }
5876}
5877
5878void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5879{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005880 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005881 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005882
5883 try
5884 {
5885 if (count < 0 || transpose != GL_FALSE)
5886 {
5887 return error(GL_INVALID_VALUE);
5888 }
5889
5890 if (location == -1)
5891 {
5892 return;
5893 }
5894
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005895 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005896
5897 if (context)
5898 {
5899 gl::Program *program = context->getCurrentProgram();
5900
5901 if (!program)
5902 {
5903 return error(GL_INVALID_OPERATION);
5904 }
5905
5906 if (!program->setUniformMatrix3fv(location, count, value))
5907 {
5908 return error(GL_INVALID_OPERATION);
5909 }
5910 }
5911 }
5912 catch(std::bad_alloc&)
5913 {
5914 return error(GL_OUT_OF_MEMORY);
5915 }
5916}
5917
5918void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5919{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005920 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005921 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005922
5923 try
5924 {
5925 if (count < 0 || transpose != GL_FALSE)
5926 {
5927 return error(GL_INVALID_VALUE);
5928 }
5929
5930 if (location == -1)
5931 {
5932 return;
5933 }
5934
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005935 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005936
5937 if (context)
5938 {
5939 gl::Program *program = context->getCurrentProgram();
5940
5941 if (!program)
5942 {
5943 return error(GL_INVALID_OPERATION);
5944 }
5945
5946 if (!program->setUniformMatrix4fv(location, count, value))
5947 {
5948 return error(GL_INVALID_OPERATION);
5949 }
5950 }
5951 }
5952 catch(std::bad_alloc&)
5953 {
5954 return error(GL_OUT_OF_MEMORY);
5955 }
5956}
5957
5958void __stdcall glUseProgram(GLuint program)
5959{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005960 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005961
5962 try
5963 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005964 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005965
5966 if (context)
5967 {
5968 gl::Program *programObject = context->getProgram(program);
5969
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005970 if (!programObject && program != 0)
5971 {
5972 if (context->getShader(program))
5973 {
5974 return error(GL_INVALID_OPERATION);
5975 }
5976 else
5977 {
5978 return error(GL_INVALID_VALUE);
5979 }
5980 }
5981
5982 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005983 {
5984 return error(GL_INVALID_OPERATION);
5985 }
5986
5987 context->useProgram(program);
5988 }
5989 }
5990 catch(std::bad_alloc&)
5991 {
5992 return error(GL_OUT_OF_MEMORY);
5993 }
5994}
5995
5996void __stdcall glValidateProgram(GLuint program)
5997{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005998 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005999
6000 try
6001 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006002 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006003
6004 if (context)
6005 {
6006 gl::Program *programObject = context->getProgram(program);
6007
6008 if (!programObject)
6009 {
6010 if (context->getShader(program))
6011 {
6012 return error(GL_INVALID_OPERATION);
6013 }
6014 else
6015 {
6016 return error(GL_INVALID_VALUE);
6017 }
6018 }
6019
6020 programObject->validate();
6021 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006022 }
6023 catch(std::bad_alloc&)
6024 {
6025 return error(GL_OUT_OF_MEMORY);
6026 }
6027}
6028
6029void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
6030{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006031 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006032
6033 try
6034 {
6035 if (index >= gl::MAX_VERTEX_ATTRIBS)
6036 {
6037 return error(GL_INVALID_VALUE);
6038 }
6039
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006040 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006041
6042 if (context)
6043 {
6044 GLfloat vals[4] = { x, 0, 0, 1 };
6045 context->setVertexAttrib(index, vals);
6046 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006047 }
6048 catch(std::bad_alloc&)
6049 {
6050 return error(GL_OUT_OF_MEMORY);
6051 }
6052}
6053
6054void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
6055{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006056 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006057
6058 try
6059 {
6060 if (index >= gl::MAX_VERTEX_ATTRIBS)
6061 {
6062 return error(GL_INVALID_VALUE);
6063 }
6064
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006065 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006066
6067 if (context)
6068 {
6069 GLfloat vals[4] = { values[0], 0, 0, 1 };
6070 context->setVertexAttrib(index, vals);
6071 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006072 }
6073 catch(std::bad_alloc&)
6074 {
6075 return error(GL_OUT_OF_MEMORY);
6076 }
6077}
6078
6079void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6080{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006081 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006082
6083 try
6084 {
6085 if (index >= gl::MAX_VERTEX_ATTRIBS)
6086 {
6087 return error(GL_INVALID_VALUE);
6088 }
6089
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006090 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006091
6092 if (context)
6093 {
6094 GLfloat vals[4] = { x, y, 0, 1 };
6095 context->setVertexAttrib(index, vals);
6096 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006097 }
6098 catch(std::bad_alloc&)
6099 {
6100 return error(GL_OUT_OF_MEMORY);
6101 }
6102}
6103
6104void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
6105{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006106 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006107
6108 try
6109 {
6110 if (index >= gl::MAX_VERTEX_ATTRIBS)
6111 {
6112 return error(GL_INVALID_VALUE);
6113 }
6114
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006115 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006116
6117 if (context)
6118 {
6119 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6120 context->setVertexAttrib(index, vals);
6121 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006122 }
6123 catch(std::bad_alloc&)
6124 {
6125 return error(GL_OUT_OF_MEMORY);
6126 }
6127}
6128
6129void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6130{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006131 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 +00006132
6133 try
6134 {
6135 if (index >= gl::MAX_VERTEX_ATTRIBS)
6136 {
6137 return error(GL_INVALID_VALUE);
6138 }
6139
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006140 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006141
6142 if (context)
6143 {
6144 GLfloat vals[4] = { x, y, z, 1 };
6145 context->setVertexAttrib(index, vals);
6146 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006147 }
6148 catch(std::bad_alloc&)
6149 {
6150 return error(GL_OUT_OF_MEMORY);
6151 }
6152}
6153
6154void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
6155{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006156 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006157
6158 try
6159 {
6160 if (index >= gl::MAX_VERTEX_ATTRIBS)
6161 {
6162 return error(GL_INVALID_VALUE);
6163 }
6164
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006165 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006166
6167 if (context)
6168 {
6169 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6170 context->setVertexAttrib(index, vals);
6171 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006172 }
6173 catch(std::bad_alloc&)
6174 {
6175 return error(GL_OUT_OF_MEMORY);
6176 }
6177}
6178
6179void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6180{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006181 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 +00006182
6183 try
6184 {
6185 if (index >= gl::MAX_VERTEX_ATTRIBS)
6186 {
6187 return error(GL_INVALID_VALUE);
6188 }
6189
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006190 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006191
6192 if (context)
6193 {
6194 GLfloat vals[4] = { x, y, z, w };
6195 context->setVertexAttrib(index, vals);
6196 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006197 }
6198 catch(std::bad_alloc&)
6199 {
6200 return error(GL_OUT_OF_MEMORY);
6201 }
6202}
6203
6204void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
6205{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006206 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006207
6208 try
6209 {
6210 if (index >= gl::MAX_VERTEX_ATTRIBS)
6211 {
6212 return error(GL_INVALID_VALUE);
6213 }
6214
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006215 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006216
6217 if (context)
6218 {
6219 context->setVertexAttrib(index, values);
6220 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006221 }
6222 catch(std::bad_alloc&)
6223 {
6224 return error(GL_OUT_OF_MEMORY);
6225 }
6226}
6227
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006228void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006229{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006230 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006231 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006232 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006233
6234 try
6235 {
6236 if (index >= gl::MAX_VERTEX_ATTRIBS)
6237 {
6238 return error(GL_INVALID_VALUE);
6239 }
6240
6241 if (size < 1 || size > 4)
6242 {
6243 return error(GL_INVALID_VALUE);
6244 }
6245
6246 switch (type)
6247 {
6248 case GL_BYTE:
6249 case GL_UNSIGNED_BYTE:
6250 case GL_SHORT:
6251 case GL_UNSIGNED_SHORT:
6252 case GL_FIXED:
6253 case GL_FLOAT:
6254 break;
6255 default:
6256 return error(GL_INVALID_ENUM);
6257 }
6258
6259 if (stride < 0)
6260 {
6261 return error(GL_INVALID_VALUE);
6262 }
6263
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006264 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006265
6266 if (context)
6267 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006268 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006269 }
6270 }
6271 catch(std::bad_alloc&)
6272 {
6273 return error(GL_OUT_OF_MEMORY);
6274 }
6275}
6276
6277void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6278{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006279 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 +00006280
6281 try
6282 {
6283 if (width < 0 || height < 0)
6284 {
6285 return error(GL_INVALID_VALUE);
6286 }
6287
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006288 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006289
6290 if (context)
6291 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006292 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006293 }
6294 }
6295 catch(std::bad_alloc&)
6296 {
6297 return error(GL_OUT_OF_MEMORY);
6298 }
6299}
6300
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006301void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6302 GLbitfield mask, GLenum filter)
6303{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006304 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006305 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6306 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6307 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6308
6309 try
6310 {
6311 switch (filter)
6312 {
6313 case GL_NEAREST:
6314 break;
6315 default:
6316 return error(GL_INVALID_ENUM);
6317 }
6318
6319 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6320 {
6321 return error(GL_INVALID_VALUE);
6322 }
6323
6324 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6325 {
6326 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6327 return error(GL_INVALID_OPERATION);
6328 }
6329
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006330 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006331
6332 if (context)
6333 {
6334 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6335 {
6336 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6337 return error(GL_INVALID_OPERATION);
6338 }
6339
6340 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6341 }
6342 }
6343 catch(std::bad_alloc&)
6344 {
6345 return error(GL_OUT_OF_MEMORY);
6346 }
6347}
6348
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006349void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6350 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006351{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006352 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006353 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006354 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006355 target, level, internalformat, width, height, depth, border, format, type, pixels);
6356
6357 try
6358 {
6359 UNIMPLEMENTED(); // FIXME
6360 }
6361 catch(std::bad_alloc&)
6362 {
6363 return error(GL_OUT_OF_MEMORY);
6364 }
6365}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006366
6367__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6368{
6369 struct Extension
6370 {
6371 const char *name;
6372 __eglMustCastToProperFunctionPointerType address;
6373 };
6374
6375 static const Extension glExtensions[] =
6376 {
6377 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006378 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006379 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006380 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6381 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6382 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6383 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6384 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6385 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6386 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006387 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006388 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006389 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6390 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6391 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6392 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00006393 {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT},
6394 {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT},
6395 {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT},
6396 {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT},
6397 {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
6398 {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
6399 {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006400 };
6401
6402 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6403 {
6404 if (strcmp(procname, glExtensions[ext].name) == 0)
6405 {
6406 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6407 }
6408 }
6409
6410 return NULL;
6411}
6412
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006413// Non-public functions used by EGL
6414
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006415bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006416{
6417 EVENT("(egl::Surface* surface = 0x%0.8p)",
6418 surface);
6419
6420 try
6421 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006422 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006423
6424 if (context)
6425 {
6426 gl::Texture2D *textureObject = context->getTexture2D();
6427
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006428 if (textureObject->isImmutable())
6429 {
6430 return false;
6431 }
6432
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006433 if (textureObject)
6434 {
6435 textureObject->bindTexImage(surface);
6436 }
6437 }
6438 }
6439 catch(std::bad_alloc&)
6440 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006441 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006442 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006443
6444 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006445}
6446
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006447}