blob: 30055bb832186bbceb6697600394e8c9065dff7a [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.com4f39fd92010-03-08 20:26:45 +000030
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +000031bool validImageSize(GLint level, GLsizei width, GLsizei height)
32{
33 if (level < 0 || width < 0 || height < 0)
34 {
35 return false;
36 }
37
38 if (gl::getContext() && gl::getContext()->supportsNonPower2Texture())
39 {
40 return true;
41 }
42
43 if (level == 0)
44 {
45 return true;
46 }
47
48 if (gl::isPow2(width) && gl::isPow2(height))
49 {
50 return true;
51 }
52
53 return false;
54}
55
daniel@transgaming.com343373a2011-11-29 19:42:32 +000056bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLint level, GLenum format, gl::Texture *texture)
57{
58 if (!texture)
59 {
60 return error(GL_INVALID_OPERATION, false);
61 }
62
63 if (compressed != texture->isCompressed())
64 {
65 return error(GL_INVALID_OPERATION, false);
66 }
67
68 if (format != GL_NONE && format != texture->getInternalFormat())
69 {
70 return error(GL_INVALID_OPERATION, false);
71 }
72
73 if (compressed)
74 {
75 if ((width % 4 != 0 && width != texture->getWidth(0)) ||
76 (height % 4 != 0 && height != texture->getHeight(0)))
77 {
78 return error(GL_INVALID_OPERATION, false);
79 }
80 }
81
82 if (xoffset + width > texture->getWidth(level) ||
83 yoffset + height > texture->getHeight(level))
84 {
85 return error(GL_INVALID_VALUE, false);
86 }
87
88 return true;
89}
90
daniel@transgaming.comb7915a52011-11-12 03:14:20 +000091// check for combinations of format and type that are valid for ReadPixels
92bool validReadFormatType(GLenum format, GLenum type)
93{
94 switch (format)
95 {
96 case GL_RGBA:
97 switch (type)
98 {
99 case GL_UNSIGNED_BYTE:
100 break;
101 default:
102 return false;
103 }
104 break;
105 case GL_BGRA_EXT:
106 switch (type)
107 {
108 case GL_UNSIGNED_BYTE:
109 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
110 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
111 break;
112 default:
113 return false;
114 }
115 break;
116 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
117 switch (type)
118 {
119 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
120 break;
121 default:
122 return false;
123 }
124 break;
125 default:
126 return false;
127 }
128 return true;
129}
130
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000131extern "C"
132{
133
134void __stdcall glActiveTexture(GLenum texture)
135{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000136 EVENT("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137
138 try
139 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000140 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000141
142 if (context)
143 {
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +0000144 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
145 {
146 return error(GL_INVALID_ENUM);
147 }
148
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000149 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000150 }
151 }
152 catch(std::bad_alloc&)
153 {
154 return error(GL_OUT_OF_MEMORY);
155 }
156}
157
158void __stdcall glAttachShader(GLuint program, GLuint shader)
159{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000160 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000161
162 try
163 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000164 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000165
166 if (context)
167 {
168 gl::Program *programObject = context->getProgram(program);
169 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000170
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000171 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000172 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000173 if (context->getShader(program))
174 {
175 return error(GL_INVALID_OPERATION);
176 }
177 else
178 {
179 return error(GL_INVALID_VALUE);
180 }
181 }
182
183 if (!shaderObject)
184 {
185 if (context->getProgram(shader))
186 {
187 return error(GL_INVALID_OPERATION);
188 }
189 else
190 {
191 return error(GL_INVALID_VALUE);
192 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000193 }
194
195 if (!programObject->attachShader(shaderObject))
196 {
197 return error(GL_INVALID_OPERATION);
198 }
199 }
200 }
201 catch(std::bad_alloc&)
202 {
203 return error(GL_OUT_OF_MEMORY);
204 }
205}
206
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000207void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000208{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000209 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000210
211 try
212 {
213 if (index >= gl::MAX_VERTEX_ATTRIBS)
214 {
215 return error(GL_INVALID_VALUE);
216 }
217
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000218 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000219
220 if (context)
221 {
222 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000223
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000224 if (!programObject)
225 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000226 if (context->getShader(program))
227 {
228 return error(GL_INVALID_OPERATION);
229 }
230 else
231 {
232 return error(GL_INVALID_VALUE);
233 }
234 }
235
236 if (strncmp(name, "gl_", 3) == 0)
237 {
238 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000239 }
240
241 programObject->bindAttributeLocation(index, name);
242 }
243 }
244 catch(std::bad_alloc&)
245 {
246 return error(GL_OUT_OF_MEMORY);
247 }
248}
249
250void __stdcall glBindBuffer(GLenum target, GLuint buffer)
251{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000252 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000253
254 try
255 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000256 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000257
258 if (context)
259 {
260 switch (target)
261 {
262 case GL_ARRAY_BUFFER:
263 context->bindArrayBuffer(buffer);
264 return;
265 case GL_ELEMENT_ARRAY_BUFFER:
266 context->bindElementArrayBuffer(buffer);
267 return;
268 default:
269 return error(GL_INVALID_ENUM);
270 }
271 }
272 }
273 catch(std::bad_alloc&)
274 {
275 return error(GL_OUT_OF_MEMORY);
276 }
277}
278
279void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
280{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000281 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000282
283 try
284 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000285 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000286 {
287 return error(GL_INVALID_ENUM);
288 }
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 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000294 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
295 {
296 context->bindReadFramebuffer(framebuffer);
297 }
298
299 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
300 {
301 context->bindDrawFramebuffer(framebuffer);
302 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000303 }
304 }
305 catch(std::bad_alloc&)
306 {
307 return error(GL_OUT_OF_MEMORY);
308 }
309}
310
311void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
312{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000313 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000314
315 try
316 {
317 if (target != GL_RENDERBUFFER)
318 {
319 return error(GL_INVALID_ENUM);
320 }
321
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000322 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000323
324 if (context)
325 {
326 context->bindRenderbuffer(renderbuffer);
327 }
328 }
329 catch(std::bad_alloc&)
330 {
331 return error(GL_OUT_OF_MEMORY);
332 }
333}
334
335void __stdcall glBindTexture(GLenum target, GLuint texture)
336{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000337 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000338
339 try
340 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000341 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000342
343 if (context)
344 {
345 gl::Texture *textureObject = context->getTexture(texture);
346
347 if (textureObject && textureObject->getTarget() != target && texture != 0)
348 {
349 return error(GL_INVALID_OPERATION);
350 }
351
352 switch (target)
353 {
354 case GL_TEXTURE_2D:
355 context->bindTexture2D(texture);
356 return;
357 case GL_TEXTURE_CUBE_MAP:
358 context->bindTextureCubeMap(texture);
359 return;
360 default:
361 return error(GL_INVALID_ENUM);
362 }
363 }
364 }
365 catch(std::bad_alloc&)
366 {
367 return error(GL_OUT_OF_MEMORY);
368 }
369}
370
371void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
372{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000373 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000374 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000375
376 try
377 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000378 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000379
380 if (context)
381 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000382 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000383 }
384 }
385 catch(std::bad_alloc&)
386 {
387 return error(GL_OUT_OF_MEMORY);
388 }
389}
390
391void __stdcall glBlendEquation(GLenum mode)
392{
393 glBlendEquationSeparate(mode, mode);
394}
395
396void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
397{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000398 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000399
400 try
401 {
402 switch (modeRGB)
403 {
404 case GL_FUNC_ADD:
405 case GL_FUNC_SUBTRACT:
406 case GL_FUNC_REVERSE_SUBTRACT:
407 break;
408 default:
409 return error(GL_INVALID_ENUM);
410 }
411
412 switch (modeAlpha)
413 {
414 case GL_FUNC_ADD:
415 case GL_FUNC_SUBTRACT:
416 case GL_FUNC_REVERSE_SUBTRACT:
417 break;
418 default:
419 return error(GL_INVALID_ENUM);
420 }
421
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000422 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000423
424 if (context)
425 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000426 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000427 }
428 }
429 catch(std::bad_alloc&)
430 {
431 return error(GL_OUT_OF_MEMORY);
432 }
433}
434
435void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
436{
437 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
438}
439
440void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
441{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000442 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 +0000443 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000444
445 try
446 {
447 switch (srcRGB)
448 {
449 case GL_ZERO:
450 case GL_ONE:
451 case GL_SRC_COLOR:
452 case GL_ONE_MINUS_SRC_COLOR:
453 case GL_DST_COLOR:
454 case GL_ONE_MINUS_DST_COLOR:
455 case GL_SRC_ALPHA:
456 case GL_ONE_MINUS_SRC_ALPHA:
457 case GL_DST_ALPHA:
458 case GL_ONE_MINUS_DST_ALPHA:
459 case GL_CONSTANT_COLOR:
460 case GL_ONE_MINUS_CONSTANT_COLOR:
461 case GL_CONSTANT_ALPHA:
462 case GL_ONE_MINUS_CONSTANT_ALPHA:
463 case GL_SRC_ALPHA_SATURATE:
464 break;
465 default:
466 return error(GL_INVALID_ENUM);
467 }
468
469 switch (dstRGB)
470 {
471 case GL_ZERO:
472 case GL_ONE:
473 case GL_SRC_COLOR:
474 case GL_ONE_MINUS_SRC_COLOR:
475 case GL_DST_COLOR:
476 case GL_ONE_MINUS_DST_COLOR:
477 case GL_SRC_ALPHA:
478 case GL_ONE_MINUS_SRC_ALPHA:
479 case GL_DST_ALPHA:
480 case GL_ONE_MINUS_DST_ALPHA:
481 case GL_CONSTANT_COLOR:
482 case GL_ONE_MINUS_CONSTANT_COLOR:
483 case GL_CONSTANT_ALPHA:
484 case GL_ONE_MINUS_CONSTANT_ALPHA:
485 break;
486 default:
487 return error(GL_INVALID_ENUM);
488 }
489
490 switch (srcAlpha)
491 {
492 case GL_ZERO:
493 case GL_ONE:
494 case GL_SRC_COLOR:
495 case GL_ONE_MINUS_SRC_COLOR:
496 case GL_DST_COLOR:
497 case GL_ONE_MINUS_DST_COLOR:
498 case GL_SRC_ALPHA:
499 case GL_ONE_MINUS_SRC_ALPHA:
500 case GL_DST_ALPHA:
501 case GL_ONE_MINUS_DST_ALPHA:
502 case GL_CONSTANT_COLOR:
503 case GL_ONE_MINUS_CONSTANT_COLOR:
504 case GL_CONSTANT_ALPHA:
505 case GL_ONE_MINUS_CONSTANT_ALPHA:
506 case GL_SRC_ALPHA_SATURATE:
507 break;
508 default:
509 return error(GL_INVALID_ENUM);
510 }
511
512 switch (dstAlpha)
513 {
514 case GL_ZERO:
515 case GL_ONE:
516 case GL_SRC_COLOR:
517 case GL_ONE_MINUS_SRC_COLOR:
518 case GL_DST_COLOR:
519 case GL_ONE_MINUS_DST_COLOR:
520 case GL_SRC_ALPHA:
521 case GL_ONE_MINUS_SRC_ALPHA:
522 case GL_DST_ALPHA:
523 case GL_ONE_MINUS_DST_ALPHA:
524 case GL_CONSTANT_COLOR:
525 case GL_ONE_MINUS_CONSTANT_COLOR:
526 case GL_CONSTANT_ALPHA:
527 case GL_ONE_MINUS_CONSTANT_ALPHA:
528 break;
529 default:
530 return error(GL_INVALID_ENUM);
531 }
532
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000533 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
534 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
535
536 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
537 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
538
539 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000540 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000541 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
542 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000543 }
544
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000545 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000546
547 if (context)
548 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000549 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000550 }
551 }
552 catch(std::bad_alloc&)
553 {
554 return error(GL_OUT_OF_MEMORY);
555 }
556}
557
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000558void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000559{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000560 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 +0000561 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000562
563 try
564 {
565 if (size < 0)
566 {
567 return error(GL_INVALID_VALUE);
568 }
569
570 switch (usage)
571 {
572 case GL_STREAM_DRAW:
573 case GL_STATIC_DRAW:
574 case GL_DYNAMIC_DRAW:
575 break;
576 default:
577 return error(GL_INVALID_ENUM);
578 }
579
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000580 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000581
582 if (context)
583 {
584 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000585
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000586 switch (target)
587 {
588 case GL_ARRAY_BUFFER:
589 buffer = context->getArrayBuffer();
590 break;
591 case GL_ELEMENT_ARRAY_BUFFER:
592 buffer = context->getElementArrayBuffer();
593 break;
594 default:
595 return error(GL_INVALID_ENUM);
596 }
597
598 if (!buffer)
599 {
600 return error(GL_INVALID_OPERATION);
601 }
602
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000603 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000604 }
605 }
606 catch(std::bad_alloc&)
607 {
608 return error(GL_OUT_OF_MEMORY);
609 }
610}
611
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000612void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000613{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000614 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 +0000615 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000616
617 try
618 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000619 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000620 {
621 return error(GL_INVALID_VALUE);
622 }
623
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000624 if (data == NULL)
625 {
626 return;
627 }
628
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000629 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000630
631 if (context)
632 {
633 gl::Buffer *buffer;
634
635 switch (target)
636 {
637 case GL_ARRAY_BUFFER:
638 buffer = context->getArrayBuffer();
639 break;
640 case GL_ELEMENT_ARRAY_BUFFER:
641 buffer = context->getElementArrayBuffer();
642 break;
643 default:
644 return error(GL_INVALID_ENUM);
645 }
646
647 if (!buffer)
648 {
649 return error(GL_INVALID_OPERATION);
650 }
651
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000652 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000653 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000654 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000655 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000656
657 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000658 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000659 }
660 catch(std::bad_alloc&)
661 {
662 return error(GL_OUT_OF_MEMORY);
663 }
664}
665
666GLenum __stdcall glCheckFramebufferStatus(GLenum target)
667{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000668 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000669
670 try
671 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000672 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000673 {
674 return error(GL_INVALID_ENUM, 0);
675 }
676
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000677 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000678
679 if (context)
680 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000681 gl::Framebuffer *framebuffer = NULL;
682 if (target == GL_READ_FRAMEBUFFER_ANGLE)
683 {
684 framebuffer = context->getReadFramebuffer();
685 }
686 else
687 {
688 framebuffer = context->getDrawFramebuffer();
689 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000690
691 return framebuffer->completeness();
692 }
693 }
694 catch(std::bad_alloc&)
695 {
696 return error(GL_OUT_OF_MEMORY, 0);
697 }
698
699 return 0;
700}
701
702void __stdcall glClear(GLbitfield mask)
703{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000704 EVENT("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000705
706 try
707 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000708 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000709
710 if (context)
711 {
712 context->clear(mask);
713 }
714 }
715 catch(std::bad_alloc&)
716 {
717 return error(GL_OUT_OF_MEMORY);
718 }
719}
720
721void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
722{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000723 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000724 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000725
726 try
727 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000728 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000729
730 if (context)
731 {
732 context->setClearColor(red, green, blue, alpha);
733 }
734 }
735 catch(std::bad_alloc&)
736 {
737 return error(GL_OUT_OF_MEMORY);
738 }
739}
740
741void __stdcall glClearDepthf(GLclampf depth)
742{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000743 EVENT("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000744
745 try
746 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000747 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748
749 if (context)
750 {
751 context->setClearDepth(depth);
752 }
753 }
754 catch(std::bad_alloc&)
755 {
756 return error(GL_OUT_OF_MEMORY);
757 }
758}
759
760void __stdcall glClearStencil(GLint s)
761{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000762 EVENT("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000763
764 try
765 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000766 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000767
768 if (context)
769 {
770 context->setClearStencil(s);
771 }
772 }
773 catch(std::bad_alloc&)
774 {
775 return error(GL_OUT_OF_MEMORY);
776 }
777}
778
779void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
780{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000781 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000782 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000783
784 try
785 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000786 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000787
788 if (context)
789 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000790 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000791 }
792 }
793 catch(std::bad_alloc&)
794 {
795 return error(GL_OUT_OF_MEMORY);
796 }
797}
798
799void __stdcall glCompileShader(GLuint shader)
800{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000801 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000802
803 try
804 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000805 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000806
807 if (context)
808 {
809 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000810
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000811 if (!shaderObject)
812 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000813 if (context->getProgram(shader))
814 {
815 return error(GL_INVALID_OPERATION);
816 }
817 else
818 {
819 return error(GL_INVALID_VALUE);
820 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000821 }
822
823 shaderObject->compile();
824 }
825 }
826 catch(std::bad_alloc&)
827 {
828 return error(GL_OUT_OF_MEMORY);
829 }
830}
831
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000832void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
833 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000834{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000835 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000836 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000837 target, level, internalformat, width, height, border, imageSize, data);
838
839 try
840 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000841 if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000842 {
843 return error(GL_INVALID_VALUE);
844 }
845
daniel@transgaming.com01868132010-08-24 19:21:17 +0000846 switch (internalformat)
847 {
848 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
849 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +0000850 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
851 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +0000852 break;
853 default:
854 return error(GL_INVALID_ENUM);
855 }
856
857 if (border != 0)
858 {
859 return error(GL_INVALID_VALUE);
860 }
861
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000862 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000863
864 if (context)
865 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000866 if (level > context->getMaximumTextureLevel())
867 {
868 return error(GL_INVALID_VALUE);
869 }
870
871 switch (target)
872 {
873 case GL_TEXTURE_2D:
874 if (width > (context->getMaximumTextureDimension() >> level) ||
875 height > (context->getMaximumTextureDimension() >> level))
876 {
877 return error(GL_INVALID_VALUE);
878 }
879 break;
880 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
881 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
882 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
883 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
884 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
885 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
886 if (width != height)
887 {
888 return error(GL_INVALID_VALUE);
889 }
890
891 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
892 height > (context->getMaximumCubeTextureDimension() >> level))
893 {
894 return error(GL_INVALID_VALUE);
895 }
896 break;
897 default:
898 return error(GL_INVALID_ENUM);
899 }
900
gman@chromium.org50c526d2011-08-10 05:19:44 +0000901 switch (internalformat) {
902 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
903 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
904 if (!context->supportsDXT1Textures())
905 {
906 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
907 }
908 break;
909 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
910 if (!context->supportsDXT3Textures())
911 {
912 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
913 }
914 break;
915 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
916 if (!context->supportsDXT5Textures())
917 {
918 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
919 }
920 break;
921 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000922 }
923
924 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
925 {
926 return error(GL_INVALID_VALUE);
927 }
928
929 if (target == GL_TEXTURE_2D)
930 {
931 gl::Texture2D *texture = context->getTexture2D();
932
933 if (!texture)
934 {
935 return error(GL_INVALID_OPERATION);
936 }
937
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +0000938 if (texture->isImmutable())
939 {
940 return error(GL_INVALID_OPERATION);
941 }
942
daniel@transgaming.com01868132010-08-24 19:21:17 +0000943 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
944 }
945 else
946 {
947 gl::TextureCubeMap *texture = context->getTextureCubeMap();
948
949 if (!texture)
950 {
951 return error(GL_INVALID_OPERATION);
952 }
953
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +0000954 if (texture->isImmutable())
955 {
956 return error(GL_INVALID_OPERATION);
957 }
958
daniel@transgaming.com01868132010-08-24 19:21:17 +0000959 switch (target)
960 {
961 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
962 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
963 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
964 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
965 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
966 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
967 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
968 break;
969 default: UNREACHABLE();
970 }
971 }
972 }
973
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000974 }
975 catch(std::bad_alloc&)
976 {
977 return error(GL_OUT_OF_MEMORY);
978 }
979}
980
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000981void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
982 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000983{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000984 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000985 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000986 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000987 target, level, xoffset, yoffset, width, height, format, imageSize, data);
988
989 try
990 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000991 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000992 {
993 return error(GL_INVALID_ENUM);
994 }
995
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000996 if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000997 {
998 return error(GL_INVALID_VALUE);
999 }
1000
daniel@transgaming.com01868132010-08-24 19:21:17 +00001001 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001002 {
daniel@transgaming.com01868132010-08-24 19:21:17 +00001003 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1004 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001005 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1006 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001007 break;
1008 default:
1009 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +00001010 }
1011
daniel@transgaming.com01868132010-08-24 19:21:17 +00001012 if (width == 0 || height == 0 || data == NULL)
1013 {
1014 return;
1015 }
1016
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001017 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001018
1019 if (context)
1020 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001021 if (level > context->getMaximumTextureLevel())
1022 {
1023 return error(GL_INVALID_VALUE);
1024 }
1025
gman@chromium.org50c526d2011-08-10 05:19:44 +00001026 switch (format) {
1027 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1028 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1029 if (!context->supportsDXT1Textures())
1030 {
1031 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1032 }
1033 break;
1034 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1035 if (!context->supportsDXT3Textures())
1036 {
1037 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1038 }
1039 break;
1040 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1041 if (!context->supportsDXT5Textures())
1042 {
1043 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1044 }
1045 break;
1046 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001047 }
1048
1049 if (imageSize != gl::ComputeCompressedSize(width, height, format))
1050 {
1051 return error(GL_INVALID_VALUE);
1052 }
1053
1054 if (xoffset % 4 != 0 || yoffset % 4 != 0)
1055 {
1056 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 +00001057 // does not exist unless DXT textures are supported.
daniel@transgaming.com01868132010-08-24 19:21:17 +00001058 }
1059
1060 if (target == GL_TEXTURE_2D)
1061 {
1062 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001063 if (validateSubImageParams(true, width, height, xoffset, yoffset, level, GL_NONE, texture))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001064 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001065 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
daniel@transgaming.com01868132010-08-24 19:21:17 +00001066 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001067 }
1068 else if (gl::IsCubemapTextureTarget(target))
1069 {
1070 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001071 if (validateSubImageParams(true, width, height, xoffset, yoffset, level, GL_NONE, texture))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001072 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001073 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
daniel@transgaming.com01868132010-08-24 19:21:17 +00001074 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001075 }
1076 else
1077 {
1078 UNREACHABLE();
1079 }
1080 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001081 }
1082 catch(std::bad_alloc&)
1083 {
1084 return error(GL_OUT_OF_MEMORY);
1085 }
1086}
1087
1088void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1089{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001090 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001091 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001092 target, level, internalformat, x, y, width, height, border);
1093
1094 try
1095 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001096 if (!validImageSize(level, width, height))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001097 {
1098 return error(GL_INVALID_VALUE);
1099 }
1100
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001101 if (border != 0)
1102 {
1103 return error(GL_INVALID_VALUE);
1104 }
1105
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001106 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001107
1108 if (context)
1109 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00001110 if (level > context->getMaximumTextureLevel())
1111 {
1112 return error(GL_INVALID_VALUE);
1113 }
1114
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001115 switch (target)
1116 {
1117 case GL_TEXTURE_2D:
1118 if (width > (context->getMaximumTextureDimension() >> level) ||
1119 height > (context->getMaximumTextureDimension() >> level))
1120 {
1121 return error(GL_INVALID_VALUE);
1122 }
1123 break;
1124 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1125 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1126 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1127 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1128 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1129 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1130 if (width != height)
1131 {
1132 return error(GL_INVALID_VALUE);
1133 }
1134
1135 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1136 height > (context->getMaximumCubeTextureDimension() >> level))
1137 {
1138 return error(GL_INVALID_VALUE);
1139 }
1140 break;
1141 default:
1142 return error(GL_INVALID_ENUM);
1143 }
1144
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001145 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001146
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001147 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1148 {
1149 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1150 }
1151
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001152 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1153 {
1154 return error(GL_INVALID_OPERATION);
1155 }
1156
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001157 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001158 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001159
1160 // [OpenGL ES 2.0.24] table 3.9
1161 switch (internalformat)
1162 {
1163 case GL_ALPHA:
1164 if (colorbufferFormat != GL_ALPHA &&
1165 colorbufferFormat != GL_RGBA &&
1166 colorbufferFormat != GL_RGBA4 &&
1167 colorbufferFormat != GL_RGB5_A1 &&
1168 colorbufferFormat != GL_RGBA8_OES)
1169 {
1170 return error(GL_INVALID_OPERATION);
1171 }
1172 break;
1173 case GL_LUMINANCE:
1174 case GL_RGB:
1175 if (colorbufferFormat != GL_RGB &&
1176 colorbufferFormat != GL_RGB565 &&
1177 colorbufferFormat != GL_RGB8_OES &&
1178 colorbufferFormat != GL_RGBA &&
1179 colorbufferFormat != GL_RGBA4 &&
1180 colorbufferFormat != GL_RGB5_A1 &&
1181 colorbufferFormat != GL_RGBA8_OES)
1182 {
1183 return error(GL_INVALID_OPERATION);
1184 }
1185 break;
1186 case GL_LUMINANCE_ALPHA:
1187 case GL_RGBA:
1188 if (colorbufferFormat != GL_RGBA &&
1189 colorbufferFormat != GL_RGBA4 &&
1190 colorbufferFormat != GL_RGB5_A1 &&
1191 colorbufferFormat != GL_RGBA8_OES)
1192 {
1193 return error(GL_INVALID_OPERATION);
1194 }
1195 break;
1196 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1197 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001198 if (context->supportsDXT1Textures())
1199 {
1200 return error(GL_INVALID_OPERATION);
1201 }
1202 else
1203 {
1204 return error(GL_INVALID_ENUM);
1205 }
1206 break;
1207 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1208 if (context->supportsDXT3Textures())
1209 {
1210 return error(GL_INVALID_OPERATION);
1211 }
1212 else
1213 {
1214 return error(GL_INVALID_ENUM);
1215 }
1216 break;
1217 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1218 if (context->supportsDXT5Textures())
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001219 {
1220 return error(GL_INVALID_OPERATION);
1221 }
1222 else
1223 {
1224 return error(GL_INVALID_ENUM);
1225 }
1226 break;
1227 default:
1228 return error(GL_INVALID_ENUM);
1229 }
1230
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001231 if (target == GL_TEXTURE_2D)
1232 {
1233 gl::Texture2D *texture = context->getTexture2D();
1234
1235 if (!texture)
1236 {
1237 return error(GL_INVALID_OPERATION);
1238 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001239
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001240 if (texture->isImmutable())
1241 {
1242 return error(GL_INVALID_OPERATION);
1243 }
1244
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001245 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001246 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001247 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001248 {
1249 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1250
1251 if (!texture)
1252 {
1253 return error(GL_INVALID_OPERATION);
1254 }
1255
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001256 if (texture->isImmutable())
1257 {
1258 return error(GL_INVALID_OPERATION);
1259 }
1260
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001261 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001262 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001263 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001264 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001265 }
1266 catch(std::bad_alloc&)
1267 {
1268 return error(GL_OUT_OF_MEMORY);
1269 }
1270}
1271
1272void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1273{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001274 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001275 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001276 target, level, xoffset, yoffset, x, y, width, height);
1277
1278 try
1279 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001280 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001281 {
1282 return error(GL_INVALID_ENUM);
1283 }
1284
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001285 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001286 {
1287 return error(GL_INVALID_VALUE);
1288 }
1289
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001290 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1291 {
1292 return error(GL_INVALID_VALUE);
1293 }
1294
1295 if (width == 0 || height == 0)
1296 {
1297 return;
1298 }
1299
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001300 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001301
1302 if (context)
1303 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001304 if (level > context->getMaximumTextureLevel())
1305 {
1306 return error(GL_INVALID_VALUE);
1307 }
1308
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001309 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001310
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001311 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1312 {
1313 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1314 }
1315
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001316 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1317 {
1318 return error(GL_INVALID_OPERATION);
1319 }
1320
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001321 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001322 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001323 gl::Texture *texture = NULL;
1324
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001325 if (target == GL_TEXTURE_2D)
1326 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001327 texture = context->getTexture2D();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001328 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001329 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001330 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001331 texture = context->getTextureCubeMap();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001332 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001333 else UNREACHABLE();
1334
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001335 if (!validateSubImageParams(false, width, height, xoffset, yoffset, level, GL_NONE, texture))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001336 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001337 return; // error already registered by validateSubImageParams
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00001338 }
1339
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001340 GLenum textureFormat = texture->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001341
1342 // [OpenGL ES 2.0.24] table 3.9
1343 switch (textureFormat)
1344 {
1345 case GL_ALPHA:
1346 if (colorbufferFormat != GL_ALPHA &&
1347 colorbufferFormat != GL_RGBA &&
1348 colorbufferFormat != GL_RGBA4 &&
1349 colorbufferFormat != GL_RGB5_A1 &&
1350 colorbufferFormat != GL_RGBA8_OES)
1351 {
1352 return error(GL_INVALID_OPERATION);
1353 }
1354 break;
1355 case GL_LUMINANCE:
1356 case GL_RGB:
1357 if (colorbufferFormat != GL_RGB &&
1358 colorbufferFormat != GL_RGB565 &&
1359 colorbufferFormat != GL_RGB8_OES &&
1360 colorbufferFormat != GL_RGBA &&
1361 colorbufferFormat != GL_RGBA4 &&
1362 colorbufferFormat != GL_RGB5_A1 &&
1363 colorbufferFormat != GL_RGBA8_OES)
1364 {
1365 return error(GL_INVALID_OPERATION);
1366 }
1367 break;
1368 case GL_LUMINANCE_ALPHA:
1369 case GL_RGBA:
1370 if (colorbufferFormat != GL_RGBA &&
1371 colorbufferFormat != GL_RGBA4 &&
1372 colorbufferFormat != GL_RGB5_A1 &&
1373 colorbufferFormat != GL_RGBA8_OES)
1374 {
1375 return error(GL_INVALID_OPERATION);
1376 }
1377 break;
1378 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1379 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001380 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1381 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001382 return error(GL_INVALID_OPERATION);
1383 default:
1384 return error(GL_INVALID_OPERATION);
1385 }
1386
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001387 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001388 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001389 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001390
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001391 catch(std::bad_alloc&)
1392 {
1393 return error(GL_OUT_OF_MEMORY);
1394 }
1395}
1396
1397GLuint __stdcall glCreateProgram(void)
1398{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001399 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001400
1401 try
1402 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001403 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001404
1405 if (context)
1406 {
1407 return context->createProgram();
1408 }
1409 }
1410 catch(std::bad_alloc&)
1411 {
1412 return error(GL_OUT_OF_MEMORY, 0);
1413 }
1414
1415 return 0;
1416}
1417
1418GLuint __stdcall glCreateShader(GLenum type)
1419{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001420 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001421
1422 try
1423 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001424 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001425
1426 if (context)
1427 {
1428 switch (type)
1429 {
1430 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001431 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001432 return context->createShader(type);
1433 default:
1434 return error(GL_INVALID_ENUM, 0);
1435 }
1436 }
1437 }
1438 catch(std::bad_alloc&)
1439 {
1440 return error(GL_OUT_OF_MEMORY, 0);
1441 }
1442
1443 return 0;
1444}
1445
1446void __stdcall glCullFace(GLenum mode)
1447{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001448 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001449
1450 try
1451 {
1452 switch (mode)
1453 {
1454 case GL_FRONT:
1455 case GL_BACK:
1456 case GL_FRONT_AND_BACK:
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 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001462 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001463 }
1464 }
1465 break;
1466 default:
1467 return error(GL_INVALID_ENUM);
1468 }
1469 }
1470 catch(std::bad_alloc&)
1471 {
1472 return error(GL_OUT_OF_MEMORY);
1473 }
1474}
1475
1476void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1477{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001478 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001479
1480 try
1481 {
1482 if (n < 0)
1483 {
1484 return error(GL_INVALID_VALUE);
1485 }
1486
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001487 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001488
1489 if (context)
1490 {
1491 for (int i = 0; i < n; i++)
1492 {
1493 context->deleteBuffer(buffers[i]);
1494 }
1495 }
1496 }
1497 catch(std::bad_alloc&)
1498 {
1499 return error(GL_OUT_OF_MEMORY);
1500 }
1501}
1502
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001503void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1504{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001505 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001506
1507 try
1508 {
1509 if (n < 0)
1510 {
1511 return error(GL_INVALID_VALUE);
1512 }
1513
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001514 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001515
1516 if (context)
1517 {
1518 for (int i = 0; i < n; i++)
1519 {
1520 context->deleteFence(fences[i]);
1521 }
1522 }
1523 }
1524 catch(std::bad_alloc&)
1525 {
1526 return error(GL_OUT_OF_MEMORY);
1527 }
1528}
1529
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001530void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1531{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001532 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001533
1534 try
1535 {
1536 if (n < 0)
1537 {
1538 return error(GL_INVALID_VALUE);
1539 }
1540
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001541 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001542
1543 if (context)
1544 {
1545 for (int i = 0; i < n; i++)
1546 {
1547 if (framebuffers[i] != 0)
1548 {
1549 context->deleteFramebuffer(framebuffers[i]);
1550 }
1551 }
1552 }
1553 }
1554 catch(std::bad_alloc&)
1555 {
1556 return error(GL_OUT_OF_MEMORY);
1557 }
1558}
1559
1560void __stdcall glDeleteProgram(GLuint program)
1561{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001562 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001563
1564 try
1565 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001566 if (program == 0)
1567 {
1568 return;
1569 }
1570
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001571 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001572
1573 if (context)
1574 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001575 if (!context->getProgram(program))
1576 {
1577 if(context->getShader(program))
1578 {
1579 return error(GL_INVALID_OPERATION);
1580 }
1581 else
1582 {
1583 return error(GL_INVALID_VALUE);
1584 }
1585 }
1586
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001587 context->deleteProgram(program);
1588 }
1589 }
1590 catch(std::bad_alloc&)
1591 {
1592 return error(GL_OUT_OF_MEMORY);
1593 }
1594}
1595
1596void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1597{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001598 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001599
1600 try
1601 {
1602 if (n < 0)
1603 {
1604 return error(GL_INVALID_VALUE);
1605 }
1606
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001607 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001608
1609 if (context)
1610 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001611 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001612 {
1613 context->deleteRenderbuffer(renderbuffers[i]);
1614 }
1615 }
1616 }
1617 catch(std::bad_alloc&)
1618 {
1619 return error(GL_OUT_OF_MEMORY);
1620 }
1621}
1622
1623void __stdcall glDeleteShader(GLuint shader)
1624{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001625 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001626
1627 try
1628 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001629 if (shader == 0)
1630 {
1631 return;
1632 }
1633
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001634 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001635
1636 if (context)
1637 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001638 if (!context->getShader(shader))
1639 {
1640 if(context->getProgram(shader))
1641 {
1642 return error(GL_INVALID_OPERATION);
1643 }
1644 else
1645 {
1646 return error(GL_INVALID_VALUE);
1647 }
1648 }
1649
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001650 context->deleteShader(shader);
1651 }
1652 }
1653 catch(std::bad_alloc&)
1654 {
1655 return error(GL_OUT_OF_MEMORY);
1656 }
1657}
1658
1659void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1660{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001661 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001662
1663 try
1664 {
1665 if (n < 0)
1666 {
1667 return error(GL_INVALID_VALUE);
1668 }
1669
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001670 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001671
1672 if (context)
1673 {
1674 for (int i = 0; i < n; i++)
1675 {
1676 if (textures[i] != 0)
1677 {
1678 context->deleteTexture(textures[i]);
1679 }
1680 }
1681 }
1682 }
1683 catch(std::bad_alloc&)
1684 {
1685 return error(GL_OUT_OF_MEMORY);
1686 }
1687}
1688
1689void __stdcall glDepthFunc(GLenum func)
1690{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001691 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001692
1693 try
1694 {
1695 switch (func)
1696 {
1697 case GL_NEVER:
1698 case GL_ALWAYS:
1699 case GL_LESS:
1700 case GL_LEQUAL:
1701 case GL_EQUAL:
1702 case GL_GREATER:
1703 case GL_GEQUAL:
1704 case GL_NOTEQUAL:
1705 break;
1706 default:
1707 return error(GL_INVALID_ENUM);
1708 }
1709
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001710 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001711
1712 if (context)
1713 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001714 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001715 }
1716 }
1717 catch(std::bad_alloc&)
1718 {
1719 return error(GL_OUT_OF_MEMORY);
1720 }
1721}
1722
1723void __stdcall glDepthMask(GLboolean flag)
1724{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001725 EVENT("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001726
1727 try
1728 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001729 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001730
1731 if (context)
1732 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001733 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001734 }
1735 }
1736 catch(std::bad_alloc&)
1737 {
1738 return error(GL_OUT_OF_MEMORY);
1739 }
1740}
1741
1742void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1743{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001744 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001745
1746 try
1747 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001748 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001749
1750 if (context)
1751 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001752 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001753 }
1754 }
1755 catch(std::bad_alloc&)
1756 {
1757 return error(GL_OUT_OF_MEMORY);
1758 }
1759}
1760
1761void __stdcall glDetachShader(GLuint program, GLuint shader)
1762{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001763 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001764
1765 try
1766 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001767 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001768
1769 if (context)
1770 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001771
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001772 gl::Program *programObject = context->getProgram(program);
1773 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001774
1775 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001776 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001777 gl::Shader *shaderByProgramHandle;
1778 shaderByProgramHandle = context->getShader(program);
1779 if (!shaderByProgramHandle)
1780 {
1781 return error(GL_INVALID_VALUE);
1782 }
1783 else
1784 {
1785 return error(GL_INVALID_OPERATION);
1786 }
1787 }
1788
1789 if (!shaderObject)
1790 {
1791 gl::Program *programByShaderHandle = context->getProgram(shader);
1792 if (!programByShaderHandle)
1793 {
1794 return error(GL_INVALID_VALUE);
1795 }
1796 else
1797 {
1798 return error(GL_INVALID_OPERATION);
1799 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001800 }
1801
1802 if (!programObject->detachShader(shaderObject))
1803 {
1804 return error(GL_INVALID_OPERATION);
1805 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001806 }
1807 }
1808 catch(std::bad_alloc&)
1809 {
1810 return error(GL_OUT_OF_MEMORY);
1811 }
1812}
1813
1814void __stdcall glDisable(GLenum cap)
1815{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001816 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001817
1818 try
1819 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001820 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001821
1822 if (context)
1823 {
1824 switch (cap)
1825 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001826 case GL_CULL_FACE: context->setCullFace(false); break;
1827 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1828 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1829 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1830 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1831 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1832 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1833 case GL_BLEND: context->setBlend(false); break;
1834 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001835 default:
1836 return error(GL_INVALID_ENUM);
1837 }
1838 }
1839 }
1840 catch(std::bad_alloc&)
1841 {
1842 return error(GL_OUT_OF_MEMORY);
1843 }
1844}
1845
1846void __stdcall glDisableVertexAttribArray(GLuint index)
1847{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001848 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001849
1850 try
1851 {
1852 if (index >= gl::MAX_VERTEX_ATTRIBS)
1853 {
1854 return error(GL_INVALID_VALUE);
1855 }
1856
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001857 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001858
1859 if (context)
1860 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001861 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001862 }
1863 }
1864 catch(std::bad_alloc&)
1865 {
1866 return error(GL_OUT_OF_MEMORY);
1867 }
1868}
1869
1870void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1871{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001872 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001873
1874 try
1875 {
1876 if (count < 0 || first < 0)
1877 {
1878 return error(GL_INVALID_VALUE);
1879 }
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 context->drawArrays(mode, first, count);
1886 }
1887 }
1888 catch(std::bad_alloc&)
1889 {
1890 return error(GL_OUT_OF_MEMORY);
1891 }
1892}
1893
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001894void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001895{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001896 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 +00001897 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001898
1899 try
1900 {
1901 if (count < 0)
1902 {
1903 return error(GL_INVALID_VALUE);
1904 }
1905
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001906 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001907
1908 if (context)
1909 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001910 switch (type)
1911 {
1912 case GL_UNSIGNED_BYTE:
1913 case GL_UNSIGNED_SHORT:
1914 break;
1915 case GL_UNSIGNED_INT:
1916 if (!context->supports32bitIndices())
1917 {
1918 return error(GL_INVALID_ENUM);
1919 }
1920 break;
1921 default:
1922 return error(GL_INVALID_ENUM);
1923 }
1924
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001925 context->drawElements(mode, count, type, indices);
1926 }
1927 }
1928 catch(std::bad_alloc&)
1929 {
1930 return error(GL_OUT_OF_MEMORY);
1931 }
1932}
1933
1934void __stdcall glEnable(GLenum cap)
1935{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001936 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001937
1938 try
1939 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001940 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001941
1942 if (context)
1943 {
1944 switch (cap)
1945 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001946 case GL_CULL_FACE: context->setCullFace(true); break;
1947 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1948 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1949 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1950 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1951 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1952 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1953 case GL_BLEND: context->setBlend(true); break;
1954 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001955 default:
1956 return error(GL_INVALID_ENUM);
1957 }
1958 }
1959 }
1960 catch(std::bad_alloc&)
1961 {
1962 return error(GL_OUT_OF_MEMORY);
1963 }
1964}
1965
1966void __stdcall glEnableVertexAttribArray(GLuint index)
1967{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001968 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001969
1970 try
1971 {
1972 if (index >= gl::MAX_VERTEX_ATTRIBS)
1973 {
1974 return error(GL_INVALID_VALUE);
1975 }
1976
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001977 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001978
1979 if (context)
1980 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001981 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001982 }
1983 }
1984 catch(std::bad_alloc&)
1985 {
1986 return error(GL_OUT_OF_MEMORY);
1987 }
1988}
1989
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001990void __stdcall glFinishFenceNV(GLuint fence)
1991{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001992 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001993
1994 try
1995 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001996 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001997
1998 if (context)
1999 {
2000 gl::Fence* fenceObject = context->getFence(fence);
2001
2002 if (fenceObject == NULL)
2003 {
2004 return error(GL_INVALID_OPERATION);
2005 }
2006
2007 fenceObject->finishFence();
2008 }
2009 }
2010 catch(std::bad_alloc&)
2011 {
2012 return error(GL_OUT_OF_MEMORY);
2013 }
2014}
2015
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002016void __stdcall glFinish(void)
2017{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002018 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002019
2020 try
2021 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002022 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002023
2024 if (context)
2025 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002026 context->sync(true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002027 }
2028 }
2029 catch(std::bad_alloc&)
2030 {
2031 return error(GL_OUT_OF_MEMORY);
2032 }
2033}
2034
2035void __stdcall glFlush(void)
2036{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002037 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002038
2039 try
2040 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002041 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002042
2043 if (context)
2044 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002045 context->sync(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002046 }
2047 }
2048 catch(std::bad_alloc&)
2049 {
2050 return error(GL_OUT_OF_MEMORY);
2051 }
2052}
2053
2054void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2055{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002056 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002057 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002058
2059 try
2060 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002061 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002062 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002063 {
2064 return error(GL_INVALID_ENUM);
2065 }
2066
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002067 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002068
2069 if (context)
2070 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002071 gl::Framebuffer *framebuffer = NULL;
2072 GLuint framebufferHandle = 0;
2073 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2074 {
2075 framebuffer = context->getReadFramebuffer();
2076 framebufferHandle = context->getReadFramebufferHandle();
2077 }
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002078 else
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002079 {
2080 framebuffer = context->getDrawFramebuffer();
2081 framebufferHandle = context->getDrawFramebufferHandle();
2082 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002083
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002084 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002085 {
2086 return error(GL_INVALID_OPERATION);
2087 }
2088
2089 switch (attachment)
2090 {
2091 case GL_COLOR_ATTACHMENT0:
2092 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2093 break;
2094 case GL_DEPTH_ATTACHMENT:
2095 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2096 break;
2097 case GL_STENCIL_ATTACHMENT:
2098 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2099 break;
2100 default:
2101 return error(GL_INVALID_ENUM);
2102 }
2103 }
2104 }
2105 catch(std::bad_alloc&)
2106 {
2107 return error(GL_OUT_OF_MEMORY);
2108 }
2109}
2110
2111void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2112{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002113 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002114 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002115
2116 try
2117 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002118 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002119 {
2120 return error(GL_INVALID_ENUM);
2121 }
2122
2123 switch (attachment)
2124 {
2125 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002126 case GL_DEPTH_ATTACHMENT:
2127 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002128 break;
2129 default:
2130 return error(GL_INVALID_ENUM);
2131 }
2132
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002133 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002134
2135 if (context)
2136 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002137 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002138 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002139 textarget = GL_NONE;
2140 }
2141 else
2142 {
2143 gl::Texture *tex = context->getTexture(texture);
2144
2145 if (tex == NULL)
2146 {
2147 return error(GL_INVALID_OPERATION);
2148 }
2149
daniel@transgaming.com01868132010-08-24 19:21:17 +00002150 if (tex->isCompressed())
2151 {
2152 return error(GL_INVALID_OPERATION);
2153 }
2154
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002155 switch (textarget)
2156 {
2157 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002158 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002159 {
2160 return error(GL_INVALID_OPERATION);
2161 }
2162 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002163
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002164 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002165 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002166 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002167 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002168 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002169 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002170 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2171 {
2172 return error(GL_INVALID_OPERATION);
2173 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002174 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002175
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002176 default:
2177 return error(GL_INVALID_ENUM);
2178 }
2179
2180 if (level != 0)
2181 {
2182 return error(GL_INVALID_VALUE);
2183 }
2184 }
2185
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002186 gl::Framebuffer *framebuffer = NULL;
2187 GLuint framebufferHandle = 0;
2188 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2189 {
2190 framebuffer = context->getReadFramebuffer();
2191 framebufferHandle = context->getReadFramebufferHandle();
2192 }
2193 else
2194 {
2195 framebuffer = context->getDrawFramebuffer();
2196 framebufferHandle = context->getDrawFramebufferHandle();
2197 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002198
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002199 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002200 {
2201 return error(GL_INVALID_OPERATION);
2202 }
2203
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002204 switch (attachment)
2205 {
2206 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2207 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2208 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2209 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002210 }
2211 }
2212 catch(std::bad_alloc&)
2213 {
2214 return error(GL_OUT_OF_MEMORY);
2215 }
2216}
2217
2218void __stdcall glFrontFace(GLenum mode)
2219{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002220 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002221
2222 try
2223 {
2224 switch (mode)
2225 {
2226 case GL_CW:
2227 case GL_CCW:
2228 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002229 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002230
2231 if (context)
2232 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002233 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002234 }
2235 }
2236 break;
2237 default:
2238 return error(GL_INVALID_ENUM);
2239 }
2240 }
2241 catch(std::bad_alloc&)
2242 {
2243 return error(GL_OUT_OF_MEMORY);
2244 }
2245}
2246
2247void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2248{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002249 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002250
2251 try
2252 {
2253 if (n < 0)
2254 {
2255 return error(GL_INVALID_VALUE);
2256 }
2257
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002258 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002259
2260 if (context)
2261 {
2262 for (int i = 0; i < n; i++)
2263 {
2264 buffers[i] = context->createBuffer();
2265 }
2266 }
2267 }
2268 catch(std::bad_alloc&)
2269 {
2270 return error(GL_OUT_OF_MEMORY);
2271 }
2272}
2273
2274void __stdcall glGenerateMipmap(GLenum target)
2275{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002276 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002277
2278 try
2279 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002280 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002281
2282 if (context)
2283 {
2284 gl::Texture *texture;
2285
2286 switch (target)
2287 {
2288 case GL_TEXTURE_2D:
2289 texture = context->getTexture2D();
2290 break;
2291
2292 case GL_TEXTURE_CUBE_MAP:
2293 texture = context->getTextureCubeMap();
2294 break;
2295
2296 default:
2297 return error(GL_INVALID_ENUM);
2298 }
2299
daniel@transgaming.com01868132010-08-24 19:21:17 +00002300 if (texture->isCompressed())
2301 {
2302 return error(GL_INVALID_OPERATION);
2303 }
2304
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002305 texture->generateMipmaps();
2306 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002307 }
2308 catch(std::bad_alloc&)
2309 {
2310 return error(GL_OUT_OF_MEMORY);
2311 }
2312}
2313
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002314void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2315{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002316 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002317
2318 try
2319 {
2320 if (n < 0)
2321 {
2322 return error(GL_INVALID_VALUE);
2323 }
2324
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002325 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002326
2327 if (context)
2328 {
2329 for (int i = 0; i < n; i++)
2330 {
2331 fences[i] = context->createFence();
2332 }
2333 }
2334 }
2335 catch(std::bad_alloc&)
2336 {
2337 return error(GL_OUT_OF_MEMORY);
2338 }
2339}
2340
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002341void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2342{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002343 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002344
2345 try
2346 {
2347 if (n < 0)
2348 {
2349 return error(GL_INVALID_VALUE);
2350 }
2351
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002352 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002353
2354 if (context)
2355 {
2356 for (int i = 0; i < n; i++)
2357 {
2358 framebuffers[i] = context->createFramebuffer();
2359 }
2360 }
2361 }
2362 catch(std::bad_alloc&)
2363 {
2364 return error(GL_OUT_OF_MEMORY);
2365 }
2366}
2367
2368void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2369{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002370 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002371
2372 try
2373 {
2374 if (n < 0)
2375 {
2376 return error(GL_INVALID_VALUE);
2377 }
2378
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002379 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002380
2381 if (context)
2382 {
2383 for (int i = 0; i < n; i++)
2384 {
2385 renderbuffers[i] = context->createRenderbuffer();
2386 }
2387 }
2388 }
2389 catch(std::bad_alloc&)
2390 {
2391 return error(GL_OUT_OF_MEMORY);
2392 }
2393}
2394
2395void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2396{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002397 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002398
2399 try
2400 {
2401 if (n < 0)
2402 {
2403 return error(GL_INVALID_VALUE);
2404 }
2405
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002406 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002407
2408 if (context)
2409 {
2410 for (int i = 0; i < n; i++)
2411 {
2412 textures[i] = context->createTexture();
2413 }
2414 }
2415 }
2416 catch(std::bad_alloc&)
2417 {
2418 return error(GL_OUT_OF_MEMORY);
2419 }
2420}
2421
daniel@transgaming.com85423182010-04-22 13:35:27 +00002422void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002423{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002424 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002425 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002426 program, index, bufsize, length, size, type, name);
2427
2428 try
2429 {
2430 if (bufsize < 0)
2431 {
2432 return error(GL_INVALID_VALUE);
2433 }
2434
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002435 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com85423182010-04-22 13:35:27 +00002436
2437 if (context)
2438 {
2439 gl::Program *programObject = context->getProgram(program);
2440
2441 if (!programObject)
2442 {
2443 if (context->getShader(program))
2444 {
2445 return error(GL_INVALID_OPERATION);
2446 }
2447 else
2448 {
2449 return error(GL_INVALID_VALUE);
2450 }
2451 }
2452
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002453 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002454 {
2455 return error(GL_INVALID_VALUE);
2456 }
2457
2458 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
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
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002467void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002468{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002469 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002470 "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 +00002471 program, index, bufsize, length, size, type, name);
2472
2473 try
2474 {
2475 if (bufsize < 0)
2476 {
2477 return error(GL_INVALID_VALUE);
2478 }
2479
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002480 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002481
2482 if (context)
2483 {
2484 gl::Program *programObject = context->getProgram(program);
2485
2486 if (!programObject)
2487 {
2488 if (context->getShader(program))
2489 {
2490 return error(GL_INVALID_OPERATION);
2491 }
2492 else
2493 {
2494 return error(GL_INVALID_VALUE);
2495 }
2496 }
2497
2498 if (index >= (GLuint)programObject->getActiveUniformCount())
2499 {
2500 return error(GL_INVALID_VALUE);
2501 }
2502
2503 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2504 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002505 }
2506 catch(std::bad_alloc&)
2507 {
2508 return error(GL_OUT_OF_MEMORY);
2509 }
2510}
2511
2512void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2513{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002514 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 +00002515 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002516
2517 try
2518 {
2519 if (maxcount < 0)
2520 {
2521 return error(GL_INVALID_VALUE);
2522 }
2523
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002524 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002525
2526 if (context)
2527 {
2528 gl::Program *programObject = context->getProgram(program);
2529
2530 if (!programObject)
2531 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002532 if (context->getShader(program))
2533 {
2534 return error(GL_INVALID_OPERATION);
2535 }
2536 else
2537 {
2538 return error(GL_INVALID_VALUE);
2539 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002540 }
2541
2542 return programObject->getAttachedShaders(maxcount, count, shaders);
2543 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002544 }
2545 catch(std::bad_alloc&)
2546 {
2547 return error(GL_OUT_OF_MEMORY);
2548 }
2549}
2550
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002551int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002552{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002553 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002554
2555 try
2556 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002557 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002558
2559 if (context)
2560 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002561
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002562 gl::Program *programObject = context->getProgram(program);
2563
2564 if (!programObject)
2565 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002566 if (context->getShader(program))
2567 {
2568 return error(GL_INVALID_OPERATION, -1);
2569 }
2570 else
2571 {
2572 return error(GL_INVALID_VALUE, -1);
2573 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002574 }
2575
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002576 if (!programObject->isLinked())
2577 {
2578 return error(GL_INVALID_OPERATION, -1);
2579 }
2580
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002581 return programObject->getAttributeLocation(name);
2582 }
2583 }
2584 catch(std::bad_alloc&)
2585 {
2586 return error(GL_OUT_OF_MEMORY, -1);
2587 }
2588
2589 return -1;
2590}
2591
2592void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2593{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002594 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002595
2596 try
2597 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002598 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002599
2600 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002601 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002602 if (!(context->getBooleanv(pname, params)))
2603 {
2604 GLenum nativeType;
2605 unsigned int numParams = 0;
2606 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2607 return error(GL_INVALID_ENUM);
2608
2609 if (numParams == 0)
2610 return; // it is known that the pname is valid, but there are no parameters to return
2611
2612 if (nativeType == GL_FLOAT)
2613 {
2614 GLfloat *floatParams = NULL;
2615 floatParams = new GLfloat[numParams];
2616
2617 context->getFloatv(pname, floatParams);
2618
2619 for (unsigned int i = 0; i < numParams; ++i)
2620 {
2621 if (floatParams[i] == 0.0f)
2622 params[i] = GL_FALSE;
2623 else
2624 params[i] = GL_TRUE;
2625 }
2626
2627 delete [] floatParams;
2628 }
2629 else if (nativeType == GL_INT)
2630 {
2631 GLint *intParams = NULL;
2632 intParams = new GLint[numParams];
2633
2634 context->getIntegerv(pname, intParams);
2635
2636 for (unsigned int i = 0; i < numParams; ++i)
2637 {
2638 if (intParams[i] == 0)
2639 params[i] = GL_FALSE;
2640 else
2641 params[i] = GL_TRUE;
2642 }
2643
2644 delete [] intParams;
2645 }
2646 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002647 }
2648 }
2649 catch(std::bad_alloc&)
2650 {
2651 return error(GL_OUT_OF_MEMORY);
2652 }
2653}
2654
2655void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2656{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002657 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 +00002658
2659 try
2660 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002661 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002662
2663 if (context)
2664 {
2665 gl::Buffer *buffer;
2666
2667 switch (target)
2668 {
2669 case GL_ARRAY_BUFFER:
2670 buffer = context->getArrayBuffer();
2671 break;
2672 case GL_ELEMENT_ARRAY_BUFFER:
2673 buffer = context->getElementArrayBuffer();
2674 break;
2675 default: return error(GL_INVALID_ENUM);
2676 }
2677
2678 if (!buffer)
2679 {
2680 // A null buffer means that "0" is bound to the requested buffer target
2681 return error(GL_INVALID_OPERATION);
2682 }
2683
2684 switch (pname)
2685 {
2686 case GL_BUFFER_USAGE:
2687 *params = buffer->usage();
2688 break;
2689 case GL_BUFFER_SIZE:
2690 *params = buffer->size();
2691 break;
2692 default: return error(GL_INVALID_ENUM);
2693 }
2694 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002695 }
2696 catch(std::bad_alloc&)
2697 {
2698 return error(GL_OUT_OF_MEMORY);
2699 }
2700}
2701
2702GLenum __stdcall glGetError(void)
2703{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002704 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002705
2706 gl::Context *context = gl::getContext();
2707
2708 if (context)
2709 {
daniel@transgaming.com82b28912011-12-12 21:01:35 +00002710 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002711 }
2712
2713 return GL_NO_ERROR;
2714}
2715
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002716void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2717{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002718 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002719
2720 try
2721 {
2722
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002723 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002724
2725 if (context)
2726 {
2727 gl::Fence *fenceObject = context->getFence(fence);
2728
2729 if (fenceObject == NULL)
2730 {
2731 return error(GL_INVALID_OPERATION);
2732 }
2733
2734 fenceObject->getFenceiv(pname, params);
2735 }
2736 }
2737 catch(std::bad_alloc&)
2738 {
2739 return error(GL_OUT_OF_MEMORY);
2740 }
2741}
2742
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002743void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2744{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002745 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002746
2747 try
2748 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002749 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002750
2751 if (context)
2752 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002753 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002754 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002755 GLenum nativeType;
2756 unsigned int numParams = 0;
2757 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2758 return error(GL_INVALID_ENUM);
2759
2760 if (numParams == 0)
2761 return; // it is known that the pname is valid, but that there are no parameters to return.
2762
2763 if (nativeType == GL_BOOL)
2764 {
2765 GLboolean *boolParams = NULL;
2766 boolParams = new GLboolean[numParams];
2767
2768 context->getBooleanv(pname, boolParams);
2769
2770 for (unsigned int i = 0; i < numParams; ++i)
2771 {
2772 if (boolParams[i] == GL_FALSE)
2773 params[i] = 0.0f;
2774 else
2775 params[i] = 1.0f;
2776 }
2777
2778 delete [] boolParams;
2779 }
2780 else if (nativeType == GL_INT)
2781 {
2782 GLint *intParams = NULL;
2783 intParams = new GLint[numParams];
2784
2785 context->getIntegerv(pname, intParams);
2786
2787 for (unsigned int i = 0; i < numParams; ++i)
2788 {
2789 params[i] = (GLfloat)intParams[i];
2790 }
2791
2792 delete [] intParams;
2793 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002794 }
2795 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002796 }
2797 catch(std::bad_alloc&)
2798 {
2799 return error(GL_OUT_OF_MEMORY);
2800 }
2801}
2802
2803void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2804{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002805 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 +00002806 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002807
2808 try
2809 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002810 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002811
2812 if (context)
2813 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002814 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002815 {
2816 return error(GL_INVALID_ENUM);
2817 }
2818
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002819 gl::Framebuffer *framebuffer = NULL;
2820 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2821 {
2822 if(context->getReadFramebufferHandle() == 0)
2823 {
2824 return error(GL_INVALID_OPERATION);
2825 }
2826
2827 framebuffer = context->getReadFramebuffer();
2828 }
2829 else
2830 {
2831 if (context->getDrawFramebufferHandle() == 0)
2832 {
2833 return error(GL_INVALID_OPERATION);
2834 }
2835
2836 framebuffer = context->getDrawFramebuffer();
2837 }
2838
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002839 GLenum attachmentType;
2840 GLuint attachmentHandle;
2841 switch (attachment)
2842 {
2843 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002844 attachmentType = framebuffer->getColorbufferType();
2845 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002846 break;
2847 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002848 attachmentType = framebuffer->getDepthbufferType();
2849 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002850 break;
2851 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002852 attachmentType = framebuffer->getStencilbufferType();
2853 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002854 break;
2855 default: return error(GL_INVALID_ENUM);
2856 }
2857
2858 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002859 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002860 {
2861 attachmentObjectType = attachmentType;
2862 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002863 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002864 {
2865 attachmentObjectType = GL_TEXTURE;
2866 }
2867 else UNREACHABLE();
2868
2869 switch (pname)
2870 {
2871 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2872 *params = attachmentObjectType;
2873 break;
2874 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2875 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2876 {
2877 *params = attachmentHandle;
2878 }
2879 else
2880 {
2881 return error(GL_INVALID_ENUM);
2882 }
2883 break;
2884 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2885 if (attachmentObjectType == GL_TEXTURE)
2886 {
2887 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2888 }
2889 else
2890 {
2891 return error(GL_INVALID_ENUM);
2892 }
2893 break;
2894 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2895 if (attachmentObjectType == GL_TEXTURE)
2896 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002897 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002898 {
2899 *params = attachmentType;
2900 }
2901 else
2902 {
2903 *params = 0;
2904 }
2905 }
2906 else
2907 {
2908 return error(GL_INVALID_ENUM);
2909 }
2910 break;
2911 default:
2912 return error(GL_INVALID_ENUM);
2913 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002914 }
2915 }
2916 catch(std::bad_alloc&)
2917 {
2918 return error(GL_OUT_OF_MEMORY);
2919 }
2920}
2921
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00002922GLenum __stdcall glGetGraphicsResetStatusEXT(void)
2923{
2924 EVENT("()");
2925
2926 try
2927 {
2928 gl::Context *context = gl::getContext();
2929
2930 if (context)
2931 {
2932 return context->getResetStatus();
2933 }
2934
2935 return GL_NO_ERROR;
2936 }
2937 catch(std::bad_alloc&)
2938 {
2939 return GL_OUT_OF_MEMORY;
2940 }
2941}
2942
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002943void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2944{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002945 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002946
2947 try
2948 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002949 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002950
2951 if (context)
2952 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002953 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002954 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002955 GLenum nativeType;
2956 unsigned int numParams = 0;
2957 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2958 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002959
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002960 if (numParams == 0)
2961 return; // it is known that pname is valid, but there are no parameters to return
2962
2963 if (nativeType == GL_BOOL)
2964 {
2965 GLboolean *boolParams = NULL;
2966 boolParams = new GLboolean[numParams];
2967
2968 context->getBooleanv(pname, boolParams);
2969
2970 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002971 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002972 if (boolParams[i] == GL_FALSE)
2973 params[i] = 0;
2974 else
2975 params[i] = 1;
2976 }
2977
2978 delete [] boolParams;
2979 }
2980 else if (nativeType == GL_FLOAT)
2981 {
2982 GLfloat *floatParams = NULL;
2983 floatParams = new GLfloat[numParams];
2984
2985 context->getFloatv(pname, floatParams);
2986
2987 for (unsigned int i = 0; i < numParams; ++i)
2988 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002989 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 +00002990 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002991 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002992 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002993 else
2994 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 +00002995 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002996
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002997 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002998 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002999 }
3000 }
3001 }
3002 catch(std::bad_alloc&)
3003 {
3004 return error(GL_OUT_OF_MEMORY);
3005 }
3006}
3007
3008void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3009{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003010 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003011
3012 try
3013 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003014 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003015
3016 if (context)
3017 {
3018 gl::Program *programObject = context->getProgram(program);
3019
3020 if (!programObject)
3021 {
3022 return error(GL_INVALID_VALUE);
3023 }
3024
3025 switch (pname)
3026 {
3027 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003028 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003029 return;
3030 case GL_LINK_STATUS:
3031 *params = programObject->isLinked();
3032 return;
3033 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003034 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003035 return;
3036 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003037 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003038 return;
3039 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003040 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003041 return;
3042 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003043 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003044 return;
3045 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003046 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003047 return;
3048 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003049 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003050 return;
3051 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003052 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003053 return;
3054 default:
3055 return error(GL_INVALID_ENUM);
3056 }
3057 }
3058 }
3059 catch(std::bad_alloc&)
3060 {
3061 return error(GL_OUT_OF_MEMORY);
3062 }
3063}
3064
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003065void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003066{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003067 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 +00003068 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003069
3070 try
3071 {
3072 if (bufsize < 0)
3073 {
3074 return error(GL_INVALID_VALUE);
3075 }
3076
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003077 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003078
3079 if (context)
3080 {
3081 gl::Program *programObject = context->getProgram(program);
3082
3083 if (!programObject)
3084 {
3085 return error(GL_INVALID_VALUE);
3086 }
3087
3088 programObject->getInfoLog(bufsize, length, infolog);
3089 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003090 }
3091 catch(std::bad_alloc&)
3092 {
3093 return error(GL_OUT_OF_MEMORY);
3094 }
3095}
3096
3097void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3098{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003099 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 +00003100
3101 try
3102 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003103 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003104
3105 if (context)
3106 {
3107 if (target != GL_RENDERBUFFER)
3108 {
3109 return error(GL_INVALID_ENUM);
3110 }
3111
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003112 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003113 {
3114 return error(GL_INVALID_OPERATION);
3115 }
3116
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003117 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003118
3119 switch (pname)
3120 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003121 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3122 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3123 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3124 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3125 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3126 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3127 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3128 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3129 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003130 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003131 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003132 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003133 *params = renderbuffer->getSamples();
3134 }
3135 else
3136 {
3137 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003138 }
3139 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003140 default:
3141 return error(GL_INVALID_ENUM);
3142 }
3143 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003144 }
3145 catch(std::bad_alloc&)
3146 {
3147 return error(GL_OUT_OF_MEMORY);
3148 }
3149}
3150
3151void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3152{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003153 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003154
3155 try
3156 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003157 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003158
3159 if (context)
3160 {
3161 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003162
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003163 if (!shaderObject)
3164 {
3165 return error(GL_INVALID_VALUE);
3166 }
3167
3168 switch (pname)
3169 {
3170 case GL_SHADER_TYPE:
3171 *params = shaderObject->getType();
3172 return;
3173 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003174 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003175 return;
3176 case GL_COMPILE_STATUS:
3177 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3178 return;
3179 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003180 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003181 return;
3182 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003183 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003184 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003185 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3186 *params = shaderObject->getTranslatedSourceLength();
3187 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003188 default:
3189 return error(GL_INVALID_ENUM);
3190 }
3191 }
3192 }
3193 catch(std::bad_alloc&)
3194 {
3195 return error(GL_OUT_OF_MEMORY);
3196 }
3197}
3198
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003199void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003200{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003201 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 +00003202 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003203
3204 try
3205 {
3206 if (bufsize < 0)
3207 {
3208 return error(GL_INVALID_VALUE);
3209 }
3210
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003211 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003212
3213 if (context)
3214 {
3215 gl::Shader *shaderObject = context->getShader(shader);
3216
3217 if (!shaderObject)
3218 {
3219 return error(GL_INVALID_VALUE);
3220 }
3221
3222 shaderObject->getInfoLog(bufsize, length, infolog);
3223 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003224 }
3225 catch(std::bad_alloc&)
3226 {
3227 return error(GL_OUT_OF_MEMORY);
3228 }
3229}
3230
3231void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3232{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003233 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 +00003234 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003235
3236 try
3237 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003238 switch (shadertype)
3239 {
3240 case GL_VERTEX_SHADER:
3241 case GL_FRAGMENT_SHADER:
3242 break;
3243 default:
3244 return error(GL_INVALID_ENUM);
3245 }
3246
3247 switch (precisiontype)
3248 {
3249 case GL_LOW_FLOAT:
3250 case GL_MEDIUM_FLOAT:
3251 case GL_HIGH_FLOAT:
3252 // Assume IEEE 754 precision
3253 range[0] = 127;
3254 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003255 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003256 break;
3257 case GL_LOW_INT:
3258 case GL_MEDIUM_INT:
3259 case GL_HIGH_INT:
3260 // Some (most) hardware only supports single-precision floating-point numbers,
3261 // which can accurately represent integers up to +/-16777216
3262 range[0] = 24;
3263 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003264 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003265 break;
3266 default:
3267 return error(GL_INVALID_ENUM);
3268 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003269 }
3270 catch(std::bad_alloc&)
3271 {
3272 return error(GL_OUT_OF_MEMORY);
3273 }
3274}
3275
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003276void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003277{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003278 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 +00003279 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003280
3281 try
3282 {
3283 if (bufsize < 0)
3284 {
3285 return error(GL_INVALID_VALUE);
3286 }
3287
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003288 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003289
3290 if (context)
3291 {
3292 gl::Shader *shaderObject = context->getShader(shader);
3293
3294 if (!shaderObject)
3295 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003296 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003297 }
3298
3299 shaderObject->getSource(bufsize, length, source);
3300 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003301 }
3302 catch(std::bad_alloc&)
3303 {
3304 return error(GL_OUT_OF_MEMORY);
3305 }
3306}
3307
zmo@google.coma574f782011-10-03 21:45:23 +00003308void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3309{
3310 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3311 shader, bufsize, length, source);
3312
3313 try
3314 {
3315 if (bufsize < 0)
3316 {
3317 return error(GL_INVALID_VALUE);
3318 }
3319
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003320 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003321
3322 if (context)
3323 {
3324 gl::Shader *shaderObject = context->getShader(shader);
3325
3326 if (!shaderObject)
3327 {
3328 return error(GL_INVALID_OPERATION);
3329 }
3330
3331 shaderObject->getTranslatedSource(bufsize, length, source);
3332 }
3333 }
3334 catch(std::bad_alloc&)
3335 {
3336 return error(GL_OUT_OF_MEMORY);
3337 }
3338}
3339
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003340const GLubyte* __stdcall glGetString(GLenum name)
3341{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003342 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003343
3344 try
3345 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003346 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003347
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003348 switch (name)
3349 {
3350 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003351 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003352 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003353 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003354 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003355 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003356 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003357 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003358 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003359 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003360 default:
3361 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3362 }
3363 }
3364 catch(std::bad_alloc&)
3365 {
3366 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3367 }
3368
3369 return NULL;
3370}
3371
3372void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3373{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003374 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 +00003375
3376 try
3377 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003378 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003379
3380 if (context)
3381 {
3382 gl::Texture *texture;
3383
3384 switch (target)
3385 {
3386 case GL_TEXTURE_2D:
3387 texture = context->getTexture2D();
3388 break;
3389 case GL_TEXTURE_CUBE_MAP:
3390 texture = context->getTextureCubeMap();
3391 break;
3392 default:
3393 return error(GL_INVALID_ENUM);
3394 }
3395
3396 switch (pname)
3397 {
3398 case GL_TEXTURE_MAG_FILTER:
3399 *params = (GLfloat)texture->getMagFilter();
3400 break;
3401 case GL_TEXTURE_MIN_FILTER:
3402 *params = (GLfloat)texture->getMinFilter();
3403 break;
3404 case GL_TEXTURE_WRAP_S:
3405 *params = (GLfloat)texture->getWrapS();
3406 break;
3407 case GL_TEXTURE_WRAP_T:
3408 *params = (GLfloat)texture->getWrapT();
3409 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003410 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3411 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3412 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003413 case GL_TEXTURE_USAGE_ANGLE:
3414 *params = (GLfloat)texture->getUsage();
3415 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003416 default:
3417 return error(GL_INVALID_ENUM);
3418 }
3419 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003420 }
3421 catch(std::bad_alloc&)
3422 {
3423 return error(GL_OUT_OF_MEMORY);
3424 }
3425}
3426
3427void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3428{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003429 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 +00003430
3431 try
3432 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003433 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003434
3435 if (context)
3436 {
3437 gl::Texture *texture;
3438
3439 switch (target)
3440 {
3441 case GL_TEXTURE_2D:
3442 texture = context->getTexture2D();
3443 break;
3444 case GL_TEXTURE_CUBE_MAP:
3445 texture = context->getTextureCubeMap();
3446 break;
3447 default:
3448 return error(GL_INVALID_ENUM);
3449 }
3450
3451 switch (pname)
3452 {
3453 case GL_TEXTURE_MAG_FILTER:
3454 *params = texture->getMagFilter();
3455 break;
3456 case GL_TEXTURE_MIN_FILTER:
3457 *params = texture->getMinFilter();
3458 break;
3459 case GL_TEXTURE_WRAP_S:
3460 *params = texture->getWrapS();
3461 break;
3462 case GL_TEXTURE_WRAP_T:
3463 *params = texture->getWrapT();
3464 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003465 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3466 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3467 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003468 case GL_TEXTURE_USAGE_ANGLE:
3469 *params = texture->getUsage();
3470 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003471 default:
3472 return error(GL_INVALID_ENUM);
3473 }
3474 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003475 }
3476 catch(std::bad_alloc&)
3477 {
3478 return error(GL_OUT_OF_MEMORY);
3479 }
3480}
3481
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003482void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3483{
3484 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3485 program, location, bufSize, params);
3486
3487 try
3488 {
3489 if (bufSize < 0)
3490 {
3491 return error(GL_INVALID_VALUE);
3492 }
3493
3494 gl::Context *context = gl::getNonLostContext();
3495
3496 if (context)
3497 {
3498 if (program == 0)
3499 {
3500 return error(GL_INVALID_VALUE);
3501 }
3502
3503 gl::Program *programObject = context->getProgram(program);
3504
3505 if (!programObject || !programObject->isLinked())
3506 {
3507 return error(GL_INVALID_OPERATION);
3508 }
3509
3510 if (!programObject->getUniformfv(location, &bufSize, params))
3511 {
3512 return error(GL_INVALID_OPERATION);
3513 }
3514 }
3515 }
3516 catch(std::bad_alloc&)
3517 {
3518 return error(GL_OUT_OF_MEMORY);
3519 }
3520}
3521
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003522void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3523{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003524 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003525
3526 try
3527 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003528 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003529
3530 if (context)
3531 {
3532 if (program == 0)
3533 {
3534 return error(GL_INVALID_VALUE);
3535 }
3536
3537 gl::Program *programObject = context->getProgram(program);
3538
3539 if (!programObject || !programObject->isLinked())
3540 {
3541 return error(GL_INVALID_OPERATION);
3542 }
3543
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003544 if (!programObject->getUniformfv(location, NULL, params))
3545 {
3546 return error(GL_INVALID_OPERATION);
3547 }
3548 }
3549 }
3550 catch(std::bad_alloc&)
3551 {
3552 return error(GL_OUT_OF_MEMORY);
3553 }
3554}
3555
3556void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3557{
3558 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3559 program, location, bufSize, params);
3560
3561 try
3562 {
3563 if (bufSize < 0)
3564 {
3565 return error(GL_INVALID_VALUE);
3566 }
3567
3568 gl::Context *context = gl::getNonLostContext();
3569
3570 if (context)
3571 {
3572 if (program == 0)
3573 {
3574 return error(GL_INVALID_VALUE);
3575 }
3576
3577 gl::Program *programObject = context->getProgram(program);
3578
3579 if (!programObject || !programObject->isLinked())
3580 {
3581 return error(GL_INVALID_OPERATION);
3582 }
3583
3584 if (!programObject)
3585 {
3586 return error(GL_INVALID_OPERATION);
3587 }
3588
3589 if (!programObject->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003590 {
3591 return error(GL_INVALID_OPERATION);
3592 }
3593 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003594 }
3595 catch(std::bad_alloc&)
3596 {
3597 return error(GL_OUT_OF_MEMORY);
3598 }
3599}
3600
3601void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3602{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003603 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
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.combb3d9d02010-04-13 03:26:06 +00003608
3609 if (context)
3610 {
3611 if (program == 0)
3612 {
3613 return error(GL_INVALID_VALUE);
3614 }
3615
3616 gl::Program *programObject = context->getProgram(program);
3617
3618 if (!programObject || !programObject->isLinked())
3619 {
3620 return error(GL_INVALID_OPERATION);
3621 }
3622
3623 if (!programObject)
3624 {
3625 return error(GL_INVALID_OPERATION);
3626 }
3627
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003628 if (!programObject->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003629 {
3630 return error(GL_INVALID_OPERATION);
3631 }
3632 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003633 }
3634 catch(std::bad_alloc&)
3635 {
3636 return error(GL_OUT_OF_MEMORY);
3637 }
3638}
3639
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003640int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003641{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003642 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003643
3644 try
3645 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003646 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003647
3648 if (strstr(name, "gl_") == name)
3649 {
3650 return -1;
3651 }
3652
3653 if (context)
3654 {
3655 gl::Program *programObject = context->getProgram(program);
3656
3657 if (!programObject)
3658 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003659 if (context->getShader(program))
3660 {
3661 return error(GL_INVALID_OPERATION, -1);
3662 }
3663 else
3664 {
3665 return error(GL_INVALID_VALUE, -1);
3666 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003667 }
3668
3669 if (!programObject->isLinked())
3670 {
3671 return error(GL_INVALID_OPERATION, -1);
3672 }
3673
daniel@transgaming.com024f1a92011-09-20 16:06:25 +00003674 return programObject->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003675 }
3676 }
3677 catch(std::bad_alloc&)
3678 {
3679 return error(GL_OUT_OF_MEMORY, -1);
3680 }
3681
3682 return -1;
3683}
3684
3685void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3686{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003687 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003688
3689 try
3690 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003691 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003692
daniel@transgaming.come0078962010-04-15 20:45:08 +00003693 if (context)
3694 {
3695 if (index >= gl::MAX_VERTEX_ATTRIBS)
3696 {
3697 return error(GL_INVALID_VALUE);
3698 }
3699
daniel@transgaming.com83921382011-01-08 05:46:00 +00003700 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003701
daniel@transgaming.come0078962010-04-15 20:45:08 +00003702 switch (pname)
3703 {
3704 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003705 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003706 break;
3707 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003708 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003709 break;
3710 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003711 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003712 break;
3713 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003714 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003715 break;
3716 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003717 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003718 break;
3719 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003720 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003721 break;
3722 case GL_CURRENT_VERTEX_ATTRIB:
3723 for (int i = 0; i < 4; ++i)
3724 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003725 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003726 }
3727 break;
3728 default: return error(GL_INVALID_ENUM);
3729 }
3730 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003731 }
3732 catch(std::bad_alloc&)
3733 {
3734 return error(GL_OUT_OF_MEMORY);
3735 }
3736}
3737
3738void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3739{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003740 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003741
3742 try
3743 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003744 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003745
daniel@transgaming.come0078962010-04-15 20:45:08 +00003746 if (context)
3747 {
3748 if (index >= gl::MAX_VERTEX_ATTRIBS)
3749 {
3750 return error(GL_INVALID_VALUE);
3751 }
3752
daniel@transgaming.com83921382011-01-08 05:46:00 +00003753 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003754
daniel@transgaming.come0078962010-04-15 20:45:08 +00003755 switch (pname)
3756 {
3757 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003758 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003759 break;
3760 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003761 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003762 break;
3763 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003764 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003765 break;
3766 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003767 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003768 break;
3769 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003770 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003771 break;
3772 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003773 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003774 break;
3775 case GL_CURRENT_VERTEX_ATTRIB:
3776 for (int i = 0; i < 4; ++i)
3777 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003778 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003779 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3780 }
3781 break;
3782 default: return error(GL_INVALID_ENUM);
3783 }
3784 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003785 }
3786 catch(std::bad_alloc&)
3787 {
3788 return error(GL_OUT_OF_MEMORY);
3789 }
3790}
3791
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003792void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003793{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003794 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003795
3796 try
3797 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003798 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003799
daniel@transgaming.come0078962010-04-15 20:45:08 +00003800 if (context)
3801 {
3802 if (index >= gl::MAX_VERTEX_ATTRIBS)
3803 {
3804 return error(GL_INVALID_VALUE);
3805 }
3806
3807 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3808 {
3809 return error(GL_INVALID_ENUM);
3810 }
3811
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003812 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003813 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003814 }
3815 catch(std::bad_alloc&)
3816 {
3817 return error(GL_OUT_OF_MEMORY);
3818 }
3819}
3820
3821void __stdcall glHint(GLenum target, GLenum mode)
3822{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003823 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003824
3825 try
3826 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003827 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003828 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003829 case GL_FASTEST:
3830 case GL_NICEST:
3831 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003832 break;
3833 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003834 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003835 }
3836
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003837 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003838 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003839 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003840 case GL_GENERATE_MIPMAP_HINT:
3841 if (context) context->setGenerateMipmapHint(mode);
3842 break;
3843 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3844 if (context) context->setFragmentShaderDerivativeHint(mode);
3845 break;
3846 default:
3847 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003848 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003849 }
3850 catch(std::bad_alloc&)
3851 {
3852 return error(GL_OUT_OF_MEMORY);
3853 }
3854}
3855
3856GLboolean __stdcall glIsBuffer(GLuint buffer)
3857{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003858 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003859
3860 try
3861 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003862 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003863
3864 if (context && buffer)
3865 {
3866 gl::Buffer *bufferObject = context->getBuffer(buffer);
3867
3868 if (bufferObject)
3869 {
3870 return GL_TRUE;
3871 }
3872 }
3873 }
3874 catch(std::bad_alloc&)
3875 {
3876 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3877 }
3878
3879 return GL_FALSE;
3880}
3881
3882GLboolean __stdcall glIsEnabled(GLenum cap)
3883{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003884 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003885
3886 try
3887 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003888 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003889
3890 if (context)
3891 {
3892 switch (cap)
3893 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003894 case GL_CULL_FACE: return context->isCullFaceEnabled();
3895 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3896 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3897 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3898 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3899 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3900 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3901 case GL_BLEND: return context->isBlendEnabled();
3902 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003903 default:
3904 return error(GL_INVALID_ENUM, false);
3905 }
3906 }
3907 }
3908 catch(std::bad_alloc&)
3909 {
3910 return error(GL_OUT_OF_MEMORY, false);
3911 }
3912
3913 return false;
3914}
3915
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003916GLboolean __stdcall glIsFenceNV(GLuint fence)
3917{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003918 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003919
3920 try
3921 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003922 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003923
3924 if (context)
3925 {
3926 gl::Fence *fenceObject = context->getFence(fence);
3927
3928 if (fenceObject == NULL)
3929 {
3930 return GL_FALSE;
3931 }
3932
3933 return fenceObject->isFence();
3934 }
3935 }
3936 catch(std::bad_alloc&)
3937 {
3938 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3939 }
3940
3941 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003942}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003943
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003944GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3945{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003946 EVENT("(GLuint framebuffer = %d)", framebuffer);
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
3952 if (context && framebuffer)
3953 {
3954 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3955
3956 if (framebufferObject)
3957 {
3958 return GL_TRUE;
3959 }
3960 }
3961 }
3962 catch(std::bad_alloc&)
3963 {
3964 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3965 }
3966
3967 return GL_FALSE;
3968}
3969
3970GLboolean __stdcall glIsProgram(GLuint program)
3971{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003972 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003973
3974 try
3975 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003976 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003977
3978 if (context && program)
3979 {
3980 gl::Program *programObject = context->getProgram(program);
3981
3982 if (programObject)
3983 {
3984 return GL_TRUE;
3985 }
3986 }
3987 }
3988 catch(std::bad_alloc&)
3989 {
3990 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3991 }
3992
3993 return GL_FALSE;
3994}
3995
3996GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3997{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003998 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003999
4000 try
4001 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004002 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004003
4004 if (context && renderbuffer)
4005 {
4006 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4007
4008 if (renderbufferObject)
4009 {
4010 return GL_TRUE;
4011 }
4012 }
4013 }
4014 catch(std::bad_alloc&)
4015 {
4016 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4017 }
4018
4019 return GL_FALSE;
4020}
4021
4022GLboolean __stdcall glIsShader(GLuint shader)
4023{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004024 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004025
4026 try
4027 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004028 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004029
4030 if (context && shader)
4031 {
4032 gl::Shader *shaderObject = context->getShader(shader);
4033
4034 if (shaderObject)
4035 {
4036 return GL_TRUE;
4037 }
4038 }
4039 }
4040 catch(std::bad_alloc&)
4041 {
4042 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4043 }
4044
4045 return GL_FALSE;
4046}
4047
4048GLboolean __stdcall glIsTexture(GLuint texture)
4049{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004050 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004051
4052 try
4053 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004054 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004055
4056 if (context && texture)
4057 {
4058 gl::Texture *textureObject = context->getTexture(texture);
4059
4060 if (textureObject)
4061 {
4062 return GL_TRUE;
4063 }
4064 }
4065 }
4066 catch(std::bad_alloc&)
4067 {
4068 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4069 }
4070
4071 return GL_FALSE;
4072}
4073
4074void __stdcall glLineWidth(GLfloat width)
4075{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004076 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004077
4078 try
4079 {
4080 if (width <= 0.0f)
4081 {
4082 return error(GL_INVALID_VALUE);
4083 }
4084
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004085 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004086
4087 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004088 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004089 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004090 }
4091 }
4092 catch(std::bad_alloc&)
4093 {
4094 return error(GL_OUT_OF_MEMORY);
4095 }
4096}
4097
4098void __stdcall glLinkProgram(GLuint program)
4099{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004100 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004101
4102 try
4103 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004104 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004105
4106 if (context)
4107 {
4108 gl::Program *programObject = context->getProgram(program);
4109
4110 if (!programObject)
4111 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004112 if (context->getShader(program))
4113 {
4114 return error(GL_INVALID_OPERATION);
4115 }
4116 else
4117 {
4118 return error(GL_INVALID_VALUE);
4119 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004120 }
4121
4122 programObject->link();
4123 }
4124 }
4125 catch(std::bad_alloc&)
4126 {
4127 return error(GL_OUT_OF_MEMORY);
4128 }
4129}
4130
4131void __stdcall glPixelStorei(GLenum pname, GLint param)
4132{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004133 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004134
4135 try
4136 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004137 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004138
4139 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004140 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004141 switch (pname)
4142 {
4143 case GL_UNPACK_ALIGNMENT:
4144 if (param != 1 && param != 2 && param != 4 && param != 8)
4145 {
4146 return error(GL_INVALID_VALUE);
4147 }
4148
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004149 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004150 break;
4151
4152 case GL_PACK_ALIGNMENT:
4153 if (param != 1 && param != 2 && param != 4 && param != 8)
4154 {
4155 return error(GL_INVALID_VALUE);
4156 }
4157
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004158 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004159 break;
4160
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004161 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4162 context->setPackReverseRowOrder(param != 0);
4163 break;
4164
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004165 default:
4166 return error(GL_INVALID_ENUM);
4167 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004168 }
4169 }
4170 catch(std::bad_alloc&)
4171 {
4172 return error(GL_OUT_OF_MEMORY);
4173 }
4174}
4175
4176void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4177{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004178 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004179
4180 try
4181 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004182 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004183
4184 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004185 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004186 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004187 }
4188 }
4189 catch(std::bad_alloc&)
4190 {
4191 return error(GL_OUT_OF_MEMORY);
4192 }
4193}
4194
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004195void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4196 GLenum format, GLenum type, GLsizei bufSize,
4197 GLvoid *data)
4198{
4199 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4200 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4201 x, y, width, height, format, type, bufSize, data);
4202
4203 try
4204 {
4205 if (width < 0 || height < 0 || bufSize < 0)
4206 {
4207 return error(GL_INVALID_VALUE);
4208 }
4209
4210 if (!validReadFormatType(format, type))
4211 {
4212 return error(GL_INVALID_OPERATION);
4213 }
4214
4215 gl::Context *context = gl::getNonLostContext();
4216
4217 if (context)
4218 {
4219 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4220 }
4221 }
4222 catch(std::bad_alloc&)
4223 {
4224 return error(GL_OUT_OF_MEMORY);
4225 }
4226}
4227
4228void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4229 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004230{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004231 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004232 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004233 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004234
4235 try
4236 {
4237 if (width < 0 || height < 0)
4238 {
4239 return error(GL_INVALID_VALUE);
4240 }
4241
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004242 if (!validReadFormatType(format, type))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004243 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004244 return error(GL_INVALID_OPERATION);
4245 }
4246
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004247 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004248
4249 if (context)
4250 {
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004251 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004252 }
4253 }
4254 catch(std::bad_alloc&)
4255 {
4256 return error(GL_OUT_OF_MEMORY);
4257 }
4258}
4259
4260void __stdcall glReleaseShaderCompiler(void)
4261{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004262 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004263
4264 try
4265 {
4266 gl::Shader::releaseCompiler();
4267 }
4268 catch(std::bad_alloc&)
4269 {
4270 return error(GL_OUT_OF_MEMORY);
4271 }
4272}
4273
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004274void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004275{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004276 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 +00004277 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004278
4279 try
4280 {
4281 switch (target)
4282 {
4283 case GL_RENDERBUFFER:
4284 break;
4285 default:
4286 return error(GL_INVALID_ENUM);
4287 }
4288
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004289 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004290 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004291 return error(GL_INVALID_ENUM);
4292 }
4293
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004294 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004295 {
4296 return error(GL_INVALID_VALUE);
4297 }
4298
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004299 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004300
4301 if (context)
4302 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004303 if (width > context->getMaximumRenderbufferDimension() ||
4304 height > context->getMaximumRenderbufferDimension() ||
4305 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004306 {
4307 return error(GL_INVALID_VALUE);
4308 }
4309
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004310 GLuint handle = context->getRenderbufferHandle();
4311 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004312 {
4313 return error(GL_INVALID_OPERATION);
4314 }
4315
4316 switch (internalformat)
4317 {
4318 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004319 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004320 break;
4321 case GL_RGBA4:
4322 case GL_RGB5_A1:
4323 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004324 case GL_RGB8_OES:
4325 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004326 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004327 break;
4328 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004329 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004330 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004331 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004332 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004333 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004334 default:
4335 return error(GL_INVALID_ENUM);
4336 }
4337 }
4338 }
4339 catch(std::bad_alloc&)
4340 {
4341 return error(GL_OUT_OF_MEMORY);
4342 }
4343}
4344
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004345void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4346{
4347 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4348}
4349
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004350void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4351{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004352 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004353
4354 try
4355 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004356 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004357
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004358 if (context)
4359 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004360 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004361 }
4362 }
4363 catch(std::bad_alloc&)
4364 {
4365 return error(GL_OUT_OF_MEMORY);
4366 }
4367}
4368
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004369void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4370{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004371 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004372
4373 try
4374 {
4375 if (condition != GL_ALL_COMPLETED_NV)
4376 {
4377 return error(GL_INVALID_ENUM);
4378 }
4379
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004380 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004381
4382 if (context)
4383 {
4384 gl::Fence *fenceObject = context->getFence(fence);
4385
4386 if (fenceObject == NULL)
4387 {
4388 return error(GL_INVALID_OPERATION);
4389 }
4390
4391 fenceObject->setFence(condition);
4392 }
4393 }
4394 catch(std::bad_alloc&)
4395 {
4396 return error(GL_OUT_OF_MEMORY);
4397 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004398}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004399
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004400void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4401{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004402 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 +00004403
4404 try
4405 {
4406 if (width < 0 || height < 0)
4407 {
4408 return error(GL_INVALID_VALUE);
4409 }
4410
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004411 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004412
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004413 if (context)
4414 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004415 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004416 }
4417 }
4418 catch(std::bad_alloc&)
4419 {
4420 return error(GL_OUT_OF_MEMORY);
4421 }
4422}
4423
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004424void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004425{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004426 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004427 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004428 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004429
4430 try
4431 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004432 // No binary shader formats are supported.
4433 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004434 }
4435 catch(std::bad_alloc&)
4436 {
4437 return error(GL_OUT_OF_MEMORY);
4438 }
4439}
4440
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004441void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004442{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004443 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 +00004444 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004445
4446 try
4447 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004448 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004449 {
4450 return error(GL_INVALID_VALUE);
4451 }
4452
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004453 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004454
4455 if (context)
4456 {
4457 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004458
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004459 if (!shaderObject)
4460 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004461 if (context->getProgram(shader))
4462 {
4463 return error(GL_INVALID_OPERATION);
4464 }
4465 else
4466 {
4467 return error(GL_INVALID_VALUE);
4468 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004469 }
4470
4471 shaderObject->setSource(count, string, length);
4472 }
4473 }
4474 catch(std::bad_alloc&)
4475 {
4476 return error(GL_OUT_OF_MEMORY);
4477 }
4478}
4479
4480void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4481{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004482 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004483}
4484
4485void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4486{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004487 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 +00004488
4489 try
4490 {
4491 switch (face)
4492 {
4493 case GL_FRONT:
4494 case GL_BACK:
4495 case GL_FRONT_AND_BACK:
4496 break;
4497 default:
4498 return error(GL_INVALID_ENUM);
4499 }
4500
4501 switch (func)
4502 {
4503 case GL_NEVER:
4504 case GL_ALWAYS:
4505 case GL_LESS:
4506 case GL_LEQUAL:
4507 case GL_EQUAL:
4508 case GL_GEQUAL:
4509 case GL_GREATER:
4510 case GL_NOTEQUAL:
4511 break;
4512 default:
4513 return error(GL_INVALID_ENUM);
4514 }
4515
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004516 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004517
4518 if (context)
4519 {
4520 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4521 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004522 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004523 }
4524
4525 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4526 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004527 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004528 }
4529 }
4530 }
4531 catch(std::bad_alloc&)
4532 {
4533 return error(GL_OUT_OF_MEMORY);
4534 }
4535}
4536
4537void __stdcall glStencilMask(GLuint mask)
4538{
4539 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4540}
4541
4542void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4543{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004544 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004545
4546 try
4547 {
4548 switch (face)
4549 {
4550 case GL_FRONT:
4551 case GL_BACK:
4552 case GL_FRONT_AND_BACK:
4553 break;
4554 default:
4555 return error(GL_INVALID_ENUM);
4556 }
4557
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004558 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004559
4560 if (context)
4561 {
4562 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4563 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004564 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004565 }
4566
4567 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4568 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004569 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004570 }
4571 }
4572 }
4573 catch(std::bad_alloc&)
4574 {
4575 return error(GL_OUT_OF_MEMORY);
4576 }
4577}
4578
4579void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4580{
4581 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4582}
4583
4584void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4585{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004586 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 +00004587 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004588
4589 try
4590 {
4591 switch (face)
4592 {
4593 case GL_FRONT:
4594 case GL_BACK:
4595 case GL_FRONT_AND_BACK:
4596 break;
4597 default:
4598 return error(GL_INVALID_ENUM);
4599 }
4600
4601 switch (fail)
4602 {
4603 case GL_ZERO:
4604 case GL_KEEP:
4605 case GL_REPLACE:
4606 case GL_INCR:
4607 case GL_DECR:
4608 case GL_INVERT:
4609 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004610 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004611 break;
4612 default:
4613 return error(GL_INVALID_ENUM);
4614 }
4615
4616 switch (zfail)
4617 {
4618 case GL_ZERO:
4619 case GL_KEEP:
4620 case GL_REPLACE:
4621 case GL_INCR:
4622 case GL_DECR:
4623 case GL_INVERT:
4624 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004625 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004626 break;
4627 default:
4628 return error(GL_INVALID_ENUM);
4629 }
4630
4631 switch (zpass)
4632 {
4633 case GL_ZERO:
4634 case GL_KEEP:
4635 case GL_REPLACE:
4636 case GL_INCR:
4637 case GL_DECR:
4638 case GL_INVERT:
4639 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004640 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004641 break;
4642 default:
4643 return error(GL_INVALID_ENUM);
4644 }
4645
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004646 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004647
4648 if (context)
4649 {
4650 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4651 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004652 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004653 }
4654
4655 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4656 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004657 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004658 }
4659 }
4660 }
4661 catch(std::bad_alloc&)
4662 {
4663 return error(GL_OUT_OF_MEMORY);
4664 }
4665}
4666
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004667GLboolean __stdcall glTestFenceNV(GLuint fence)
4668{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004669 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004670
4671 try
4672 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004673 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004674
4675 if (context)
4676 {
4677 gl::Fence *fenceObject = context->getFence(fence);
4678
4679 if (fenceObject == NULL)
4680 {
4681 return error(GL_INVALID_OPERATION, GL_TRUE);
4682 }
4683
4684 return fenceObject->testFence();
4685 }
4686 }
4687 catch(std::bad_alloc&)
4688 {
4689 error(GL_OUT_OF_MEMORY);
4690 }
4691
4692 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004693}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004694
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004695void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4696 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004697{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004698 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 +00004699 "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 +00004700 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004701
4702 try
4703 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00004704 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004705 {
4706 return error(GL_INVALID_VALUE);
4707 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004708
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004709 if (internalformat != format)
4710 {
4711 return error(GL_INVALID_OPERATION);
4712 }
4713
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004714 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004715 {
4716 case GL_ALPHA:
4717 case GL_LUMINANCE:
4718 case GL_LUMINANCE_ALPHA:
4719 switch (type)
4720 {
4721 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004722 case GL_FLOAT:
4723 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004724 break;
4725 default:
4726 return error(GL_INVALID_ENUM);
4727 }
4728 break;
4729 case GL_RGB:
4730 switch (type)
4731 {
4732 case GL_UNSIGNED_BYTE:
4733 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004734 case GL_FLOAT:
4735 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004736 break;
4737 default:
4738 return error(GL_INVALID_ENUM);
4739 }
4740 break;
4741 case GL_RGBA:
4742 switch (type)
4743 {
4744 case GL_UNSIGNED_BYTE:
4745 case GL_UNSIGNED_SHORT_4_4_4_4:
4746 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004747 case GL_FLOAT:
4748 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004749 break;
4750 default:
4751 return error(GL_INVALID_ENUM);
4752 }
4753 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004754 case GL_BGRA_EXT:
4755 switch (type)
4756 {
4757 case GL_UNSIGNED_BYTE:
4758 break;
4759 default:
4760 return error(GL_INVALID_ENUM);
4761 }
4762 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004763 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4764 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00004765 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4766 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00004767 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004768 default:
4769 return error(GL_INVALID_VALUE);
4770 }
4771
4772 if (border != 0)
4773 {
4774 return error(GL_INVALID_VALUE);
4775 }
4776
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004777 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004778
4779 if (context)
4780 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00004781 if (level > context->getMaximumTextureLevel())
4782 {
4783 return error(GL_INVALID_VALUE);
4784 }
4785
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004786 switch (target)
4787 {
4788 case GL_TEXTURE_2D:
4789 if (width > (context->getMaximumTextureDimension() >> level) ||
4790 height > (context->getMaximumTextureDimension() >> level))
4791 {
4792 return error(GL_INVALID_VALUE);
4793 }
4794 break;
4795 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4796 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4797 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4798 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4799 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4800 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4801 if (width != height)
4802 {
4803 return error(GL_INVALID_VALUE);
4804 }
4805
4806 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4807 height > (context->getMaximumCubeTextureDimension() >> level))
4808 {
4809 return error(GL_INVALID_VALUE);
4810 }
4811 break;
4812 default:
4813 return error(GL_INVALID_ENUM);
4814 }
4815
gman@chromium.org50c526d2011-08-10 05:19:44 +00004816 switch (format) {
4817 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
4818 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4819 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00004820 {
4821 return error(GL_INVALID_OPERATION);
4822 }
4823 else
4824 {
4825 return error(GL_INVALID_ENUM);
4826 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00004827 break;
4828 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4829 if (context->supportsDXT3Textures())
4830 {
4831 return error(GL_INVALID_OPERATION);
4832 }
4833 else
4834 {
4835 return error(GL_INVALID_ENUM);
4836 }
4837 break;
4838 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
4839 if (context->supportsDXT5Textures())
4840 {
4841 return error(GL_INVALID_OPERATION);
4842 }
4843 else
4844 {
4845 return error(GL_INVALID_ENUM);
4846 }
4847 break;
4848 default:
4849 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004850 }
4851
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004852 if (type == GL_FLOAT)
4853 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004854 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004855 {
4856 return error(GL_INVALID_ENUM);
4857 }
4858 }
4859 else if (type == GL_HALF_FLOAT_OES)
4860 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004861 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004862 {
4863 return error(GL_INVALID_ENUM);
4864 }
4865 }
4866
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004867 if (target == GL_TEXTURE_2D)
4868 {
4869 gl::Texture2D *texture = context->getTexture2D();
4870
4871 if (!texture)
4872 {
4873 return error(GL_INVALID_OPERATION);
4874 }
4875
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004876 if (texture->isImmutable())
4877 {
4878 return error(GL_INVALID_OPERATION);
4879 }
4880
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004881 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004882 }
4883 else
4884 {
4885 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4886
4887 if (!texture)
4888 {
4889 return error(GL_INVALID_OPERATION);
4890 }
4891
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004892 if (texture->isImmutable())
4893 {
4894 return error(GL_INVALID_OPERATION);
4895 }
4896
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004897 switch (target)
4898 {
4899 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004900 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004901 break;
4902 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004903 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004904 break;
4905 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004906 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004907 break;
4908 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004909 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004910 break;
4911 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004912 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004913 break;
4914 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004915 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004916 break;
4917 default: UNREACHABLE();
4918 }
4919 }
4920 }
4921 }
4922 catch(std::bad_alloc&)
4923 {
4924 return error(GL_OUT_OF_MEMORY);
4925 }
4926}
4927
4928void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4929{
4930 glTexParameteri(target, pname, (GLint)param);
4931}
4932
4933void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4934{
4935 glTexParameteri(target, pname, (GLint)*params);
4936}
4937
4938void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4939{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004940 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004941
4942 try
4943 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004944 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004945
4946 if (context)
4947 {
4948 gl::Texture *texture;
4949
4950 switch (target)
4951 {
4952 case GL_TEXTURE_2D:
4953 texture = context->getTexture2D();
4954 break;
4955 case GL_TEXTURE_CUBE_MAP:
4956 texture = context->getTextureCubeMap();
4957 break;
4958 default:
4959 return error(GL_INVALID_ENUM);
4960 }
4961
4962 switch (pname)
4963 {
4964 case GL_TEXTURE_WRAP_S:
4965 if (!texture->setWrapS((GLenum)param))
4966 {
4967 return error(GL_INVALID_ENUM);
4968 }
4969 break;
4970 case GL_TEXTURE_WRAP_T:
4971 if (!texture->setWrapT((GLenum)param))
4972 {
4973 return error(GL_INVALID_ENUM);
4974 }
4975 break;
4976 case GL_TEXTURE_MIN_FILTER:
4977 if (!texture->setMinFilter((GLenum)param))
4978 {
4979 return error(GL_INVALID_ENUM);
4980 }
4981 break;
4982 case GL_TEXTURE_MAG_FILTER:
4983 if (!texture->setMagFilter((GLenum)param))
4984 {
4985 return error(GL_INVALID_ENUM);
4986 }
4987 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00004988 case GL_TEXTURE_USAGE_ANGLE:
4989 if (!texture->setUsage((GLenum)param))
4990 {
4991 return error(GL_INVALID_ENUM);
4992 }
4993 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004994 default:
4995 return error(GL_INVALID_ENUM);
4996 }
4997 }
4998 }
4999 catch(std::bad_alloc&)
5000 {
5001 return error(GL_OUT_OF_MEMORY);
5002 }
5003}
5004
5005void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5006{
5007 glTexParameteri(target, pname, *params);
5008}
5009
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005010void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5011{
5012 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5013 target, levels, internalformat, width, height);
5014
5015 try
5016 {
5017 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5018 {
5019 return error(GL_INVALID_ENUM);
5020 }
5021
5022 if (width < 1 || height < 1 || levels < 1)
5023 {
5024 return error(GL_INVALID_VALUE);
5025 }
5026
5027 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5028 {
5029 return error(GL_INVALID_VALUE);
5030 }
5031
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005032 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005033 {
5034 return error(GL_INVALID_OPERATION);
5035 }
5036
5037 GLenum format = gl::ExtractFormat(internalformat);
5038 GLenum type = gl::ExtractType(internalformat);
5039
5040 if (format == GL_NONE || type == GL_NONE)
5041 {
5042 return error(GL_INVALID_ENUM);
5043 }
5044
5045 gl::Context *context = gl::getNonLostContext();
5046
5047 if (context)
5048 {
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005049 switch (target)
5050 {
5051 case GL_TEXTURE_2D:
5052 if (width > context->getMaximumTextureDimension() ||
5053 height > context->getMaximumTextureDimension())
5054 {
5055 return error(GL_INVALID_VALUE);
5056 }
5057 break;
5058 case GL_TEXTURE_CUBE_MAP:
5059 if (width > context->getMaximumCubeTextureDimension() ||
5060 height > context->getMaximumCubeTextureDimension())
5061 {
5062 return error(GL_INVALID_VALUE);
5063 }
5064 break;
5065 default:
5066 return error(GL_INVALID_ENUM);
5067 }
5068
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005069 if (levels != 1 && !context->supportsNonPower2Texture())
5070 {
5071 if (!gl::isPow2(width) || !gl::isPow2(height))
5072 {
5073 return error(GL_INVALID_OPERATION);
5074 }
5075 }
5076
daniel@transgaming.come1077362011-11-11 04:16:50 +00005077 switch (internalformat)
5078 {
5079 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5080 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5081 if (!context->supportsDXT1Textures())
5082 {
5083 return error(GL_INVALID_ENUM);
5084 }
5085 break;
5086 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5087 if (!context->supportsDXT3Textures())
5088 {
5089 return error(GL_INVALID_ENUM);
5090 }
5091 break;
5092 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5093 if (!context->supportsDXT5Textures())
5094 {
5095 return error(GL_INVALID_ENUM);
5096 }
5097 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005098 case GL_RGBA32F_EXT:
5099 case GL_RGB32F_EXT:
5100 case GL_ALPHA32F_EXT:
5101 case GL_LUMINANCE32F_EXT:
5102 case GL_LUMINANCE_ALPHA32F_EXT:
5103 if (!context->supportsFloat32Textures())
5104 {
5105 return error(GL_INVALID_ENUM);
5106 }
5107 break;
5108 case GL_RGBA16F_EXT:
5109 case GL_RGB16F_EXT:
5110 case GL_ALPHA16F_EXT:
5111 case GL_LUMINANCE16F_EXT:
5112 case GL_LUMINANCE_ALPHA16F_EXT:
5113 if (!context->supportsFloat16Textures())
5114 {
5115 return error(GL_INVALID_ENUM);
5116 }
5117 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005118 }
5119
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005120 if (target == GL_TEXTURE_2D)
5121 {
5122 gl::Texture2D *texture = context->getTexture2D();
5123
5124 if (!texture || texture->id() == 0)
5125 {
5126 return error(GL_INVALID_OPERATION);
5127 }
5128
5129 if (texture->isImmutable())
5130 {
5131 return error(GL_INVALID_OPERATION);
5132 }
5133
5134 texture->storage(levels, internalformat, width, height);
5135 }
5136 else if (target == GL_TEXTURE_CUBE_MAP)
5137 {
5138 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5139
5140 if (!texture || texture->id() == 0)
5141 {
5142 return error(GL_INVALID_OPERATION);
5143 }
5144
5145 if (texture->isImmutable())
5146 {
5147 return error(GL_INVALID_OPERATION);
5148 }
5149
5150 texture->storage(levels, internalformat, width);
5151 }
5152 else UNREACHABLE();
5153 }
5154 }
5155 catch(std::bad_alloc&)
5156 {
5157 return error(GL_OUT_OF_MEMORY);
5158 }
5159}
5160
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005161void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5162 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005163{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005164 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005165 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005166 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005167 target, level, xoffset, yoffset, width, height, format, type, pixels);
5168
5169 try
5170 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005171 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005172 {
5173 return error(GL_INVALID_ENUM);
5174 }
5175
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005176 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005177 {
5178 return error(GL_INVALID_VALUE);
5179 }
5180
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005181 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5182 {
5183 return error(GL_INVALID_VALUE);
5184 }
5185
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005186 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005187 {
5188 return error(GL_INVALID_ENUM);
5189 }
5190
5191 if (width == 0 || height == 0 || pixels == NULL)
5192 {
5193 return;
5194 }
5195
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005196 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005197
5198 if (context)
5199 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005200 if (level > context->getMaximumTextureLevel())
5201 {
5202 return error(GL_INVALID_VALUE);
5203 }
5204
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005205 if (format == GL_FLOAT)
5206 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005207 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005208 {
5209 return error(GL_INVALID_ENUM);
5210 }
5211 }
5212 else if (format == GL_HALF_FLOAT_OES)
5213 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005214 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005215 {
5216 return error(GL_INVALID_ENUM);
5217 }
5218 }
5219
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005220 if (target == GL_TEXTURE_2D)
5221 {
5222 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005223 if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005224 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005225 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005226 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005227 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005228 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005229 {
5230 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005231 if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005232 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005233 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005234 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005235 }
5236 else
5237 {
5238 UNREACHABLE();
5239 }
5240 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005241 }
5242 catch(std::bad_alloc&)
5243 {
5244 return error(GL_OUT_OF_MEMORY);
5245 }
5246}
5247
5248void __stdcall glUniform1f(GLint location, GLfloat x)
5249{
5250 glUniform1fv(location, 1, &x);
5251}
5252
5253void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5254{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005255 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005256
5257 try
5258 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005259 if (count < 0)
5260 {
5261 return error(GL_INVALID_VALUE);
5262 }
5263
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005264 if (location == -1)
5265 {
5266 return;
5267 }
5268
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005269 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005270
5271 if (context)
5272 {
5273 gl::Program *program = context->getCurrentProgram();
5274
5275 if (!program)
5276 {
5277 return error(GL_INVALID_OPERATION);
5278 }
5279
5280 if (!program->setUniform1fv(location, count, v))
5281 {
5282 return error(GL_INVALID_OPERATION);
5283 }
5284 }
5285 }
5286 catch(std::bad_alloc&)
5287 {
5288 return error(GL_OUT_OF_MEMORY);
5289 }
5290}
5291
5292void __stdcall glUniform1i(GLint location, GLint x)
5293{
5294 glUniform1iv(location, 1, &x);
5295}
5296
5297void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5298{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005299 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005300
5301 try
5302 {
5303 if (count < 0)
5304 {
5305 return error(GL_INVALID_VALUE);
5306 }
5307
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005308 if (location == -1)
5309 {
5310 return;
5311 }
5312
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005313 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005314
5315 if (context)
5316 {
5317 gl::Program *program = context->getCurrentProgram();
5318
5319 if (!program)
5320 {
5321 return error(GL_INVALID_OPERATION);
5322 }
5323
5324 if (!program->setUniform1iv(location, count, v))
5325 {
5326 return error(GL_INVALID_OPERATION);
5327 }
5328 }
5329 }
5330 catch(std::bad_alloc&)
5331 {
5332 return error(GL_OUT_OF_MEMORY);
5333 }
5334}
5335
5336void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5337{
5338 GLfloat xy[2] = {x, y};
5339
5340 glUniform2fv(location, 1, (GLfloat*)&xy);
5341}
5342
5343void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5344{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005345 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005346
5347 try
5348 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005349 if (count < 0)
5350 {
5351 return error(GL_INVALID_VALUE);
5352 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005353
5354 if (location == -1)
5355 {
5356 return;
5357 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005358
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005359 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005360
5361 if (context)
5362 {
5363 gl::Program *program = context->getCurrentProgram();
5364
5365 if (!program)
5366 {
5367 return error(GL_INVALID_OPERATION);
5368 }
5369
5370 if (!program->setUniform2fv(location, count, v))
5371 {
5372 return error(GL_INVALID_OPERATION);
5373 }
5374 }
5375 }
5376 catch(std::bad_alloc&)
5377 {
5378 return error(GL_OUT_OF_MEMORY);
5379 }
5380}
5381
5382void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5383{
5384 GLint xy[4] = {x, y};
5385
5386 glUniform2iv(location, 1, (GLint*)&xy);
5387}
5388
5389void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5390{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005391 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005392
5393 try
5394 {
5395 if (count < 0)
5396 {
5397 return error(GL_INVALID_VALUE);
5398 }
5399
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005400 if (location == -1)
5401 {
5402 return;
5403 }
5404
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005405 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005406
5407 if (context)
5408 {
5409 gl::Program *program = context->getCurrentProgram();
5410
5411 if (!program)
5412 {
5413 return error(GL_INVALID_OPERATION);
5414 }
5415
5416 if (!program->setUniform2iv(location, count, v))
5417 {
5418 return error(GL_INVALID_OPERATION);
5419 }
5420 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005421 }
5422 catch(std::bad_alloc&)
5423 {
5424 return error(GL_OUT_OF_MEMORY);
5425 }
5426}
5427
5428void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5429{
5430 GLfloat xyz[3] = {x, y, z};
5431
5432 glUniform3fv(location, 1, (GLfloat*)&xyz);
5433}
5434
5435void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5436{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005437 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005438
5439 try
5440 {
5441 if (count < 0)
5442 {
5443 return error(GL_INVALID_VALUE);
5444 }
5445
5446 if (location == -1)
5447 {
5448 return;
5449 }
5450
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005451 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005452
5453 if (context)
5454 {
5455 gl::Program *program = context->getCurrentProgram();
5456
5457 if (!program)
5458 {
5459 return error(GL_INVALID_OPERATION);
5460 }
5461
5462 if (!program->setUniform3fv(location, count, v))
5463 {
5464 return error(GL_INVALID_OPERATION);
5465 }
5466 }
5467 }
5468 catch(std::bad_alloc&)
5469 {
5470 return error(GL_OUT_OF_MEMORY);
5471 }
5472}
5473
5474void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5475{
5476 GLint xyz[3] = {x, y, z};
5477
5478 glUniform3iv(location, 1, (GLint*)&xyz);
5479}
5480
5481void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5482{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005483 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005484
5485 try
5486 {
5487 if (count < 0)
5488 {
5489 return error(GL_INVALID_VALUE);
5490 }
5491
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005492 if (location == -1)
5493 {
5494 return;
5495 }
5496
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005497 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005498
5499 if (context)
5500 {
5501 gl::Program *program = context->getCurrentProgram();
5502
5503 if (!program)
5504 {
5505 return error(GL_INVALID_OPERATION);
5506 }
5507
5508 if (!program->setUniform3iv(location, count, v))
5509 {
5510 return error(GL_INVALID_OPERATION);
5511 }
5512 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005513 }
5514 catch(std::bad_alloc&)
5515 {
5516 return error(GL_OUT_OF_MEMORY);
5517 }
5518}
5519
5520void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5521{
5522 GLfloat xyzw[4] = {x, y, z, w};
5523
5524 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5525}
5526
5527void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5528{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005529 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005530
5531 try
5532 {
5533 if (count < 0)
5534 {
5535 return error(GL_INVALID_VALUE);
5536 }
5537
5538 if (location == -1)
5539 {
5540 return;
5541 }
5542
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005543 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005544
5545 if (context)
5546 {
5547 gl::Program *program = context->getCurrentProgram();
5548
5549 if (!program)
5550 {
5551 return error(GL_INVALID_OPERATION);
5552 }
5553
5554 if (!program->setUniform4fv(location, count, v))
5555 {
5556 return error(GL_INVALID_OPERATION);
5557 }
5558 }
5559 }
5560 catch(std::bad_alloc&)
5561 {
5562 return error(GL_OUT_OF_MEMORY);
5563 }
5564}
5565
5566void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5567{
5568 GLint xyzw[4] = {x, y, z, w};
5569
5570 glUniform4iv(location, 1, (GLint*)&xyzw);
5571}
5572
5573void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5574{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005575 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005576
5577 try
5578 {
5579 if (count < 0)
5580 {
5581 return error(GL_INVALID_VALUE);
5582 }
5583
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005584 if (location == -1)
5585 {
5586 return;
5587 }
5588
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005589 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005590
5591 if (context)
5592 {
5593 gl::Program *program = context->getCurrentProgram();
5594
5595 if (!program)
5596 {
5597 return error(GL_INVALID_OPERATION);
5598 }
5599
5600 if (!program->setUniform4iv(location, count, v))
5601 {
5602 return error(GL_INVALID_OPERATION);
5603 }
5604 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005605 }
5606 catch(std::bad_alloc&)
5607 {
5608 return error(GL_OUT_OF_MEMORY);
5609 }
5610}
5611
5612void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5613{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005614 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005615 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005616
5617 try
5618 {
5619 if (count < 0 || transpose != GL_FALSE)
5620 {
5621 return error(GL_INVALID_VALUE);
5622 }
5623
5624 if (location == -1)
5625 {
5626 return;
5627 }
5628
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005629 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005630
5631 if (context)
5632 {
5633 gl::Program *program = context->getCurrentProgram();
5634
5635 if (!program)
5636 {
5637 return error(GL_INVALID_OPERATION);
5638 }
5639
5640 if (!program->setUniformMatrix2fv(location, count, value))
5641 {
5642 return error(GL_INVALID_OPERATION);
5643 }
5644 }
5645 }
5646 catch(std::bad_alloc&)
5647 {
5648 return error(GL_OUT_OF_MEMORY);
5649 }
5650}
5651
5652void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5653{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005654 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005655 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005656
5657 try
5658 {
5659 if (count < 0 || transpose != GL_FALSE)
5660 {
5661 return error(GL_INVALID_VALUE);
5662 }
5663
5664 if (location == -1)
5665 {
5666 return;
5667 }
5668
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005669 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005670
5671 if (context)
5672 {
5673 gl::Program *program = context->getCurrentProgram();
5674
5675 if (!program)
5676 {
5677 return error(GL_INVALID_OPERATION);
5678 }
5679
5680 if (!program->setUniformMatrix3fv(location, count, value))
5681 {
5682 return error(GL_INVALID_OPERATION);
5683 }
5684 }
5685 }
5686 catch(std::bad_alloc&)
5687 {
5688 return error(GL_OUT_OF_MEMORY);
5689 }
5690}
5691
5692void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5693{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005694 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005695 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005696
5697 try
5698 {
5699 if (count < 0 || transpose != GL_FALSE)
5700 {
5701 return error(GL_INVALID_VALUE);
5702 }
5703
5704 if (location == -1)
5705 {
5706 return;
5707 }
5708
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005709 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005710
5711 if (context)
5712 {
5713 gl::Program *program = context->getCurrentProgram();
5714
5715 if (!program)
5716 {
5717 return error(GL_INVALID_OPERATION);
5718 }
5719
5720 if (!program->setUniformMatrix4fv(location, count, value))
5721 {
5722 return error(GL_INVALID_OPERATION);
5723 }
5724 }
5725 }
5726 catch(std::bad_alloc&)
5727 {
5728 return error(GL_OUT_OF_MEMORY);
5729 }
5730}
5731
5732void __stdcall glUseProgram(GLuint program)
5733{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005734 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005735
5736 try
5737 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005738 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005739
5740 if (context)
5741 {
5742 gl::Program *programObject = context->getProgram(program);
5743
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005744 if (!programObject && program != 0)
5745 {
5746 if (context->getShader(program))
5747 {
5748 return error(GL_INVALID_OPERATION);
5749 }
5750 else
5751 {
5752 return error(GL_INVALID_VALUE);
5753 }
5754 }
5755
5756 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005757 {
5758 return error(GL_INVALID_OPERATION);
5759 }
5760
5761 context->useProgram(program);
5762 }
5763 }
5764 catch(std::bad_alloc&)
5765 {
5766 return error(GL_OUT_OF_MEMORY);
5767 }
5768}
5769
5770void __stdcall glValidateProgram(GLuint program)
5771{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005772 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005773
5774 try
5775 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005776 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005777
5778 if (context)
5779 {
5780 gl::Program *programObject = context->getProgram(program);
5781
5782 if (!programObject)
5783 {
5784 if (context->getShader(program))
5785 {
5786 return error(GL_INVALID_OPERATION);
5787 }
5788 else
5789 {
5790 return error(GL_INVALID_VALUE);
5791 }
5792 }
5793
5794 programObject->validate();
5795 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005796 }
5797 catch(std::bad_alloc&)
5798 {
5799 return error(GL_OUT_OF_MEMORY);
5800 }
5801}
5802
5803void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5804{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005805 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005806
5807 try
5808 {
5809 if (index >= gl::MAX_VERTEX_ATTRIBS)
5810 {
5811 return error(GL_INVALID_VALUE);
5812 }
5813
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005814 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005815
5816 if (context)
5817 {
5818 GLfloat vals[4] = { x, 0, 0, 1 };
5819 context->setVertexAttrib(index, vals);
5820 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005821 }
5822 catch(std::bad_alloc&)
5823 {
5824 return error(GL_OUT_OF_MEMORY);
5825 }
5826}
5827
5828void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5829{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005830 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005831
5832 try
5833 {
5834 if (index >= gl::MAX_VERTEX_ATTRIBS)
5835 {
5836 return error(GL_INVALID_VALUE);
5837 }
5838
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005839 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005840
5841 if (context)
5842 {
5843 GLfloat vals[4] = { values[0], 0, 0, 1 };
5844 context->setVertexAttrib(index, vals);
5845 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005846 }
5847 catch(std::bad_alloc&)
5848 {
5849 return error(GL_OUT_OF_MEMORY);
5850 }
5851}
5852
5853void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5854{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005855 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005856
5857 try
5858 {
5859 if (index >= gl::MAX_VERTEX_ATTRIBS)
5860 {
5861 return error(GL_INVALID_VALUE);
5862 }
5863
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005864 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005865
5866 if (context)
5867 {
5868 GLfloat vals[4] = { x, y, 0, 1 };
5869 context->setVertexAttrib(index, vals);
5870 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005871 }
5872 catch(std::bad_alloc&)
5873 {
5874 return error(GL_OUT_OF_MEMORY);
5875 }
5876}
5877
5878void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5879{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005880 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005881
5882 try
5883 {
5884 if (index >= gl::MAX_VERTEX_ATTRIBS)
5885 {
5886 return error(GL_INVALID_VALUE);
5887 }
5888
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005889 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005890
5891 if (context)
5892 {
5893 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5894 context->setVertexAttrib(index, vals);
5895 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005896 }
5897 catch(std::bad_alloc&)
5898 {
5899 return error(GL_OUT_OF_MEMORY);
5900 }
5901}
5902
5903void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5904{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005905 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 +00005906
5907 try
5908 {
5909 if (index >= gl::MAX_VERTEX_ATTRIBS)
5910 {
5911 return error(GL_INVALID_VALUE);
5912 }
5913
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005914 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005915
5916 if (context)
5917 {
5918 GLfloat vals[4] = { x, y, z, 1 };
5919 context->setVertexAttrib(index, vals);
5920 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005921 }
5922 catch(std::bad_alloc&)
5923 {
5924 return error(GL_OUT_OF_MEMORY);
5925 }
5926}
5927
5928void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5929{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005930 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005931
5932 try
5933 {
5934 if (index >= gl::MAX_VERTEX_ATTRIBS)
5935 {
5936 return error(GL_INVALID_VALUE);
5937 }
5938
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005939 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005940
5941 if (context)
5942 {
5943 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5944 context->setVertexAttrib(index, vals);
5945 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005946 }
5947 catch(std::bad_alloc&)
5948 {
5949 return error(GL_OUT_OF_MEMORY);
5950 }
5951}
5952
5953void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5954{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005955 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 +00005956
5957 try
5958 {
5959 if (index >= gl::MAX_VERTEX_ATTRIBS)
5960 {
5961 return error(GL_INVALID_VALUE);
5962 }
5963
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005964 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005965
5966 if (context)
5967 {
5968 GLfloat vals[4] = { x, y, z, w };
5969 context->setVertexAttrib(index, vals);
5970 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005971 }
5972 catch(std::bad_alloc&)
5973 {
5974 return error(GL_OUT_OF_MEMORY);
5975 }
5976}
5977
5978void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5979{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005980 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005981
5982 try
5983 {
5984 if (index >= gl::MAX_VERTEX_ATTRIBS)
5985 {
5986 return error(GL_INVALID_VALUE);
5987 }
5988
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005989 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005990
5991 if (context)
5992 {
5993 context->setVertexAttrib(index, values);
5994 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005995 }
5996 catch(std::bad_alloc&)
5997 {
5998 return error(GL_OUT_OF_MEMORY);
5999 }
6000}
6001
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006002void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006003{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006004 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006005 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006006 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006007
6008 try
6009 {
6010 if (index >= gl::MAX_VERTEX_ATTRIBS)
6011 {
6012 return error(GL_INVALID_VALUE);
6013 }
6014
6015 if (size < 1 || size > 4)
6016 {
6017 return error(GL_INVALID_VALUE);
6018 }
6019
6020 switch (type)
6021 {
6022 case GL_BYTE:
6023 case GL_UNSIGNED_BYTE:
6024 case GL_SHORT:
6025 case GL_UNSIGNED_SHORT:
6026 case GL_FIXED:
6027 case GL_FLOAT:
6028 break;
6029 default:
6030 return error(GL_INVALID_ENUM);
6031 }
6032
6033 if (stride < 0)
6034 {
6035 return error(GL_INVALID_VALUE);
6036 }
6037
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006038 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006039
6040 if (context)
6041 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006042 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006043 }
6044 }
6045 catch(std::bad_alloc&)
6046 {
6047 return error(GL_OUT_OF_MEMORY);
6048 }
6049}
6050
6051void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6052{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006053 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 +00006054
6055 try
6056 {
6057 if (width < 0 || height < 0)
6058 {
6059 return error(GL_INVALID_VALUE);
6060 }
6061
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006062 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006063
6064 if (context)
6065 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006066 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006067 }
6068 }
6069 catch(std::bad_alloc&)
6070 {
6071 return error(GL_OUT_OF_MEMORY);
6072 }
6073}
6074
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006075void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6076 GLbitfield mask, GLenum filter)
6077{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006078 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006079 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6080 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6081 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6082
6083 try
6084 {
6085 switch (filter)
6086 {
6087 case GL_NEAREST:
6088 break;
6089 default:
6090 return error(GL_INVALID_ENUM);
6091 }
6092
6093 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6094 {
6095 return error(GL_INVALID_VALUE);
6096 }
6097
6098 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6099 {
6100 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6101 return error(GL_INVALID_OPERATION);
6102 }
6103
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006104 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006105
6106 if (context)
6107 {
6108 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6109 {
6110 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6111 return error(GL_INVALID_OPERATION);
6112 }
6113
6114 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6115 }
6116 }
6117 catch(std::bad_alloc&)
6118 {
6119 return error(GL_OUT_OF_MEMORY);
6120 }
6121}
6122
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006123void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6124 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006125{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006126 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006127 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006128 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006129 target, level, internalformat, width, height, depth, border, format, type, pixels);
6130
6131 try
6132 {
6133 UNIMPLEMENTED(); // FIXME
6134 }
6135 catch(std::bad_alloc&)
6136 {
6137 return error(GL_OUT_OF_MEMORY);
6138 }
6139}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006140
6141__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6142{
6143 struct Extension
6144 {
6145 const char *name;
6146 __eglMustCastToProperFunctionPointerType address;
6147 };
6148
6149 static const Extension glExtensions[] =
6150 {
6151 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006152 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006153 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006154 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6155 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6156 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6157 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6158 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6159 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6160 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006161 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006162 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006163 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6164 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6165 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6166 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006167 };
6168
6169 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6170 {
6171 if (strcmp(procname, glExtensions[ext].name) == 0)
6172 {
6173 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6174 }
6175 }
6176
6177 return NULL;
6178}
6179
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006180// Non-public functions used by EGL
6181
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006182bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006183{
6184 EVENT("(egl::Surface* surface = 0x%0.8p)",
6185 surface);
6186
6187 try
6188 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006189 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006190
6191 if (context)
6192 {
6193 gl::Texture2D *textureObject = context->getTexture2D();
6194
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006195 if (textureObject->isImmutable())
6196 {
6197 return false;
6198 }
6199
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006200 if (textureObject)
6201 {
6202 textureObject->bindTexImage(surface);
6203 }
6204 }
6205 }
6206 catch(std::bad_alloc&)
6207 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006208 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006209 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006210
6211 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006212}
6213
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006214}