blob: 147bd0fb31ee75a81ffb27f9aa4e04dcda2f7524 [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.comd2820bf2012-01-27 15:38:48 +00001955void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
1956{
1957 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
1958
1959 try
1960 {
1961 if (count < 0 || first < 0 || primcount < 0)
1962 {
1963 return error(GL_INVALID_VALUE);
1964 }
1965
1966 gl::Context *context = gl::getNonLostContext();
1967
1968 if (context)
1969 {
1970 context->drawArraysInstanced(mode, first, count, primcount);
1971 }
1972 }
1973 catch(std::bad_alloc&)
1974 {
1975 return error(GL_OUT_OF_MEMORY);
1976 }
1977}
1978
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001979void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001980{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001981 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 +00001982 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001983
1984 try
1985 {
1986 if (count < 0)
1987 {
1988 return error(GL_INVALID_VALUE);
1989 }
1990
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001991 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001992
1993 if (context)
1994 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001995 switch (type)
1996 {
1997 case GL_UNSIGNED_BYTE:
1998 case GL_UNSIGNED_SHORT:
1999 break;
2000 case GL_UNSIGNED_INT:
2001 if (!context->supports32bitIndices())
2002 {
2003 return error(GL_INVALID_ENUM);
2004 }
2005 break;
2006 default:
2007 return error(GL_INVALID_ENUM);
2008 }
2009
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002010 context->drawElements(mode, count, type, indices);
2011 }
2012 }
2013 catch(std::bad_alloc&)
2014 {
2015 return error(GL_OUT_OF_MEMORY);
2016 }
2017}
2018
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002019void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)
2020{
2021 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)",
2022 mode, count, type, indices, primcount);
2023
2024 try
2025 {
2026 if (count < 0 || primcount < 0)
2027 {
2028 return error(GL_INVALID_VALUE);
2029 }
2030
2031 gl::Context *context = gl::getNonLostContext();
2032
2033 if (context)
2034 {
2035 switch (type)
2036 {
2037 case GL_UNSIGNED_BYTE:
2038 case GL_UNSIGNED_SHORT:
2039 break;
2040 case GL_UNSIGNED_INT:
2041 if (!context->supports32bitIndices())
2042 {
2043 return error(GL_INVALID_ENUM);
2044 }
2045 break;
2046 default:
2047 return error(GL_INVALID_ENUM);
2048 }
2049
2050 context->drawElementsInstanced(mode, count, type, indices, primcount);
2051 }
2052 }
2053 catch(std::bad_alloc&)
2054 {
2055 return error(GL_OUT_OF_MEMORY);
2056 }
2057}
2058
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002059void __stdcall glEnable(GLenum cap)
2060{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002061 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002062
2063 try
2064 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002065 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002066
2067 if (context)
2068 {
2069 switch (cap)
2070 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002071 case GL_CULL_FACE: context->setCullFace(true); break;
2072 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
2073 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
2074 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
2075 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
2076 case GL_STENCIL_TEST: context->setStencilTest(true); break;
2077 case GL_DEPTH_TEST: context->setDepthTest(true); break;
2078 case GL_BLEND: context->setBlend(true); break;
2079 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002080 default:
2081 return error(GL_INVALID_ENUM);
2082 }
2083 }
2084 }
2085 catch(std::bad_alloc&)
2086 {
2087 return error(GL_OUT_OF_MEMORY);
2088 }
2089}
2090
2091void __stdcall glEnableVertexAttribArray(GLuint index)
2092{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002093 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002094
2095 try
2096 {
2097 if (index >= gl::MAX_VERTEX_ATTRIBS)
2098 {
2099 return error(GL_INVALID_VALUE);
2100 }
2101
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002102 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002103
2104 if (context)
2105 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002106 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002107 }
2108 }
2109 catch(std::bad_alloc&)
2110 {
2111 return error(GL_OUT_OF_MEMORY);
2112 }
2113}
2114
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00002115void __stdcall glEndQueryEXT(GLenum target)
2116{
2117 EVENT("GLenum target = 0x%X)", target);
2118
2119 try
2120 {
2121 switch (target)
2122 {
2123 case GL_ANY_SAMPLES_PASSED_EXT:
2124 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
2125 break;
2126 default:
2127 return error(GL_INVALID_ENUM);
2128 }
2129
2130 gl::Context *context = gl::getNonLostContext();
2131
2132 if (context)
2133 {
2134 context->endQuery(target);
2135 }
2136 }
2137 catch(std::bad_alloc&)
2138 {
2139 return error(GL_OUT_OF_MEMORY);
2140 }
2141}
2142
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002143void __stdcall glFinishFenceNV(GLuint fence)
2144{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002145 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002146
2147 try
2148 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002149 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002150
2151 if (context)
2152 {
2153 gl::Fence* fenceObject = context->getFence(fence);
2154
2155 if (fenceObject == NULL)
2156 {
2157 return error(GL_INVALID_OPERATION);
2158 }
2159
2160 fenceObject->finishFence();
2161 }
2162 }
2163 catch(std::bad_alloc&)
2164 {
2165 return error(GL_OUT_OF_MEMORY);
2166 }
2167}
2168
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002169void __stdcall glFinish(void)
2170{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002171 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002172
2173 try
2174 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002175 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002176
2177 if (context)
2178 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002179 context->sync(true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002180 }
2181 }
2182 catch(std::bad_alloc&)
2183 {
2184 return error(GL_OUT_OF_MEMORY);
2185 }
2186}
2187
2188void __stdcall glFlush(void)
2189{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002190 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002191
2192 try
2193 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002194 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002195
2196 if (context)
2197 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002198 context->sync(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002199 }
2200 }
2201 catch(std::bad_alloc&)
2202 {
2203 return error(GL_OUT_OF_MEMORY);
2204 }
2205}
2206
2207void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2208{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002209 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002210 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002211
2212 try
2213 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002214 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002215 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002216 {
2217 return error(GL_INVALID_ENUM);
2218 }
2219
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002220 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002221
2222 if (context)
2223 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002224 gl::Framebuffer *framebuffer = NULL;
2225 GLuint framebufferHandle = 0;
2226 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2227 {
2228 framebuffer = context->getReadFramebuffer();
2229 framebufferHandle = context->getReadFramebufferHandle();
2230 }
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002231 else
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002232 {
2233 framebuffer = context->getDrawFramebuffer();
2234 framebufferHandle = context->getDrawFramebufferHandle();
2235 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002236
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002237 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002238 {
2239 return error(GL_INVALID_OPERATION);
2240 }
2241
2242 switch (attachment)
2243 {
2244 case GL_COLOR_ATTACHMENT0:
2245 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2246 break;
2247 case GL_DEPTH_ATTACHMENT:
2248 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2249 break;
2250 case GL_STENCIL_ATTACHMENT:
2251 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2252 break;
2253 default:
2254 return error(GL_INVALID_ENUM);
2255 }
2256 }
2257 }
2258 catch(std::bad_alloc&)
2259 {
2260 return error(GL_OUT_OF_MEMORY);
2261 }
2262}
2263
2264void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2265{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002266 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002267 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002268
2269 try
2270 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002271 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002272 {
2273 return error(GL_INVALID_ENUM);
2274 }
2275
2276 switch (attachment)
2277 {
2278 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002279 case GL_DEPTH_ATTACHMENT:
2280 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002281 break;
2282 default:
2283 return error(GL_INVALID_ENUM);
2284 }
2285
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002286 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002287
2288 if (context)
2289 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002290 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002291 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002292 textarget = GL_NONE;
2293 }
2294 else
2295 {
2296 gl::Texture *tex = context->getTexture(texture);
2297
2298 if (tex == NULL)
2299 {
2300 return error(GL_INVALID_OPERATION);
2301 }
2302
daniel@transgaming.com01868132010-08-24 19:21:17 +00002303 if (tex->isCompressed())
2304 {
2305 return error(GL_INVALID_OPERATION);
2306 }
2307
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002308 switch (textarget)
2309 {
2310 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002311 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002312 {
2313 return error(GL_INVALID_OPERATION);
2314 }
2315 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002316
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002317 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002318 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002319 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002320 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002321 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002322 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002323 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2324 {
2325 return error(GL_INVALID_OPERATION);
2326 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002327 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002328
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002329 default:
2330 return error(GL_INVALID_ENUM);
2331 }
2332
2333 if (level != 0)
2334 {
2335 return error(GL_INVALID_VALUE);
2336 }
2337 }
2338
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002339 gl::Framebuffer *framebuffer = NULL;
2340 GLuint framebufferHandle = 0;
2341 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2342 {
2343 framebuffer = context->getReadFramebuffer();
2344 framebufferHandle = context->getReadFramebufferHandle();
2345 }
2346 else
2347 {
2348 framebuffer = context->getDrawFramebuffer();
2349 framebufferHandle = context->getDrawFramebufferHandle();
2350 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002351
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002352 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002353 {
2354 return error(GL_INVALID_OPERATION);
2355 }
2356
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002357 switch (attachment)
2358 {
2359 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2360 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2361 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2362 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002363 }
2364 }
2365 catch(std::bad_alloc&)
2366 {
2367 return error(GL_OUT_OF_MEMORY);
2368 }
2369}
2370
2371void __stdcall glFrontFace(GLenum mode)
2372{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002373 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002374
2375 try
2376 {
2377 switch (mode)
2378 {
2379 case GL_CW:
2380 case GL_CCW:
2381 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002382 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002383
2384 if (context)
2385 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002386 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002387 }
2388 }
2389 break;
2390 default:
2391 return error(GL_INVALID_ENUM);
2392 }
2393 }
2394 catch(std::bad_alloc&)
2395 {
2396 return error(GL_OUT_OF_MEMORY);
2397 }
2398}
2399
2400void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2401{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002402 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002403
2404 try
2405 {
2406 if (n < 0)
2407 {
2408 return error(GL_INVALID_VALUE);
2409 }
2410
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002411 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002412
2413 if (context)
2414 {
2415 for (int i = 0; i < n; i++)
2416 {
2417 buffers[i] = context->createBuffer();
2418 }
2419 }
2420 }
2421 catch(std::bad_alloc&)
2422 {
2423 return error(GL_OUT_OF_MEMORY);
2424 }
2425}
2426
2427void __stdcall glGenerateMipmap(GLenum target)
2428{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002429 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002430
2431 try
2432 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002433 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002434
2435 if (context)
2436 {
2437 gl::Texture *texture;
2438
2439 switch (target)
2440 {
2441 case GL_TEXTURE_2D:
2442 texture = context->getTexture2D();
2443 break;
2444
2445 case GL_TEXTURE_CUBE_MAP:
2446 texture = context->getTextureCubeMap();
2447 break;
2448
2449 default:
2450 return error(GL_INVALID_ENUM);
2451 }
2452
daniel@transgaming.com01868132010-08-24 19:21:17 +00002453 if (texture->isCompressed())
2454 {
2455 return error(GL_INVALID_OPERATION);
2456 }
2457
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002458 texture->generateMipmaps();
2459 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002460 }
2461 catch(std::bad_alloc&)
2462 {
2463 return error(GL_OUT_OF_MEMORY);
2464 }
2465}
2466
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002467void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2468{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002469 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002470
2471 try
2472 {
2473 if (n < 0)
2474 {
2475 return error(GL_INVALID_VALUE);
2476 }
2477
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002478 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002479
2480 if (context)
2481 {
2482 for (int i = 0; i < n; i++)
2483 {
2484 fences[i] = context->createFence();
2485 }
2486 }
2487 }
2488 catch(std::bad_alloc&)
2489 {
2490 return error(GL_OUT_OF_MEMORY);
2491 }
2492}
2493
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002494void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2495{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002496 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002497
2498 try
2499 {
2500 if (n < 0)
2501 {
2502 return error(GL_INVALID_VALUE);
2503 }
2504
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002505 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002506
2507 if (context)
2508 {
2509 for (int i = 0; i < n; i++)
2510 {
2511 framebuffers[i] = context->createFramebuffer();
2512 }
2513 }
2514 }
2515 catch(std::bad_alloc&)
2516 {
2517 return error(GL_OUT_OF_MEMORY);
2518 }
2519}
2520
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00002521void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
2522{
2523 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
2524
2525 try
2526 {
2527 if (n < 0)
2528 {
2529 return error(GL_INVALID_VALUE);
2530 }
2531
2532 gl::Context *context = gl::getNonLostContext();
2533
2534 if (context)
2535 {
2536 for (int i = 0; i < n; i++)
2537 {
2538 ids[i] = context->createQuery();
2539 }
2540 }
2541 }
2542 catch(std::bad_alloc&)
2543 {
2544 return error(GL_OUT_OF_MEMORY);
2545 }
2546}
2547
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002548void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2549{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002550 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002551
2552 try
2553 {
2554 if (n < 0)
2555 {
2556 return error(GL_INVALID_VALUE);
2557 }
2558
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002559 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002560
2561 if (context)
2562 {
2563 for (int i = 0; i < n; i++)
2564 {
2565 renderbuffers[i] = context->createRenderbuffer();
2566 }
2567 }
2568 }
2569 catch(std::bad_alloc&)
2570 {
2571 return error(GL_OUT_OF_MEMORY);
2572 }
2573}
2574
2575void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2576{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002577 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002578
2579 try
2580 {
2581 if (n < 0)
2582 {
2583 return error(GL_INVALID_VALUE);
2584 }
2585
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002586 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002587
2588 if (context)
2589 {
2590 for (int i = 0; i < n; i++)
2591 {
2592 textures[i] = context->createTexture();
2593 }
2594 }
2595 }
2596 catch(std::bad_alloc&)
2597 {
2598 return error(GL_OUT_OF_MEMORY);
2599 }
2600}
2601
daniel@transgaming.com85423182010-04-22 13:35:27 +00002602void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002603{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002604 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002605 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002606 program, index, bufsize, length, size, type, name);
2607
2608 try
2609 {
2610 if (bufsize < 0)
2611 {
2612 return error(GL_INVALID_VALUE);
2613 }
2614
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002615 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com85423182010-04-22 13:35:27 +00002616
2617 if (context)
2618 {
2619 gl::Program *programObject = context->getProgram(program);
2620
2621 if (!programObject)
2622 {
2623 if (context->getShader(program))
2624 {
2625 return error(GL_INVALID_OPERATION);
2626 }
2627 else
2628 {
2629 return error(GL_INVALID_VALUE);
2630 }
2631 }
2632
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002633 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002634 {
2635 return error(GL_INVALID_VALUE);
2636 }
2637
2638 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2639 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002640 }
2641 catch(std::bad_alloc&)
2642 {
2643 return error(GL_OUT_OF_MEMORY);
2644 }
2645}
2646
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002647void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002648{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002649 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002650 "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 +00002651 program, index, bufsize, length, size, type, name);
2652
2653 try
2654 {
2655 if (bufsize < 0)
2656 {
2657 return error(GL_INVALID_VALUE);
2658 }
2659
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002660 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002661
2662 if (context)
2663 {
2664 gl::Program *programObject = context->getProgram(program);
2665
2666 if (!programObject)
2667 {
2668 if (context->getShader(program))
2669 {
2670 return error(GL_INVALID_OPERATION);
2671 }
2672 else
2673 {
2674 return error(GL_INVALID_VALUE);
2675 }
2676 }
2677
2678 if (index >= (GLuint)programObject->getActiveUniformCount())
2679 {
2680 return error(GL_INVALID_VALUE);
2681 }
2682
2683 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2684 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002685 }
2686 catch(std::bad_alloc&)
2687 {
2688 return error(GL_OUT_OF_MEMORY);
2689 }
2690}
2691
2692void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2693{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002694 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 +00002695 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002696
2697 try
2698 {
2699 if (maxcount < 0)
2700 {
2701 return error(GL_INVALID_VALUE);
2702 }
2703
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002704 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002705
2706 if (context)
2707 {
2708 gl::Program *programObject = context->getProgram(program);
2709
2710 if (!programObject)
2711 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002712 if (context->getShader(program))
2713 {
2714 return error(GL_INVALID_OPERATION);
2715 }
2716 else
2717 {
2718 return error(GL_INVALID_VALUE);
2719 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002720 }
2721
2722 return programObject->getAttachedShaders(maxcount, count, shaders);
2723 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002724 }
2725 catch(std::bad_alloc&)
2726 {
2727 return error(GL_OUT_OF_MEMORY);
2728 }
2729}
2730
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002731int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002732{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002733 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002734
2735 try
2736 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002737 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002738
2739 if (context)
2740 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002741
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002742 gl::Program *programObject = context->getProgram(program);
2743
2744 if (!programObject)
2745 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002746 if (context->getShader(program))
2747 {
2748 return error(GL_INVALID_OPERATION, -1);
2749 }
2750 else
2751 {
2752 return error(GL_INVALID_VALUE, -1);
2753 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002754 }
2755
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002756 if (!programObject->isLinked())
2757 {
2758 return error(GL_INVALID_OPERATION, -1);
2759 }
2760
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002761 return programObject->getAttributeLocation(name);
2762 }
2763 }
2764 catch(std::bad_alloc&)
2765 {
2766 return error(GL_OUT_OF_MEMORY, -1);
2767 }
2768
2769 return -1;
2770}
2771
2772void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2773{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002774 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002775
2776 try
2777 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002778 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002779
2780 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002781 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002782 if (!(context->getBooleanv(pname, params)))
2783 {
2784 GLenum nativeType;
2785 unsigned int numParams = 0;
2786 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2787 return error(GL_INVALID_ENUM);
2788
2789 if (numParams == 0)
2790 return; // it is known that the pname is valid, but there are no parameters to return
2791
2792 if (nativeType == GL_FLOAT)
2793 {
2794 GLfloat *floatParams = NULL;
2795 floatParams = new GLfloat[numParams];
2796
2797 context->getFloatv(pname, floatParams);
2798
2799 for (unsigned int i = 0; i < numParams; ++i)
2800 {
2801 if (floatParams[i] == 0.0f)
2802 params[i] = GL_FALSE;
2803 else
2804 params[i] = GL_TRUE;
2805 }
2806
2807 delete [] floatParams;
2808 }
2809 else if (nativeType == GL_INT)
2810 {
2811 GLint *intParams = NULL;
2812 intParams = new GLint[numParams];
2813
2814 context->getIntegerv(pname, intParams);
2815
2816 for (unsigned int i = 0; i < numParams; ++i)
2817 {
2818 if (intParams[i] == 0)
2819 params[i] = GL_FALSE;
2820 else
2821 params[i] = GL_TRUE;
2822 }
2823
2824 delete [] intParams;
2825 }
2826 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002827 }
2828 }
2829 catch(std::bad_alloc&)
2830 {
2831 return error(GL_OUT_OF_MEMORY);
2832 }
2833}
2834
2835void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2836{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002837 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 +00002838
2839 try
2840 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002841 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002842
2843 if (context)
2844 {
2845 gl::Buffer *buffer;
2846
2847 switch (target)
2848 {
2849 case GL_ARRAY_BUFFER:
2850 buffer = context->getArrayBuffer();
2851 break;
2852 case GL_ELEMENT_ARRAY_BUFFER:
2853 buffer = context->getElementArrayBuffer();
2854 break;
2855 default: return error(GL_INVALID_ENUM);
2856 }
2857
2858 if (!buffer)
2859 {
2860 // A null buffer means that "0" is bound to the requested buffer target
2861 return error(GL_INVALID_OPERATION);
2862 }
2863
2864 switch (pname)
2865 {
2866 case GL_BUFFER_USAGE:
2867 *params = buffer->usage();
2868 break;
2869 case GL_BUFFER_SIZE:
2870 *params = buffer->size();
2871 break;
2872 default: return error(GL_INVALID_ENUM);
2873 }
2874 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002875 }
2876 catch(std::bad_alloc&)
2877 {
2878 return error(GL_OUT_OF_MEMORY);
2879 }
2880}
2881
2882GLenum __stdcall glGetError(void)
2883{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002884 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002885
2886 gl::Context *context = gl::getContext();
2887
2888 if (context)
2889 {
daniel@transgaming.com82b28912011-12-12 21:01:35 +00002890 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002891 }
2892
2893 return GL_NO_ERROR;
2894}
2895
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002896void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2897{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002898 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002899
2900 try
2901 {
2902
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002903 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002904
2905 if (context)
2906 {
2907 gl::Fence *fenceObject = context->getFence(fence);
2908
2909 if (fenceObject == NULL)
2910 {
2911 return error(GL_INVALID_OPERATION);
2912 }
2913
2914 fenceObject->getFenceiv(pname, params);
2915 }
2916 }
2917 catch(std::bad_alloc&)
2918 {
2919 return error(GL_OUT_OF_MEMORY);
2920 }
2921}
2922
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002923void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2924{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002925 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002926
2927 try
2928 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002929 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002930
2931 if (context)
2932 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002933 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002934 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002935 GLenum nativeType;
2936 unsigned int numParams = 0;
2937 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2938 return error(GL_INVALID_ENUM);
2939
2940 if (numParams == 0)
2941 return; // it is known that the pname is valid, but that there are no parameters to return.
2942
2943 if (nativeType == GL_BOOL)
2944 {
2945 GLboolean *boolParams = NULL;
2946 boolParams = new GLboolean[numParams];
2947
2948 context->getBooleanv(pname, boolParams);
2949
2950 for (unsigned int i = 0; i < numParams; ++i)
2951 {
2952 if (boolParams[i] == GL_FALSE)
2953 params[i] = 0.0f;
2954 else
2955 params[i] = 1.0f;
2956 }
2957
2958 delete [] boolParams;
2959 }
2960 else if (nativeType == GL_INT)
2961 {
2962 GLint *intParams = NULL;
2963 intParams = new GLint[numParams];
2964
2965 context->getIntegerv(pname, intParams);
2966
2967 for (unsigned int i = 0; i < numParams; ++i)
2968 {
2969 params[i] = (GLfloat)intParams[i];
2970 }
2971
2972 delete [] intParams;
2973 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002974 }
2975 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002976 }
2977 catch(std::bad_alloc&)
2978 {
2979 return error(GL_OUT_OF_MEMORY);
2980 }
2981}
2982
2983void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2984{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002985 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 +00002986 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002987
2988 try
2989 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002990 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002991
2992 if (context)
2993 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002994 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002995 {
2996 return error(GL_INVALID_ENUM);
2997 }
2998
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002999 gl::Framebuffer *framebuffer = NULL;
3000 if (target == GL_READ_FRAMEBUFFER_ANGLE)
3001 {
3002 if(context->getReadFramebufferHandle() == 0)
3003 {
3004 return error(GL_INVALID_OPERATION);
3005 }
3006
3007 framebuffer = context->getReadFramebuffer();
3008 }
3009 else
3010 {
3011 if (context->getDrawFramebufferHandle() == 0)
3012 {
3013 return error(GL_INVALID_OPERATION);
3014 }
3015
3016 framebuffer = context->getDrawFramebuffer();
3017 }
3018
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003019 GLenum attachmentType;
3020 GLuint attachmentHandle;
3021 switch (attachment)
3022 {
3023 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003024 attachmentType = framebuffer->getColorbufferType();
3025 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003026 break;
3027 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003028 attachmentType = framebuffer->getDepthbufferType();
3029 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003030 break;
3031 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003032 attachmentType = framebuffer->getStencilbufferType();
3033 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003034 break;
3035 default: return error(GL_INVALID_ENUM);
3036 }
3037
3038 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00003039 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003040 {
3041 attachmentObjectType = attachmentType;
3042 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +00003043 else if (gl::IsInternalTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003044 {
3045 attachmentObjectType = GL_TEXTURE;
3046 }
apatrick@chromium.orga1d80592012-01-25 21:52:10 +00003047 else
3048 {
3049 UNREACHABLE();
3050 return;
3051 }
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003052
3053 switch (pname)
3054 {
3055 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3056 *params = attachmentObjectType;
3057 break;
3058 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3059 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
3060 {
3061 *params = attachmentHandle;
3062 }
3063 else
3064 {
3065 return error(GL_INVALID_ENUM);
3066 }
3067 break;
3068 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3069 if (attachmentObjectType == GL_TEXTURE)
3070 {
3071 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
3072 }
3073 else
3074 {
3075 return error(GL_INVALID_ENUM);
3076 }
3077 break;
3078 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3079 if (attachmentObjectType == GL_TEXTURE)
3080 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00003081 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003082 {
3083 *params = attachmentType;
3084 }
3085 else
3086 {
3087 *params = 0;
3088 }
3089 }
3090 else
3091 {
3092 return error(GL_INVALID_ENUM);
3093 }
3094 break;
3095 default:
3096 return error(GL_INVALID_ENUM);
3097 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003098 }
3099 }
3100 catch(std::bad_alloc&)
3101 {
3102 return error(GL_OUT_OF_MEMORY);
3103 }
3104}
3105
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00003106GLenum __stdcall glGetGraphicsResetStatusEXT(void)
3107{
3108 EVENT("()");
3109
3110 try
3111 {
3112 gl::Context *context = gl::getContext();
3113
3114 if (context)
3115 {
3116 return context->getResetStatus();
3117 }
3118
3119 return GL_NO_ERROR;
3120 }
3121 catch(std::bad_alloc&)
3122 {
3123 return GL_OUT_OF_MEMORY;
3124 }
3125}
3126
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003127void __stdcall glGetIntegerv(GLenum pname, GLint* params)
3128{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003129 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003130
3131 try
3132 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003133 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003134
3135 if (context)
3136 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003137 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003138 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003139 GLenum nativeType;
3140 unsigned int numParams = 0;
3141 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3142 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003143
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003144 if (numParams == 0)
3145 return; // it is known that pname is valid, but there are no parameters to return
3146
3147 if (nativeType == GL_BOOL)
3148 {
3149 GLboolean *boolParams = NULL;
3150 boolParams = new GLboolean[numParams];
3151
3152 context->getBooleanv(pname, boolParams);
3153
3154 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003155 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003156 if (boolParams[i] == GL_FALSE)
3157 params[i] = 0;
3158 else
3159 params[i] = 1;
3160 }
3161
3162 delete [] boolParams;
3163 }
3164 else if (nativeType == GL_FLOAT)
3165 {
3166 GLfloat *floatParams = NULL;
3167 floatParams = new GLfloat[numParams];
3168
3169 context->getFloatv(pname, floatParams);
3170
3171 for (unsigned int i = 0; i < numParams; ++i)
3172 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00003173 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 +00003174 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003175 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003176 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003177 else
3178 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 +00003179 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003180
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003181 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003182 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003183 }
3184 }
3185 }
3186 catch(std::bad_alloc&)
3187 {
3188 return error(GL_OUT_OF_MEMORY);
3189 }
3190}
3191
3192void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3193{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003194 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003195
3196 try
3197 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003198 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003199
3200 if (context)
3201 {
3202 gl::Program *programObject = context->getProgram(program);
3203
3204 if (!programObject)
3205 {
3206 return error(GL_INVALID_VALUE);
3207 }
3208
3209 switch (pname)
3210 {
3211 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003212 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003213 return;
3214 case GL_LINK_STATUS:
3215 *params = programObject->isLinked();
3216 return;
3217 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003218 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003219 return;
3220 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003221 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003222 return;
3223 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003224 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003225 return;
3226 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003227 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003228 return;
3229 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003230 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003231 return;
3232 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003233 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003234 return;
3235 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003236 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003237 return;
3238 default:
3239 return error(GL_INVALID_ENUM);
3240 }
3241 }
3242 }
3243 catch(std::bad_alloc&)
3244 {
3245 return error(GL_OUT_OF_MEMORY);
3246 }
3247}
3248
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003249void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003250{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003251 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 +00003252 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003253
3254 try
3255 {
3256 if (bufsize < 0)
3257 {
3258 return error(GL_INVALID_VALUE);
3259 }
3260
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003261 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003262
3263 if (context)
3264 {
3265 gl::Program *programObject = context->getProgram(program);
3266
3267 if (!programObject)
3268 {
3269 return error(GL_INVALID_VALUE);
3270 }
3271
3272 programObject->getInfoLog(bufsize, length, infolog);
3273 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003274 }
3275 catch(std::bad_alloc&)
3276 {
3277 return error(GL_OUT_OF_MEMORY);
3278 }
3279}
3280
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003281void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3282{
3283 EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
3284
3285 try
3286 {
3287 switch (pname)
3288 {
3289 case GL_CURRENT_QUERY_EXT:
3290 break;
3291 default:
3292 return error(GL_INVALID_ENUM);
3293 }
3294
3295 gl::Context *context = gl::getNonLostContext();
3296
3297 if (context)
3298 {
3299 params[0] = context->getActiveQuery(target);
3300 }
3301 }
3302 catch(std::bad_alloc&)
3303 {
3304 return error(GL_OUT_OF_MEMORY);
3305 }
3306}
3307
3308void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
3309{
3310 EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
3311
3312 try
3313 {
3314 switch (pname)
3315 {
3316 case GL_QUERY_RESULT_EXT:
3317 case GL_QUERY_RESULT_AVAILABLE_EXT:
3318 break;
3319 default:
3320 return error(GL_INVALID_ENUM);
3321 }
3322 gl::Context *context = gl::getNonLostContext();
3323
3324 if (context)
3325 {
3326
3327 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
3328
3329 if (!queryObject)
3330 {
3331 return error(GL_INVALID_OPERATION);
3332 }
3333
3334 if (context->getActiveQuery(queryObject->getType()) == id)
3335 {
3336 return error(GL_INVALID_OPERATION);
3337 }
3338
3339 switch(pname)
3340 {
3341 case GL_QUERY_RESULT_EXT:
3342 params[0] = queryObject->getResult();
3343 break;
3344 case GL_QUERY_RESULT_AVAILABLE_EXT:
3345 params[0] = queryObject->isResultAvailable();
3346 break;
3347 default:
3348 ASSERT(false);
3349 }
3350 }
3351 }
3352 catch(std::bad_alloc&)
3353 {
3354 return error(GL_OUT_OF_MEMORY);
3355 }
3356}
3357
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003358void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3359{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003360 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 +00003361
3362 try
3363 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003364 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003365
3366 if (context)
3367 {
3368 if (target != GL_RENDERBUFFER)
3369 {
3370 return error(GL_INVALID_ENUM);
3371 }
3372
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003373 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003374 {
3375 return error(GL_INVALID_OPERATION);
3376 }
3377
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003378 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003379
3380 switch (pname)
3381 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003382 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3383 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3384 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3385 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3386 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3387 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3388 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3389 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3390 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003391 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003392 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003393 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003394 *params = renderbuffer->getSamples();
3395 }
3396 else
3397 {
3398 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003399 }
3400 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003401 default:
3402 return error(GL_INVALID_ENUM);
3403 }
3404 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003405 }
3406 catch(std::bad_alloc&)
3407 {
3408 return error(GL_OUT_OF_MEMORY);
3409 }
3410}
3411
3412void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3413{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003414 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003415
3416 try
3417 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003418 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003419
3420 if (context)
3421 {
3422 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003423
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003424 if (!shaderObject)
3425 {
3426 return error(GL_INVALID_VALUE);
3427 }
3428
3429 switch (pname)
3430 {
3431 case GL_SHADER_TYPE:
3432 *params = shaderObject->getType();
3433 return;
3434 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003435 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003436 return;
3437 case GL_COMPILE_STATUS:
3438 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3439 return;
3440 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003441 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003442 return;
3443 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003444 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003445 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003446 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3447 *params = shaderObject->getTranslatedSourceLength();
3448 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003449 default:
3450 return error(GL_INVALID_ENUM);
3451 }
3452 }
3453 }
3454 catch(std::bad_alloc&)
3455 {
3456 return error(GL_OUT_OF_MEMORY);
3457 }
3458}
3459
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003460void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003461{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003462 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 +00003463 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003464
3465 try
3466 {
3467 if (bufsize < 0)
3468 {
3469 return error(GL_INVALID_VALUE);
3470 }
3471
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003472 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003473
3474 if (context)
3475 {
3476 gl::Shader *shaderObject = context->getShader(shader);
3477
3478 if (!shaderObject)
3479 {
3480 return error(GL_INVALID_VALUE);
3481 }
3482
3483 shaderObject->getInfoLog(bufsize, length, infolog);
3484 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003485 }
3486 catch(std::bad_alloc&)
3487 {
3488 return error(GL_OUT_OF_MEMORY);
3489 }
3490}
3491
3492void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3493{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003494 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 +00003495 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003496
3497 try
3498 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003499 switch (shadertype)
3500 {
3501 case GL_VERTEX_SHADER:
3502 case GL_FRAGMENT_SHADER:
3503 break;
3504 default:
3505 return error(GL_INVALID_ENUM);
3506 }
3507
3508 switch (precisiontype)
3509 {
3510 case GL_LOW_FLOAT:
3511 case GL_MEDIUM_FLOAT:
3512 case GL_HIGH_FLOAT:
3513 // Assume IEEE 754 precision
3514 range[0] = 127;
3515 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003516 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003517 break;
3518 case GL_LOW_INT:
3519 case GL_MEDIUM_INT:
3520 case GL_HIGH_INT:
3521 // Some (most) hardware only supports single-precision floating-point numbers,
3522 // which can accurately represent integers up to +/-16777216
3523 range[0] = 24;
3524 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003525 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003526 break;
3527 default:
3528 return error(GL_INVALID_ENUM);
3529 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003530 }
3531 catch(std::bad_alloc&)
3532 {
3533 return error(GL_OUT_OF_MEMORY);
3534 }
3535}
3536
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003537void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003538{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003539 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 +00003540 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003541
3542 try
3543 {
3544 if (bufsize < 0)
3545 {
3546 return error(GL_INVALID_VALUE);
3547 }
3548
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003549 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003550
3551 if (context)
3552 {
3553 gl::Shader *shaderObject = context->getShader(shader);
3554
3555 if (!shaderObject)
3556 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003557 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003558 }
3559
3560 shaderObject->getSource(bufsize, length, source);
3561 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003562 }
3563 catch(std::bad_alloc&)
3564 {
3565 return error(GL_OUT_OF_MEMORY);
3566 }
3567}
3568
zmo@google.coma574f782011-10-03 21:45:23 +00003569void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3570{
3571 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3572 shader, bufsize, length, source);
3573
3574 try
3575 {
3576 if (bufsize < 0)
3577 {
3578 return error(GL_INVALID_VALUE);
3579 }
3580
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003581 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003582
3583 if (context)
3584 {
3585 gl::Shader *shaderObject = context->getShader(shader);
3586
3587 if (!shaderObject)
3588 {
3589 return error(GL_INVALID_OPERATION);
3590 }
3591
3592 shaderObject->getTranslatedSource(bufsize, length, source);
3593 }
3594 }
3595 catch(std::bad_alloc&)
3596 {
3597 return error(GL_OUT_OF_MEMORY);
3598 }
3599}
3600
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003601const GLubyte* __stdcall glGetString(GLenum name)
3602{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003603 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003604
3605 try
3606 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003607 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003608
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003609 switch (name)
3610 {
3611 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003612 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003613 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003614 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003615 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003616 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003617 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003618 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003619 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003620 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003621 default:
3622 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3623 }
3624 }
3625 catch(std::bad_alloc&)
3626 {
3627 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3628 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003629}
3630
3631void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3632{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003633 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 +00003634
3635 try
3636 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003637 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003638
3639 if (context)
3640 {
3641 gl::Texture *texture;
3642
3643 switch (target)
3644 {
3645 case GL_TEXTURE_2D:
3646 texture = context->getTexture2D();
3647 break;
3648 case GL_TEXTURE_CUBE_MAP:
3649 texture = context->getTextureCubeMap();
3650 break;
3651 default:
3652 return error(GL_INVALID_ENUM);
3653 }
3654
3655 switch (pname)
3656 {
3657 case GL_TEXTURE_MAG_FILTER:
3658 *params = (GLfloat)texture->getMagFilter();
3659 break;
3660 case GL_TEXTURE_MIN_FILTER:
3661 *params = (GLfloat)texture->getMinFilter();
3662 break;
3663 case GL_TEXTURE_WRAP_S:
3664 *params = (GLfloat)texture->getWrapS();
3665 break;
3666 case GL_TEXTURE_WRAP_T:
3667 *params = (GLfloat)texture->getWrapT();
3668 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003669 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3670 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3671 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003672 case GL_TEXTURE_USAGE_ANGLE:
3673 *params = (GLfloat)texture->getUsage();
3674 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003675 default:
3676 return error(GL_INVALID_ENUM);
3677 }
3678 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003679 }
3680 catch(std::bad_alloc&)
3681 {
3682 return error(GL_OUT_OF_MEMORY);
3683 }
3684}
3685
3686void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3687{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003688 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 +00003689
3690 try
3691 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003692 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003693
3694 if (context)
3695 {
3696 gl::Texture *texture;
3697
3698 switch (target)
3699 {
3700 case GL_TEXTURE_2D:
3701 texture = context->getTexture2D();
3702 break;
3703 case GL_TEXTURE_CUBE_MAP:
3704 texture = context->getTextureCubeMap();
3705 break;
3706 default:
3707 return error(GL_INVALID_ENUM);
3708 }
3709
3710 switch (pname)
3711 {
3712 case GL_TEXTURE_MAG_FILTER:
3713 *params = texture->getMagFilter();
3714 break;
3715 case GL_TEXTURE_MIN_FILTER:
3716 *params = texture->getMinFilter();
3717 break;
3718 case GL_TEXTURE_WRAP_S:
3719 *params = texture->getWrapS();
3720 break;
3721 case GL_TEXTURE_WRAP_T:
3722 *params = texture->getWrapT();
3723 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003724 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3725 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3726 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003727 case GL_TEXTURE_USAGE_ANGLE:
3728 *params = texture->getUsage();
3729 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003730 default:
3731 return error(GL_INVALID_ENUM);
3732 }
3733 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003734 }
3735 catch(std::bad_alloc&)
3736 {
3737 return error(GL_OUT_OF_MEMORY);
3738 }
3739}
3740
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003741void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3742{
3743 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3744 program, location, bufSize, params);
3745
3746 try
3747 {
3748 if (bufSize < 0)
3749 {
3750 return error(GL_INVALID_VALUE);
3751 }
3752
3753 gl::Context *context = gl::getNonLostContext();
3754
3755 if (context)
3756 {
3757 if (program == 0)
3758 {
3759 return error(GL_INVALID_VALUE);
3760 }
3761
3762 gl::Program *programObject = context->getProgram(program);
3763
3764 if (!programObject || !programObject->isLinked())
3765 {
3766 return error(GL_INVALID_OPERATION);
3767 }
3768
3769 if (!programObject->getUniformfv(location, &bufSize, params))
3770 {
3771 return error(GL_INVALID_OPERATION);
3772 }
3773 }
3774 }
3775 catch(std::bad_alloc&)
3776 {
3777 return error(GL_OUT_OF_MEMORY);
3778 }
3779}
3780
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003781void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3782{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003783 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003784
3785 try
3786 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003787 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003788
3789 if (context)
3790 {
3791 if (program == 0)
3792 {
3793 return error(GL_INVALID_VALUE);
3794 }
3795
3796 gl::Program *programObject = context->getProgram(program);
3797
3798 if (!programObject || !programObject->isLinked())
3799 {
3800 return error(GL_INVALID_OPERATION);
3801 }
3802
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003803 if (!programObject->getUniformfv(location, NULL, params))
3804 {
3805 return error(GL_INVALID_OPERATION);
3806 }
3807 }
3808 }
3809 catch(std::bad_alloc&)
3810 {
3811 return error(GL_OUT_OF_MEMORY);
3812 }
3813}
3814
3815void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3816{
3817 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3818 program, location, bufSize, params);
3819
3820 try
3821 {
3822 if (bufSize < 0)
3823 {
3824 return error(GL_INVALID_VALUE);
3825 }
3826
3827 gl::Context *context = gl::getNonLostContext();
3828
3829 if (context)
3830 {
3831 if (program == 0)
3832 {
3833 return error(GL_INVALID_VALUE);
3834 }
3835
3836 gl::Program *programObject = context->getProgram(program);
3837
3838 if (!programObject || !programObject->isLinked())
3839 {
3840 return error(GL_INVALID_OPERATION);
3841 }
3842
3843 if (!programObject)
3844 {
3845 return error(GL_INVALID_OPERATION);
3846 }
3847
3848 if (!programObject->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003849 {
3850 return error(GL_INVALID_OPERATION);
3851 }
3852 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003853 }
3854 catch(std::bad_alloc&)
3855 {
3856 return error(GL_OUT_OF_MEMORY);
3857 }
3858}
3859
3860void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3861{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003862 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003863
3864 try
3865 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003866 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003867
3868 if (context)
3869 {
3870 if (program == 0)
3871 {
3872 return error(GL_INVALID_VALUE);
3873 }
3874
3875 gl::Program *programObject = context->getProgram(program);
3876
3877 if (!programObject || !programObject->isLinked())
3878 {
3879 return error(GL_INVALID_OPERATION);
3880 }
3881
3882 if (!programObject)
3883 {
3884 return error(GL_INVALID_OPERATION);
3885 }
3886
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003887 if (!programObject->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003888 {
3889 return error(GL_INVALID_OPERATION);
3890 }
3891 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003892 }
3893 catch(std::bad_alloc&)
3894 {
3895 return error(GL_OUT_OF_MEMORY);
3896 }
3897}
3898
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003899int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003900{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003901 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003902
3903 try
3904 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003905 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003906
3907 if (strstr(name, "gl_") == name)
3908 {
3909 return -1;
3910 }
3911
3912 if (context)
3913 {
3914 gl::Program *programObject = context->getProgram(program);
3915
3916 if (!programObject)
3917 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003918 if (context->getShader(program))
3919 {
3920 return error(GL_INVALID_OPERATION, -1);
3921 }
3922 else
3923 {
3924 return error(GL_INVALID_VALUE, -1);
3925 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003926 }
3927
3928 if (!programObject->isLinked())
3929 {
3930 return error(GL_INVALID_OPERATION, -1);
3931 }
3932
daniel@transgaming.com024f1a92011-09-20 16:06:25 +00003933 return programObject->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003934 }
3935 }
3936 catch(std::bad_alloc&)
3937 {
3938 return error(GL_OUT_OF_MEMORY, -1);
3939 }
3940
3941 return -1;
3942}
3943
3944void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3945{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003946 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003947
3948 try
3949 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003950 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003951
daniel@transgaming.come0078962010-04-15 20:45:08 +00003952 if (context)
3953 {
3954 if (index >= gl::MAX_VERTEX_ATTRIBS)
3955 {
3956 return error(GL_INVALID_VALUE);
3957 }
3958
daniel@transgaming.com83921382011-01-08 05:46:00 +00003959 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003960
daniel@transgaming.come0078962010-04-15 20:45:08 +00003961 switch (pname)
3962 {
3963 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003964 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003965 break;
3966 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003967 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003968 break;
3969 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003970 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003971 break;
3972 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003973 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003974 break;
3975 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003976 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003977 break;
3978 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003979 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003980 break;
3981 case GL_CURRENT_VERTEX_ATTRIB:
3982 for (int i = 0; i < 4; ++i)
3983 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003984 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003985 }
3986 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00003987 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
3988 *params = (GLfloat)attribState.mDivisor;
3989 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003990 default: return error(GL_INVALID_ENUM);
3991 }
3992 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003993 }
3994 catch(std::bad_alloc&)
3995 {
3996 return error(GL_OUT_OF_MEMORY);
3997 }
3998}
3999
4000void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
4001{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004002 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004003
4004 try
4005 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004006 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004007
daniel@transgaming.come0078962010-04-15 20:45:08 +00004008 if (context)
4009 {
4010 if (index >= gl::MAX_VERTEX_ATTRIBS)
4011 {
4012 return error(GL_INVALID_VALUE);
4013 }
4014
daniel@transgaming.com83921382011-01-08 05:46:00 +00004015 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004016
daniel@transgaming.come0078962010-04-15 20:45:08 +00004017 switch (pname)
4018 {
4019 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004020 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004021 break;
4022 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004023 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004024 break;
4025 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004026 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004027 break;
4028 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004029 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004030 break;
4031 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004032 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004033 break;
4034 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004035 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004036 break;
4037 case GL_CURRENT_VERTEX_ATTRIB:
4038 for (int i = 0; i < 4; ++i)
4039 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004040 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004041 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4042 }
4043 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004044 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4045 *params = (GLint)attribState.mDivisor;
4046 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004047 default: return error(GL_INVALID_ENUM);
4048 }
4049 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004050 }
4051 catch(std::bad_alloc&)
4052 {
4053 return error(GL_OUT_OF_MEMORY);
4054 }
4055}
4056
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004057void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004058{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004059 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004060
4061 try
4062 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004063 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004064
daniel@transgaming.come0078962010-04-15 20:45:08 +00004065 if (context)
4066 {
4067 if (index >= gl::MAX_VERTEX_ATTRIBS)
4068 {
4069 return error(GL_INVALID_VALUE);
4070 }
4071
4072 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4073 {
4074 return error(GL_INVALID_ENUM);
4075 }
4076
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004077 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00004078 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004079 }
4080 catch(std::bad_alloc&)
4081 {
4082 return error(GL_OUT_OF_MEMORY);
4083 }
4084}
4085
4086void __stdcall glHint(GLenum target, GLenum mode)
4087{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004088 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004089
4090 try
4091 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004092 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004093 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004094 case GL_FASTEST:
4095 case GL_NICEST:
4096 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004097 break;
4098 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004099 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004100 }
4101
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004102 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004103 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004104 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004105 case GL_GENERATE_MIPMAP_HINT:
4106 if (context) context->setGenerateMipmapHint(mode);
4107 break;
4108 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4109 if (context) context->setFragmentShaderDerivativeHint(mode);
4110 break;
4111 default:
4112 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004113 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004114 }
4115 catch(std::bad_alloc&)
4116 {
4117 return error(GL_OUT_OF_MEMORY);
4118 }
4119}
4120
4121GLboolean __stdcall glIsBuffer(GLuint buffer)
4122{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004123 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004124
4125 try
4126 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004127 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004128
4129 if (context && buffer)
4130 {
4131 gl::Buffer *bufferObject = context->getBuffer(buffer);
4132
4133 if (bufferObject)
4134 {
4135 return GL_TRUE;
4136 }
4137 }
4138 }
4139 catch(std::bad_alloc&)
4140 {
4141 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4142 }
4143
4144 return GL_FALSE;
4145}
4146
4147GLboolean __stdcall glIsEnabled(GLenum cap)
4148{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004149 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004150
4151 try
4152 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004153 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004154
4155 if (context)
4156 {
4157 switch (cap)
4158 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004159 case GL_CULL_FACE: return context->isCullFaceEnabled();
4160 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4161 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4162 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4163 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4164 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4165 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4166 case GL_BLEND: return context->isBlendEnabled();
4167 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004168 default:
4169 return error(GL_INVALID_ENUM, false);
4170 }
4171 }
4172 }
4173 catch(std::bad_alloc&)
4174 {
4175 return error(GL_OUT_OF_MEMORY, false);
4176 }
4177
4178 return false;
4179}
4180
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004181GLboolean __stdcall glIsFenceNV(GLuint fence)
4182{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004183 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004184
4185 try
4186 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004187 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004188
4189 if (context)
4190 {
4191 gl::Fence *fenceObject = context->getFence(fence);
4192
4193 if (fenceObject == NULL)
4194 {
4195 return GL_FALSE;
4196 }
4197
4198 return fenceObject->isFence();
4199 }
4200 }
4201 catch(std::bad_alloc&)
4202 {
4203 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4204 }
4205
4206 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004207}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004208
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004209GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
4210{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004211 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004212
4213 try
4214 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004215 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004216
4217 if (context && framebuffer)
4218 {
4219 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4220
4221 if (framebufferObject)
4222 {
4223 return GL_TRUE;
4224 }
4225 }
4226 }
4227 catch(std::bad_alloc&)
4228 {
4229 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4230 }
4231
4232 return GL_FALSE;
4233}
4234
4235GLboolean __stdcall glIsProgram(GLuint program)
4236{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004237 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004238
4239 try
4240 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004241 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004242
4243 if (context && program)
4244 {
4245 gl::Program *programObject = context->getProgram(program);
4246
4247 if (programObject)
4248 {
4249 return GL_TRUE;
4250 }
4251 }
4252 }
4253 catch(std::bad_alloc&)
4254 {
4255 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4256 }
4257
4258 return GL_FALSE;
4259}
4260
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00004261GLboolean __stdcall glIsQueryEXT(GLuint id)
4262{
4263 EVENT("(GLuint id = %d)", id);
4264
4265 try
4266 {
4267 if (id == 0)
4268 {
4269 return GL_FALSE;
4270 }
4271
4272 gl::Context *context = gl::getNonLostContext();
4273
4274 if (context)
4275 {
4276 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
4277
4278 if (queryObject)
4279 {
4280 return GL_TRUE;
4281 }
4282 }
4283 }
4284 catch(std::bad_alloc&)
4285 {
4286 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4287 }
4288
4289 return GL_FALSE;
4290}
4291
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004292GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
4293{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004294 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004295
4296 try
4297 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004298 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004299
4300 if (context && renderbuffer)
4301 {
4302 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4303
4304 if (renderbufferObject)
4305 {
4306 return GL_TRUE;
4307 }
4308 }
4309 }
4310 catch(std::bad_alloc&)
4311 {
4312 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4313 }
4314
4315 return GL_FALSE;
4316}
4317
4318GLboolean __stdcall glIsShader(GLuint shader)
4319{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004320 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004321
4322 try
4323 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004324 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004325
4326 if (context && shader)
4327 {
4328 gl::Shader *shaderObject = context->getShader(shader);
4329
4330 if (shaderObject)
4331 {
4332 return GL_TRUE;
4333 }
4334 }
4335 }
4336 catch(std::bad_alloc&)
4337 {
4338 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4339 }
4340
4341 return GL_FALSE;
4342}
4343
4344GLboolean __stdcall glIsTexture(GLuint texture)
4345{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004346 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004347
4348 try
4349 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004350 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004351
4352 if (context && texture)
4353 {
4354 gl::Texture *textureObject = context->getTexture(texture);
4355
4356 if (textureObject)
4357 {
4358 return GL_TRUE;
4359 }
4360 }
4361 }
4362 catch(std::bad_alloc&)
4363 {
4364 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4365 }
4366
4367 return GL_FALSE;
4368}
4369
4370void __stdcall glLineWidth(GLfloat width)
4371{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004372 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004373
4374 try
4375 {
4376 if (width <= 0.0f)
4377 {
4378 return error(GL_INVALID_VALUE);
4379 }
4380
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004381 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004382
4383 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004384 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004385 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004386 }
4387 }
4388 catch(std::bad_alloc&)
4389 {
4390 return error(GL_OUT_OF_MEMORY);
4391 }
4392}
4393
4394void __stdcall glLinkProgram(GLuint program)
4395{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004396 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004397
4398 try
4399 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004400 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004401
4402 if (context)
4403 {
4404 gl::Program *programObject = context->getProgram(program);
4405
4406 if (!programObject)
4407 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004408 if (context->getShader(program))
4409 {
4410 return error(GL_INVALID_OPERATION);
4411 }
4412 else
4413 {
4414 return error(GL_INVALID_VALUE);
4415 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004416 }
4417
4418 programObject->link();
4419 }
4420 }
4421 catch(std::bad_alloc&)
4422 {
4423 return error(GL_OUT_OF_MEMORY);
4424 }
4425}
4426
4427void __stdcall glPixelStorei(GLenum pname, GLint param)
4428{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004429 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004430
4431 try
4432 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004433 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004434
4435 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004436 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004437 switch (pname)
4438 {
4439 case GL_UNPACK_ALIGNMENT:
4440 if (param != 1 && param != 2 && param != 4 && param != 8)
4441 {
4442 return error(GL_INVALID_VALUE);
4443 }
4444
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004445 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004446 break;
4447
4448 case GL_PACK_ALIGNMENT:
4449 if (param != 1 && param != 2 && param != 4 && param != 8)
4450 {
4451 return error(GL_INVALID_VALUE);
4452 }
4453
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004454 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004455 break;
4456
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004457 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4458 context->setPackReverseRowOrder(param != 0);
4459 break;
4460
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004461 default:
4462 return error(GL_INVALID_ENUM);
4463 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004464 }
4465 }
4466 catch(std::bad_alloc&)
4467 {
4468 return error(GL_OUT_OF_MEMORY);
4469 }
4470}
4471
4472void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4473{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004474 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004475
4476 try
4477 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004478 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004479
4480 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004481 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004482 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004483 }
4484 }
4485 catch(std::bad_alloc&)
4486 {
4487 return error(GL_OUT_OF_MEMORY);
4488 }
4489}
4490
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004491void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4492 GLenum format, GLenum type, GLsizei bufSize,
4493 GLvoid *data)
4494{
4495 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4496 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4497 x, y, width, height, format, type, bufSize, data);
4498
4499 try
4500 {
4501 if (width < 0 || height < 0 || bufSize < 0)
4502 {
4503 return error(GL_INVALID_VALUE);
4504 }
4505
4506 if (!validReadFormatType(format, type))
4507 {
4508 return error(GL_INVALID_OPERATION);
4509 }
4510
4511 gl::Context *context = gl::getNonLostContext();
4512
4513 if (context)
4514 {
4515 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4516 }
4517 }
4518 catch(std::bad_alloc&)
4519 {
4520 return error(GL_OUT_OF_MEMORY);
4521 }
4522}
4523
4524void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4525 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004526{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004527 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004528 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004529 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004530
4531 try
4532 {
4533 if (width < 0 || height < 0)
4534 {
4535 return error(GL_INVALID_VALUE);
4536 }
4537
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004538 if (!validReadFormatType(format, type))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004539 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004540 return error(GL_INVALID_OPERATION);
4541 }
4542
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004543 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004544
4545 if (context)
4546 {
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004547 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004548 }
4549 }
4550 catch(std::bad_alloc&)
4551 {
4552 return error(GL_OUT_OF_MEMORY);
4553 }
4554}
4555
4556void __stdcall glReleaseShaderCompiler(void)
4557{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004558 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004559
4560 try
4561 {
4562 gl::Shader::releaseCompiler();
4563 }
4564 catch(std::bad_alloc&)
4565 {
4566 return error(GL_OUT_OF_MEMORY);
4567 }
4568}
4569
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004570void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004571{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004572 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 +00004573 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004574
4575 try
4576 {
4577 switch (target)
4578 {
4579 case GL_RENDERBUFFER:
4580 break;
4581 default:
4582 return error(GL_INVALID_ENUM);
4583 }
4584
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004585 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004586 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004587 return error(GL_INVALID_ENUM);
4588 }
4589
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004590 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004591 {
4592 return error(GL_INVALID_VALUE);
4593 }
4594
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004595 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004596
4597 if (context)
4598 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004599 if (width > context->getMaximumRenderbufferDimension() ||
4600 height > context->getMaximumRenderbufferDimension() ||
4601 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004602 {
4603 return error(GL_INVALID_VALUE);
4604 }
4605
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004606 GLuint handle = context->getRenderbufferHandle();
4607 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004608 {
4609 return error(GL_INVALID_OPERATION);
4610 }
4611
4612 switch (internalformat)
4613 {
4614 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004615 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004616 break;
4617 case GL_RGBA4:
4618 case GL_RGB5_A1:
4619 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004620 case GL_RGB8_OES:
4621 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004622 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004623 break;
4624 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004625 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004626 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004627 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004628 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004629 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004630 default:
4631 return error(GL_INVALID_ENUM);
4632 }
4633 }
4634 }
4635 catch(std::bad_alloc&)
4636 {
4637 return error(GL_OUT_OF_MEMORY);
4638 }
4639}
4640
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004641void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4642{
4643 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4644}
4645
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004646void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4647{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004648 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004649
4650 try
4651 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004652 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004653
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004654 if (context)
4655 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004656 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004657 }
4658 }
4659 catch(std::bad_alloc&)
4660 {
4661 return error(GL_OUT_OF_MEMORY);
4662 }
4663}
4664
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004665void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4666{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004667 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004668
4669 try
4670 {
4671 if (condition != GL_ALL_COMPLETED_NV)
4672 {
4673 return error(GL_INVALID_ENUM);
4674 }
4675
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004676 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004677
4678 if (context)
4679 {
4680 gl::Fence *fenceObject = context->getFence(fence);
4681
4682 if (fenceObject == NULL)
4683 {
4684 return error(GL_INVALID_OPERATION);
4685 }
4686
4687 fenceObject->setFence(condition);
4688 }
4689 }
4690 catch(std::bad_alloc&)
4691 {
4692 return error(GL_OUT_OF_MEMORY);
4693 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004694}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004695
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004696void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4697{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004698 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 +00004699
4700 try
4701 {
4702 if (width < 0 || height < 0)
4703 {
4704 return error(GL_INVALID_VALUE);
4705 }
4706
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004707 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004708
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004709 if (context)
4710 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004711 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004712 }
4713 }
4714 catch(std::bad_alloc&)
4715 {
4716 return error(GL_OUT_OF_MEMORY);
4717 }
4718}
4719
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004720void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004721{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004722 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004723 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004724 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004725
4726 try
4727 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004728 // No binary shader formats are supported.
4729 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004730 }
4731 catch(std::bad_alloc&)
4732 {
4733 return error(GL_OUT_OF_MEMORY);
4734 }
4735}
4736
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004737void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004738{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004739 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 +00004740 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004741
4742 try
4743 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004744 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004745 {
4746 return error(GL_INVALID_VALUE);
4747 }
4748
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004749 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004750
4751 if (context)
4752 {
4753 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004754
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004755 if (!shaderObject)
4756 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004757 if (context->getProgram(shader))
4758 {
4759 return error(GL_INVALID_OPERATION);
4760 }
4761 else
4762 {
4763 return error(GL_INVALID_VALUE);
4764 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004765 }
4766
4767 shaderObject->setSource(count, string, length);
4768 }
4769 }
4770 catch(std::bad_alloc&)
4771 {
4772 return error(GL_OUT_OF_MEMORY);
4773 }
4774}
4775
4776void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4777{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004778 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004779}
4780
4781void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4782{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004783 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 +00004784
4785 try
4786 {
4787 switch (face)
4788 {
4789 case GL_FRONT:
4790 case GL_BACK:
4791 case GL_FRONT_AND_BACK:
4792 break;
4793 default:
4794 return error(GL_INVALID_ENUM);
4795 }
4796
4797 switch (func)
4798 {
4799 case GL_NEVER:
4800 case GL_ALWAYS:
4801 case GL_LESS:
4802 case GL_LEQUAL:
4803 case GL_EQUAL:
4804 case GL_GEQUAL:
4805 case GL_GREATER:
4806 case GL_NOTEQUAL:
4807 break;
4808 default:
4809 return error(GL_INVALID_ENUM);
4810 }
4811
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004812 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004813
4814 if (context)
4815 {
4816 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4817 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004818 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004819 }
4820
4821 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4822 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004823 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004824 }
4825 }
4826 }
4827 catch(std::bad_alloc&)
4828 {
4829 return error(GL_OUT_OF_MEMORY);
4830 }
4831}
4832
4833void __stdcall glStencilMask(GLuint mask)
4834{
4835 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4836}
4837
4838void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4839{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004840 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004841
4842 try
4843 {
4844 switch (face)
4845 {
4846 case GL_FRONT:
4847 case GL_BACK:
4848 case GL_FRONT_AND_BACK:
4849 break;
4850 default:
4851 return error(GL_INVALID_ENUM);
4852 }
4853
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004854 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004855
4856 if (context)
4857 {
4858 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4859 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004860 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004861 }
4862
4863 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4864 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004865 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004866 }
4867 }
4868 }
4869 catch(std::bad_alloc&)
4870 {
4871 return error(GL_OUT_OF_MEMORY);
4872 }
4873}
4874
4875void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4876{
4877 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4878}
4879
4880void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4881{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004882 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 +00004883 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004884
4885 try
4886 {
4887 switch (face)
4888 {
4889 case GL_FRONT:
4890 case GL_BACK:
4891 case GL_FRONT_AND_BACK:
4892 break;
4893 default:
4894 return error(GL_INVALID_ENUM);
4895 }
4896
4897 switch (fail)
4898 {
4899 case GL_ZERO:
4900 case GL_KEEP:
4901 case GL_REPLACE:
4902 case GL_INCR:
4903 case GL_DECR:
4904 case GL_INVERT:
4905 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004906 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004907 break;
4908 default:
4909 return error(GL_INVALID_ENUM);
4910 }
4911
4912 switch (zfail)
4913 {
4914 case GL_ZERO:
4915 case GL_KEEP:
4916 case GL_REPLACE:
4917 case GL_INCR:
4918 case GL_DECR:
4919 case GL_INVERT:
4920 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004921 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004922 break;
4923 default:
4924 return error(GL_INVALID_ENUM);
4925 }
4926
4927 switch (zpass)
4928 {
4929 case GL_ZERO:
4930 case GL_KEEP:
4931 case GL_REPLACE:
4932 case GL_INCR:
4933 case GL_DECR:
4934 case GL_INVERT:
4935 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004936 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004937 break;
4938 default:
4939 return error(GL_INVALID_ENUM);
4940 }
4941
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004942 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004943
4944 if (context)
4945 {
4946 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4947 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004948 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004949 }
4950
4951 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4952 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004953 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004954 }
4955 }
4956 }
4957 catch(std::bad_alloc&)
4958 {
4959 return error(GL_OUT_OF_MEMORY);
4960 }
4961}
4962
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004963GLboolean __stdcall glTestFenceNV(GLuint fence)
4964{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004965 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004966
4967 try
4968 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004969 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004970
4971 if (context)
4972 {
4973 gl::Fence *fenceObject = context->getFence(fence);
4974
4975 if (fenceObject == NULL)
4976 {
4977 return error(GL_INVALID_OPERATION, GL_TRUE);
4978 }
4979
4980 return fenceObject->testFence();
4981 }
4982 }
4983 catch(std::bad_alloc&)
4984 {
4985 error(GL_OUT_OF_MEMORY);
4986 }
4987
4988 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004989}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004990
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004991void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4992 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004993{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004994 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 +00004995 "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 +00004996 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004997
4998 try
4999 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00005000 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005001 {
5002 return error(GL_INVALID_VALUE);
5003 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005004
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +00005005 if (internalformat != GLint(format))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005006 {
5007 return error(GL_INVALID_OPERATION);
5008 }
5009
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005010 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005011 {
5012 case GL_ALPHA:
5013 case GL_LUMINANCE:
5014 case GL_LUMINANCE_ALPHA:
5015 switch (type)
5016 {
5017 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005018 case GL_FLOAT:
5019 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005020 break;
5021 default:
5022 return error(GL_INVALID_ENUM);
5023 }
5024 break;
5025 case GL_RGB:
5026 switch (type)
5027 {
5028 case GL_UNSIGNED_BYTE:
5029 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005030 case GL_FLOAT:
5031 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005032 break;
5033 default:
5034 return error(GL_INVALID_ENUM);
5035 }
5036 break;
5037 case GL_RGBA:
5038 switch (type)
5039 {
5040 case GL_UNSIGNED_BYTE:
5041 case GL_UNSIGNED_SHORT_4_4_4_4:
5042 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005043 case GL_FLOAT:
5044 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005045 break;
5046 default:
5047 return error(GL_INVALID_ENUM);
5048 }
5049 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005050 case GL_BGRA_EXT:
5051 switch (type)
5052 {
5053 case GL_UNSIGNED_BYTE:
5054 break;
5055 default:
5056 return error(GL_INVALID_ENUM);
5057 }
5058 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005059 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
5060 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00005061 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5062 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00005063 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005064 default:
5065 return error(GL_INVALID_VALUE);
5066 }
5067
5068 if (border != 0)
5069 {
5070 return error(GL_INVALID_VALUE);
5071 }
5072
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005073 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005074
5075 if (context)
5076 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00005077 if (level > context->getMaximumTextureLevel())
5078 {
5079 return error(GL_INVALID_VALUE);
5080 }
5081
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005082 switch (target)
5083 {
5084 case GL_TEXTURE_2D:
5085 if (width > (context->getMaximumTextureDimension() >> level) ||
5086 height > (context->getMaximumTextureDimension() >> level))
5087 {
5088 return error(GL_INVALID_VALUE);
5089 }
5090 break;
5091 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5092 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5093 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5094 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5095 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5096 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5097 if (width != height)
5098 {
5099 return error(GL_INVALID_VALUE);
5100 }
5101
5102 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
5103 height > (context->getMaximumCubeTextureDimension() >> level))
5104 {
5105 return error(GL_INVALID_VALUE);
5106 }
5107 break;
5108 default:
5109 return error(GL_INVALID_ENUM);
5110 }
5111
gman@chromium.org50c526d2011-08-10 05:19:44 +00005112 switch (format) {
5113 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5114 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5115 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00005116 {
5117 return error(GL_INVALID_OPERATION);
5118 }
5119 else
5120 {
5121 return error(GL_INVALID_ENUM);
5122 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00005123 break;
5124 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5125 if (context->supportsDXT3Textures())
5126 {
5127 return error(GL_INVALID_OPERATION);
5128 }
5129 else
5130 {
5131 return error(GL_INVALID_ENUM);
5132 }
5133 break;
5134 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5135 if (context->supportsDXT5Textures())
5136 {
5137 return error(GL_INVALID_OPERATION);
5138 }
5139 else
5140 {
5141 return error(GL_INVALID_ENUM);
5142 }
5143 break;
5144 default:
5145 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005146 }
5147
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005148 if (type == GL_FLOAT)
5149 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005150 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005151 {
5152 return error(GL_INVALID_ENUM);
5153 }
5154 }
5155 else if (type == GL_HALF_FLOAT_OES)
5156 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005157 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005158 {
5159 return error(GL_INVALID_ENUM);
5160 }
5161 }
5162
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005163 if (target == GL_TEXTURE_2D)
5164 {
5165 gl::Texture2D *texture = context->getTexture2D();
5166
5167 if (!texture)
5168 {
5169 return error(GL_INVALID_OPERATION);
5170 }
5171
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005172 if (texture->isImmutable())
5173 {
5174 return error(GL_INVALID_OPERATION);
5175 }
5176
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005177 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005178 }
5179 else
5180 {
5181 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5182
5183 if (!texture)
5184 {
5185 return error(GL_INVALID_OPERATION);
5186 }
5187
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005188 if (texture->isImmutable())
5189 {
5190 return error(GL_INVALID_OPERATION);
5191 }
5192
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005193 switch (target)
5194 {
5195 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005196 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005197 break;
5198 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005199 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005200 break;
5201 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005202 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005203 break;
5204 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005205 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005206 break;
5207 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005208 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005209 break;
5210 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005211 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005212 break;
5213 default: UNREACHABLE();
5214 }
5215 }
5216 }
5217 }
5218 catch(std::bad_alloc&)
5219 {
5220 return error(GL_OUT_OF_MEMORY);
5221 }
5222}
5223
5224void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5225{
5226 glTexParameteri(target, pname, (GLint)param);
5227}
5228
5229void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5230{
5231 glTexParameteri(target, pname, (GLint)*params);
5232}
5233
5234void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
5235{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005236 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005237
5238 try
5239 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005240 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005241
5242 if (context)
5243 {
5244 gl::Texture *texture;
5245
5246 switch (target)
5247 {
5248 case GL_TEXTURE_2D:
5249 texture = context->getTexture2D();
5250 break;
5251 case GL_TEXTURE_CUBE_MAP:
5252 texture = context->getTextureCubeMap();
5253 break;
5254 default:
5255 return error(GL_INVALID_ENUM);
5256 }
5257
5258 switch (pname)
5259 {
5260 case GL_TEXTURE_WRAP_S:
5261 if (!texture->setWrapS((GLenum)param))
5262 {
5263 return error(GL_INVALID_ENUM);
5264 }
5265 break;
5266 case GL_TEXTURE_WRAP_T:
5267 if (!texture->setWrapT((GLenum)param))
5268 {
5269 return error(GL_INVALID_ENUM);
5270 }
5271 break;
5272 case GL_TEXTURE_MIN_FILTER:
5273 if (!texture->setMinFilter((GLenum)param))
5274 {
5275 return error(GL_INVALID_ENUM);
5276 }
5277 break;
5278 case GL_TEXTURE_MAG_FILTER:
5279 if (!texture->setMagFilter((GLenum)param))
5280 {
5281 return error(GL_INVALID_ENUM);
5282 }
5283 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00005284 case GL_TEXTURE_USAGE_ANGLE:
5285 if (!texture->setUsage((GLenum)param))
5286 {
5287 return error(GL_INVALID_ENUM);
5288 }
5289 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005290 default:
5291 return error(GL_INVALID_ENUM);
5292 }
5293 }
5294 }
5295 catch(std::bad_alloc&)
5296 {
5297 return error(GL_OUT_OF_MEMORY);
5298 }
5299}
5300
5301void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5302{
5303 glTexParameteri(target, pname, *params);
5304}
5305
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005306void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5307{
5308 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5309 target, levels, internalformat, width, height);
5310
5311 try
5312 {
5313 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5314 {
5315 return error(GL_INVALID_ENUM);
5316 }
5317
5318 if (width < 1 || height < 1 || levels < 1)
5319 {
5320 return error(GL_INVALID_VALUE);
5321 }
5322
5323 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5324 {
5325 return error(GL_INVALID_VALUE);
5326 }
5327
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005328 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005329 {
5330 return error(GL_INVALID_OPERATION);
5331 }
5332
5333 GLenum format = gl::ExtractFormat(internalformat);
5334 GLenum type = gl::ExtractType(internalformat);
5335
5336 if (format == GL_NONE || type == GL_NONE)
5337 {
5338 return error(GL_INVALID_ENUM);
5339 }
5340
5341 gl::Context *context = gl::getNonLostContext();
5342
5343 if (context)
5344 {
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005345 switch (target)
5346 {
5347 case GL_TEXTURE_2D:
5348 if (width > context->getMaximumTextureDimension() ||
5349 height > context->getMaximumTextureDimension())
5350 {
5351 return error(GL_INVALID_VALUE);
5352 }
5353 break;
5354 case GL_TEXTURE_CUBE_MAP:
5355 if (width > context->getMaximumCubeTextureDimension() ||
5356 height > context->getMaximumCubeTextureDimension())
5357 {
5358 return error(GL_INVALID_VALUE);
5359 }
5360 break;
5361 default:
5362 return error(GL_INVALID_ENUM);
5363 }
5364
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005365 if (levels != 1 && !context->supportsNonPower2Texture())
5366 {
5367 if (!gl::isPow2(width) || !gl::isPow2(height))
5368 {
5369 return error(GL_INVALID_OPERATION);
5370 }
5371 }
5372
daniel@transgaming.come1077362011-11-11 04:16:50 +00005373 switch (internalformat)
5374 {
5375 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5376 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5377 if (!context->supportsDXT1Textures())
5378 {
5379 return error(GL_INVALID_ENUM);
5380 }
5381 break;
5382 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5383 if (!context->supportsDXT3Textures())
5384 {
5385 return error(GL_INVALID_ENUM);
5386 }
5387 break;
5388 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5389 if (!context->supportsDXT5Textures())
5390 {
5391 return error(GL_INVALID_ENUM);
5392 }
5393 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005394 case GL_RGBA32F_EXT:
5395 case GL_RGB32F_EXT:
5396 case GL_ALPHA32F_EXT:
5397 case GL_LUMINANCE32F_EXT:
5398 case GL_LUMINANCE_ALPHA32F_EXT:
5399 if (!context->supportsFloat32Textures())
5400 {
5401 return error(GL_INVALID_ENUM);
5402 }
5403 break;
5404 case GL_RGBA16F_EXT:
5405 case GL_RGB16F_EXT:
5406 case GL_ALPHA16F_EXT:
5407 case GL_LUMINANCE16F_EXT:
5408 case GL_LUMINANCE_ALPHA16F_EXT:
5409 if (!context->supportsFloat16Textures())
5410 {
5411 return error(GL_INVALID_ENUM);
5412 }
5413 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005414 }
5415
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005416 if (target == GL_TEXTURE_2D)
5417 {
5418 gl::Texture2D *texture = context->getTexture2D();
5419
5420 if (!texture || texture->id() == 0)
5421 {
5422 return error(GL_INVALID_OPERATION);
5423 }
5424
5425 if (texture->isImmutable())
5426 {
5427 return error(GL_INVALID_OPERATION);
5428 }
5429
5430 texture->storage(levels, internalformat, width, height);
5431 }
5432 else if (target == GL_TEXTURE_CUBE_MAP)
5433 {
5434 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5435
5436 if (!texture || texture->id() == 0)
5437 {
5438 return error(GL_INVALID_OPERATION);
5439 }
5440
5441 if (texture->isImmutable())
5442 {
5443 return error(GL_INVALID_OPERATION);
5444 }
5445
5446 texture->storage(levels, internalformat, width);
5447 }
5448 else UNREACHABLE();
5449 }
5450 }
5451 catch(std::bad_alloc&)
5452 {
5453 return error(GL_OUT_OF_MEMORY);
5454 }
5455}
5456
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005457void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5458 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005459{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005460 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005461 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005462 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005463 target, level, xoffset, yoffset, width, height, format, type, pixels);
5464
5465 try
5466 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00005467 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005468 {
5469 return error(GL_INVALID_ENUM);
5470 }
5471
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005472 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005473 {
5474 return error(GL_INVALID_VALUE);
5475 }
5476
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005477 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5478 {
5479 return error(GL_INVALID_VALUE);
5480 }
5481
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005482 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005483 {
5484 return error(GL_INVALID_ENUM);
5485 }
5486
5487 if (width == 0 || height == 0 || pixels == NULL)
5488 {
5489 return;
5490 }
5491
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005492 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005493
5494 if (context)
5495 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005496 if (level > context->getMaximumTextureLevel())
5497 {
5498 return error(GL_INVALID_VALUE);
5499 }
5500
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005501 if (format == GL_FLOAT)
5502 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005503 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005504 {
5505 return error(GL_INVALID_ENUM);
5506 }
5507 }
5508 else if (format == GL_HALF_FLOAT_OES)
5509 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005510 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005511 {
5512 return error(GL_INVALID_ENUM);
5513 }
5514 }
5515
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005516 if (target == GL_TEXTURE_2D)
5517 {
5518 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005519 if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005520 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005521 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005522 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005523 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005524 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005525 {
5526 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005527 if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005528 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005529 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005530 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005531 }
5532 else
5533 {
5534 UNREACHABLE();
5535 }
5536 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005537 }
5538 catch(std::bad_alloc&)
5539 {
5540 return error(GL_OUT_OF_MEMORY);
5541 }
5542}
5543
5544void __stdcall glUniform1f(GLint location, GLfloat x)
5545{
5546 glUniform1fv(location, 1, &x);
5547}
5548
5549void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5550{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005551 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005552
5553 try
5554 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005555 if (count < 0)
5556 {
5557 return error(GL_INVALID_VALUE);
5558 }
5559
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005560 if (location == -1)
5561 {
5562 return;
5563 }
5564
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005565 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005566
5567 if (context)
5568 {
5569 gl::Program *program = context->getCurrentProgram();
5570
5571 if (!program)
5572 {
5573 return error(GL_INVALID_OPERATION);
5574 }
5575
5576 if (!program->setUniform1fv(location, count, v))
5577 {
5578 return error(GL_INVALID_OPERATION);
5579 }
5580 }
5581 }
5582 catch(std::bad_alloc&)
5583 {
5584 return error(GL_OUT_OF_MEMORY);
5585 }
5586}
5587
5588void __stdcall glUniform1i(GLint location, GLint x)
5589{
5590 glUniform1iv(location, 1, &x);
5591}
5592
5593void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5594{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005595 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005596
5597 try
5598 {
5599 if (count < 0)
5600 {
5601 return error(GL_INVALID_VALUE);
5602 }
5603
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005604 if (location == -1)
5605 {
5606 return;
5607 }
5608
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005609 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005610
5611 if (context)
5612 {
5613 gl::Program *program = context->getCurrentProgram();
5614
5615 if (!program)
5616 {
5617 return error(GL_INVALID_OPERATION);
5618 }
5619
5620 if (!program->setUniform1iv(location, count, v))
5621 {
5622 return error(GL_INVALID_OPERATION);
5623 }
5624 }
5625 }
5626 catch(std::bad_alloc&)
5627 {
5628 return error(GL_OUT_OF_MEMORY);
5629 }
5630}
5631
5632void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5633{
5634 GLfloat xy[2] = {x, y};
5635
5636 glUniform2fv(location, 1, (GLfloat*)&xy);
5637}
5638
5639void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5640{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005641 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005642
5643 try
5644 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005645 if (count < 0)
5646 {
5647 return error(GL_INVALID_VALUE);
5648 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005649
5650 if (location == -1)
5651 {
5652 return;
5653 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005654
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005655 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005656
5657 if (context)
5658 {
5659 gl::Program *program = context->getCurrentProgram();
5660
5661 if (!program)
5662 {
5663 return error(GL_INVALID_OPERATION);
5664 }
5665
5666 if (!program->setUniform2fv(location, count, v))
5667 {
5668 return error(GL_INVALID_OPERATION);
5669 }
5670 }
5671 }
5672 catch(std::bad_alloc&)
5673 {
5674 return error(GL_OUT_OF_MEMORY);
5675 }
5676}
5677
5678void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5679{
5680 GLint xy[4] = {x, y};
5681
5682 glUniform2iv(location, 1, (GLint*)&xy);
5683}
5684
5685void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5686{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005687 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005688
5689 try
5690 {
5691 if (count < 0)
5692 {
5693 return error(GL_INVALID_VALUE);
5694 }
5695
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005696 if (location == -1)
5697 {
5698 return;
5699 }
5700
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005701 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005702
5703 if (context)
5704 {
5705 gl::Program *program = context->getCurrentProgram();
5706
5707 if (!program)
5708 {
5709 return error(GL_INVALID_OPERATION);
5710 }
5711
5712 if (!program->setUniform2iv(location, count, v))
5713 {
5714 return error(GL_INVALID_OPERATION);
5715 }
5716 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005717 }
5718 catch(std::bad_alloc&)
5719 {
5720 return error(GL_OUT_OF_MEMORY);
5721 }
5722}
5723
5724void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5725{
5726 GLfloat xyz[3] = {x, y, z};
5727
5728 glUniform3fv(location, 1, (GLfloat*)&xyz);
5729}
5730
5731void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5732{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005733 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005734
5735 try
5736 {
5737 if (count < 0)
5738 {
5739 return error(GL_INVALID_VALUE);
5740 }
5741
5742 if (location == -1)
5743 {
5744 return;
5745 }
5746
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005747 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005748
5749 if (context)
5750 {
5751 gl::Program *program = context->getCurrentProgram();
5752
5753 if (!program)
5754 {
5755 return error(GL_INVALID_OPERATION);
5756 }
5757
5758 if (!program->setUniform3fv(location, count, v))
5759 {
5760 return error(GL_INVALID_OPERATION);
5761 }
5762 }
5763 }
5764 catch(std::bad_alloc&)
5765 {
5766 return error(GL_OUT_OF_MEMORY);
5767 }
5768}
5769
5770void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5771{
5772 GLint xyz[3] = {x, y, z};
5773
5774 glUniform3iv(location, 1, (GLint*)&xyz);
5775}
5776
5777void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5778{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005779 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005780
5781 try
5782 {
5783 if (count < 0)
5784 {
5785 return error(GL_INVALID_VALUE);
5786 }
5787
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005788 if (location == -1)
5789 {
5790 return;
5791 }
5792
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005793 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005794
5795 if (context)
5796 {
5797 gl::Program *program = context->getCurrentProgram();
5798
5799 if (!program)
5800 {
5801 return error(GL_INVALID_OPERATION);
5802 }
5803
5804 if (!program->setUniform3iv(location, count, v))
5805 {
5806 return error(GL_INVALID_OPERATION);
5807 }
5808 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005809 }
5810 catch(std::bad_alloc&)
5811 {
5812 return error(GL_OUT_OF_MEMORY);
5813 }
5814}
5815
5816void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5817{
5818 GLfloat xyzw[4] = {x, y, z, w};
5819
5820 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5821}
5822
5823void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5824{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005825 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005826
5827 try
5828 {
5829 if (count < 0)
5830 {
5831 return error(GL_INVALID_VALUE);
5832 }
5833
5834 if (location == -1)
5835 {
5836 return;
5837 }
5838
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005839 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005840
5841 if (context)
5842 {
5843 gl::Program *program = context->getCurrentProgram();
5844
5845 if (!program)
5846 {
5847 return error(GL_INVALID_OPERATION);
5848 }
5849
5850 if (!program->setUniform4fv(location, count, v))
5851 {
5852 return error(GL_INVALID_OPERATION);
5853 }
5854 }
5855 }
5856 catch(std::bad_alloc&)
5857 {
5858 return error(GL_OUT_OF_MEMORY);
5859 }
5860}
5861
5862void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5863{
5864 GLint xyzw[4] = {x, y, z, w};
5865
5866 glUniform4iv(location, 1, (GLint*)&xyzw);
5867}
5868
5869void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5870{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005871 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005872
5873 try
5874 {
5875 if (count < 0)
5876 {
5877 return error(GL_INVALID_VALUE);
5878 }
5879
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005880 if (location == -1)
5881 {
5882 return;
5883 }
5884
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005885 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005886
5887 if (context)
5888 {
5889 gl::Program *program = context->getCurrentProgram();
5890
5891 if (!program)
5892 {
5893 return error(GL_INVALID_OPERATION);
5894 }
5895
5896 if (!program->setUniform4iv(location, count, v))
5897 {
5898 return error(GL_INVALID_OPERATION);
5899 }
5900 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005901 }
5902 catch(std::bad_alloc&)
5903 {
5904 return error(GL_OUT_OF_MEMORY);
5905 }
5906}
5907
5908void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5909{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005910 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005911 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005912
5913 try
5914 {
5915 if (count < 0 || transpose != GL_FALSE)
5916 {
5917 return error(GL_INVALID_VALUE);
5918 }
5919
5920 if (location == -1)
5921 {
5922 return;
5923 }
5924
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005925 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005926
5927 if (context)
5928 {
5929 gl::Program *program = context->getCurrentProgram();
5930
5931 if (!program)
5932 {
5933 return error(GL_INVALID_OPERATION);
5934 }
5935
5936 if (!program->setUniformMatrix2fv(location, count, value))
5937 {
5938 return error(GL_INVALID_OPERATION);
5939 }
5940 }
5941 }
5942 catch(std::bad_alloc&)
5943 {
5944 return error(GL_OUT_OF_MEMORY);
5945 }
5946}
5947
5948void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5949{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005950 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005951 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005952
5953 try
5954 {
5955 if (count < 0 || transpose != GL_FALSE)
5956 {
5957 return error(GL_INVALID_VALUE);
5958 }
5959
5960 if (location == -1)
5961 {
5962 return;
5963 }
5964
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005965 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005966
5967 if (context)
5968 {
5969 gl::Program *program = context->getCurrentProgram();
5970
5971 if (!program)
5972 {
5973 return error(GL_INVALID_OPERATION);
5974 }
5975
5976 if (!program->setUniformMatrix3fv(location, count, value))
5977 {
5978 return error(GL_INVALID_OPERATION);
5979 }
5980 }
5981 }
5982 catch(std::bad_alloc&)
5983 {
5984 return error(GL_OUT_OF_MEMORY);
5985 }
5986}
5987
5988void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5989{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005990 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005991 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005992
5993 try
5994 {
5995 if (count < 0 || transpose != GL_FALSE)
5996 {
5997 return error(GL_INVALID_VALUE);
5998 }
5999
6000 if (location == -1)
6001 {
6002 return;
6003 }
6004
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006005 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006006
6007 if (context)
6008 {
6009 gl::Program *program = context->getCurrentProgram();
6010
6011 if (!program)
6012 {
6013 return error(GL_INVALID_OPERATION);
6014 }
6015
6016 if (!program->setUniformMatrix4fv(location, count, value))
6017 {
6018 return error(GL_INVALID_OPERATION);
6019 }
6020 }
6021 }
6022 catch(std::bad_alloc&)
6023 {
6024 return error(GL_OUT_OF_MEMORY);
6025 }
6026}
6027
6028void __stdcall glUseProgram(GLuint program)
6029{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006030 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006031
6032 try
6033 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006034 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006035
6036 if (context)
6037 {
6038 gl::Program *programObject = context->getProgram(program);
6039
daniel@transgaming.comc8478202010-04-13 19:53:35 +00006040 if (!programObject && program != 0)
6041 {
6042 if (context->getShader(program))
6043 {
6044 return error(GL_INVALID_OPERATION);
6045 }
6046 else
6047 {
6048 return error(GL_INVALID_VALUE);
6049 }
6050 }
6051
6052 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006053 {
6054 return error(GL_INVALID_OPERATION);
6055 }
6056
6057 context->useProgram(program);
6058 }
6059 }
6060 catch(std::bad_alloc&)
6061 {
6062 return error(GL_OUT_OF_MEMORY);
6063 }
6064}
6065
6066void __stdcall glValidateProgram(GLuint program)
6067{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006068 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006069
6070 try
6071 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006072 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006073
6074 if (context)
6075 {
6076 gl::Program *programObject = context->getProgram(program);
6077
6078 if (!programObject)
6079 {
6080 if (context->getShader(program))
6081 {
6082 return error(GL_INVALID_OPERATION);
6083 }
6084 else
6085 {
6086 return error(GL_INVALID_VALUE);
6087 }
6088 }
6089
6090 programObject->validate();
6091 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006092 }
6093 catch(std::bad_alloc&)
6094 {
6095 return error(GL_OUT_OF_MEMORY);
6096 }
6097}
6098
6099void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
6100{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006101 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006102
6103 try
6104 {
6105 if (index >= gl::MAX_VERTEX_ATTRIBS)
6106 {
6107 return error(GL_INVALID_VALUE);
6108 }
6109
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006110 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006111
6112 if (context)
6113 {
6114 GLfloat vals[4] = { x, 0, 0, 1 };
6115 context->setVertexAttrib(index, vals);
6116 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006117 }
6118 catch(std::bad_alloc&)
6119 {
6120 return error(GL_OUT_OF_MEMORY);
6121 }
6122}
6123
6124void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
6125{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006126 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006127
6128 try
6129 {
6130 if (index >= gl::MAX_VERTEX_ATTRIBS)
6131 {
6132 return error(GL_INVALID_VALUE);
6133 }
6134
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006135 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006136
6137 if (context)
6138 {
6139 GLfloat vals[4] = { values[0], 0, 0, 1 };
6140 context->setVertexAttrib(index, vals);
6141 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006142 }
6143 catch(std::bad_alloc&)
6144 {
6145 return error(GL_OUT_OF_MEMORY);
6146 }
6147}
6148
6149void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6150{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006151 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006152
6153 try
6154 {
6155 if (index >= gl::MAX_VERTEX_ATTRIBS)
6156 {
6157 return error(GL_INVALID_VALUE);
6158 }
6159
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006160 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006161
6162 if (context)
6163 {
6164 GLfloat vals[4] = { x, y, 0, 1 };
6165 context->setVertexAttrib(index, vals);
6166 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006167 }
6168 catch(std::bad_alloc&)
6169 {
6170 return error(GL_OUT_OF_MEMORY);
6171 }
6172}
6173
6174void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
6175{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006176 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006177
6178 try
6179 {
6180 if (index >= gl::MAX_VERTEX_ATTRIBS)
6181 {
6182 return error(GL_INVALID_VALUE);
6183 }
6184
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006185 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006186
6187 if (context)
6188 {
6189 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6190 context->setVertexAttrib(index, vals);
6191 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006192 }
6193 catch(std::bad_alloc&)
6194 {
6195 return error(GL_OUT_OF_MEMORY);
6196 }
6197}
6198
6199void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6200{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006201 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 +00006202
6203 try
6204 {
6205 if (index >= gl::MAX_VERTEX_ATTRIBS)
6206 {
6207 return error(GL_INVALID_VALUE);
6208 }
6209
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006210 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006211
6212 if (context)
6213 {
6214 GLfloat vals[4] = { x, y, z, 1 };
6215 context->setVertexAttrib(index, vals);
6216 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006217 }
6218 catch(std::bad_alloc&)
6219 {
6220 return error(GL_OUT_OF_MEMORY);
6221 }
6222}
6223
6224void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
6225{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006226 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006227
6228 try
6229 {
6230 if (index >= gl::MAX_VERTEX_ATTRIBS)
6231 {
6232 return error(GL_INVALID_VALUE);
6233 }
6234
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006235 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006236
6237 if (context)
6238 {
6239 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6240 context->setVertexAttrib(index, vals);
6241 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006242 }
6243 catch(std::bad_alloc&)
6244 {
6245 return error(GL_OUT_OF_MEMORY);
6246 }
6247}
6248
6249void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6250{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006251 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 +00006252
6253 try
6254 {
6255 if (index >= gl::MAX_VERTEX_ATTRIBS)
6256 {
6257 return error(GL_INVALID_VALUE);
6258 }
6259
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006260 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006261
6262 if (context)
6263 {
6264 GLfloat vals[4] = { x, y, z, w };
6265 context->setVertexAttrib(index, vals);
6266 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006267 }
6268 catch(std::bad_alloc&)
6269 {
6270 return error(GL_OUT_OF_MEMORY);
6271 }
6272}
6273
6274void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
6275{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006276 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006277
6278 try
6279 {
6280 if (index >= gl::MAX_VERTEX_ATTRIBS)
6281 {
6282 return error(GL_INVALID_VALUE);
6283 }
6284
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006285 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006286
6287 if (context)
6288 {
6289 context->setVertexAttrib(index, values);
6290 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006291 }
6292 catch(std::bad_alloc&)
6293 {
6294 return error(GL_OUT_OF_MEMORY);
6295 }
6296}
6297
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00006298void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
6299{
6300 EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
6301
6302 try
6303 {
6304 if (index >= gl::MAX_VERTEX_ATTRIBS)
6305 {
6306 return error(GL_INVALID_VALUE);
6307 }
6308
6309 gl::Context *context = gl::getNonLostContext();
6310
6311 if (context)
6312 {
6313 context->setVertexAttribDivisor(index, divisor);
6314 }
6315 }
6316 catch(std::bad_alloc&)
6317 {
6318 return error(GL_OUT_OF_MEMORY);
6319 }
6320}
6321
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006322void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006323{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006324 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006325 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006326 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006327
6328 try
6329 {
6330 if (index >= gl::MAX_VERTEX_ATTRIBS)
6331 {
6332 return error(GL_INVALID_VALUE);
6333 }
6334
6335 if (size < 1 || size > 4)
6336 {
6337 return error(GL_INVALID_VALUE);
6338 }
6339
6340 switch (type)
6341 {
6342 case GL_BYTE:
6343 case GL_UNSIGNED_BYTE:
6344 case GL_SHORT:
6345 case GL_UNSIGNED_SHORT:
6346 case GL_FIXED:
6347 case GL_FLOAT:
6348 break;
6349 default:
6350 return error(GL_INVALID_ENUM);
6351 }
6352
6353 if (stride < 0)
6354 {
6355 return error(GL_INVALID_VALUE);
6356 }
6357
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006358 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006359
6360 if (context)
6361 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006362 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006363 }
6364 }
6365 catch(std::bad_alloc&)
6366 {
6367 return error(GL_OUT_OF_MEMORY);
6368 }
6369}
6370
6371void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6372{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006373 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 +00006374
6375 try
6376 {
6377 if (width < 0 || height < 0)
6378 {
6379 return error(GL_INVALID_VALUE);
6380 }
6381
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006382 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006383
6384 if (context)
6385 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006386 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006387 }
6388 }
6389 catch(std::bad_alloc&)
6390 {
6391 return error(GL_OUT_OF_MEMORY);
6392 }
6393}
6394
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006395void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6396 GLbitfield mask, GLenum filter)
6397{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006398 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006399 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6400 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6401 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6402
6403 try
6404 {
6405 switch (filter)
6406 {
6407 case GL_NEAREST:
6408 break;
6409 default:
6410 return error(GL_INVALID_ENUM);
6411 }
6412
6413 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6414 {
6415 return error(GL_INVALID_VALUE);
6416 }
6417
6418 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6419 {
6420 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6421 return error(GL_INVALID_OPERATION);
6422 }
6423
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006424 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006425
6426 if (context)
6427 {
6428 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6429 {
6430 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6431 return error(GL_INVALID_OPERATION);
6432 }
6433
6434 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6435 }
6436 }
6437 catch(std::bad_alloc&)
6438 {
6439 return error(GL_OUT_OF_MEMORY);
6440 }
6441}
6442
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006443void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6444 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006445{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006446 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006447 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006448 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006449 target, level, internalformat, width, height, depth, border, format, type, pixels);
6450
6451 try
6452 {
6453 UNIMPLEMENTED(); // FIXME
6454 }
6455 catch(std::bad_alloc&)
6456 {
6457 return error(GL_OUT_OF_MEMORY);
6458 }
6459}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006460
6461__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6462{
6463 struct Extension
6464 {
6465 const char *name;
6466 __eglMustCastToProperFunctionPointerType address;
6467 };
6468
6469 static const Extension glExtensions[] =
6470 {
6471 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006472 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006473 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006474 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6475 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6476 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6477 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6478 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6479 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6480 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006481 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006482 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006483 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6484 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6485 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6486 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00006487 {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT},
6488 {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT},
6489 {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT},
6490 {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT},
6491 {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
6492 {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
6493 {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006494 };
6495
6496 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6497 {
6498 if (strcmp(procname, glExtensions[ext].name) == 0)
6499 {
6500 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6501 }
6502 }
6503
6504 return NULL;
6505}
6506
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006507// Non-public functions used by EGL
6508
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006509bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006510{
6511 EVENT("(egl::Surface* surface = 0x%0.8p)",
6512 surface);
6513
6514 try
6515 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006516 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006517
6518 if (context)
6519 {
6520 gl::Texture2D *textureObject = context->getTexture2D();
6521
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006522 if (textureObject->isImmutable())
6523 {
6524 return false;
6525 }
6526
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006527 if (textureObject)
6528 {
6529 textureObject->bindTexImage(surface);
6530 }
6531 }
6532 }
6533 catch(std::bad_alloc&)
6534 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006535 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006536 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006537
6538 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006539}
6540
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006541}