blob: bad6f41d54f9f4225bd242d6f178e0f6b89dd4af [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.com9d788502011-11-09 17:46:55 +00002710 if (context->isContextLost())
2711 return GL_OUT_OF_MEMORY;
2712 else
2713 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002714 }
2715
2716 return GL_NO_ERROR;
2717}
2718
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002719void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2720{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002721 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002722
2723 try
2724 {
2725
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002726 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002727
2728 if (context)
2729 {
2730 gl::Fence *fenceObject = context->getFence(fence);
2731
2732 if (fenceObject == NULL)
2733 {
2734 return error(GL_INVALID_OPERATION);
2735 }
2736
2737 fenceObject->getFenceiv(pname, params);
2738 }
2739 }
2740 catch(std::bad_alloc&)
2741 {
2742 return error(GL_OUT_OF_MEMORY);
2743 }
2744}
2745
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002746void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2747{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002748 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002749
2750 try
2751 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002752 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002753
2754 if (context)
2755 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002756 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002757 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002758 GLenum nativeType;
2759 unsigned int numParams = 0;
2760 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2761 return error(GL_INVALID_ENUM);
2762
2763 if (numParams == 0)
2764 return; // it is known that the pname is valid, but that there are no parameters to return.
2765
2766 if (nativeType == GL_BOOL)
2767 {
2768 GLboolean *boolParams = NULL;
2769 boolParams = new GLboolean[numParams];
2770
2771 context->getBooleanv(pname, boolParams);
2772
2773 for (unsigned int i = 0; i < numParams; ++i)
2774 {
2775 if (boolParams[i] == GL_FALSE)
2776 params[i] = 0.0f;
2777 else
2778 params[i] = 1.0f;
2779 }
2780
2781 delete [] boolParams;
2782 }
2783 else if (nativeType == GL_INT)
2784 {
2785 GLint *intParams = NULL;
2786 intParams = new GLint[numParams];
2787
2788 context->getIntegerv(pname, intParams);
2789
2790 for (unsigned int i = 0; i < numParams; ++i)
2791 {
2792 params[i] = (GLfloat)intParams[i];
2793 }
2794
2795 delete [] intParams;
2796 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002797 }
2798 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002799 }
2800 catch(std::bad_alloc&)
2801 {
2802 return error(GL_OUT_OF_MEMORY);
2803 }
2804}
2805
2806void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2807{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002808 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 +00002809 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002810
2811 try
2812 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002813 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002814
2815 if (context)
2816 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002817 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002818 {
2819 return error(GL_INVALID_ENUM);
2820 }
2821
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002822 gl::Framebuffer *framebuffer = NULL;
2823 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2824 {
2825 if(context->getReadFramebufferHandle() == 0)
2826 {
2827 return error(GL_INVALID_OPERATION);
2828 }
2829
2830 framebuffer = context->getReadFramebuffer();
2831 }
2832 else
2833 {
2834 if (context->getDrawFramebufferHandle() == 0)
2835 {
2836 return error(GL_INVALID_OPERATION);
2837 }
2838
2839 framebuffer = context->getDrawFramebuffer();
2840 }
2841
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002842 GLenum attachmentType;
2843 GLuint attachmentHandle;
2844 switch (attachment)
2845 {
2846 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002847 attachmentType = framebuffer->getColorbufferType();
2848 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002849 break;
2850 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002851 attachmentType = framebuffer->getDepthbufferType();
2852 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002853 break;
2854 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002855 attachmentType = framebuffer->getStencilbufferType();
2856 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002857 break;
2858 default: return error(GL_INVALID_ENUM);
2859 }
2860
2861 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002862 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002863 {
2864 attachmentObjectType = attachmentType;
2865 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002866 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002867 {
2868 attachmentObjectType = GL_TEXTURE;
2869 }
2870 else UNREACHABLE();
2871
2872 switch (pname)
2873 {
2874 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2875 *params = attachmentObjectType;
2876 break;
2877 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2878 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2879 {
2880 *params = attachmentHandle;
2881 }
2882 else
2883 {
2884 return error(GL_INVALID_ENUM);
2885 }
2886 break;
2887 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2888 if (attachmentObjectType == GL_TEXTURE)
2889 {
2890 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2891 }
2892 else
2893 {
2894 return error(GL_INVALID_ENUM);
2895 }
2896 break;
2897 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2898 if (attachmentObjectType == GL_TEXTURE)
2899 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002900 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002901 {
2902 *params = attachmentType;
2903 }
2904 else
2905 {
2906 *params = 0;
2907 }
2908 }
2909 else
2910 {
2911 return error(GL_INVALID_ENUM);
2912 }
2913 break;
2914 default:
2915 return error(GL_INVALID_ENUM);
2916 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002917 }
2918 }
2919 catch(std::bad_alloc&)
2920 {
2921 return error(GL_OUT_OF_MEMORY);
2922 }
2923}
2924
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00002925GLenum __stdcall glGetGraphicsResetStatusEXT(void)
2926{
2927 EVENT("()");
2928
2929 try
2930 {
2931 gl::Context *context = gl::getContext();
2932
2933 if (context)
2934 {
2935 return context->getResetStatus();
2936 }
2937
2938 return GL_NO_ERROR;
2939 }
2940 catch(std::bad_alloc&)
2941 {
2942 return GL_OUT_OF_MEMORY;
2943 }
2944}
2945
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002946void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2947{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002948 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002949
2950 try
2951 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002952 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002953
2954 if (context)
2955 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002956 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002957 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002958 GLenum nativeType;
2959 unsigned int numParams = 0;
2960 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2961 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002962
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002963 if (numParams == 0)
2964 return; // it is known that pname is valid, but there are no parameters to return
2965
2966 if (nativeType == GL_BOOL)
2967 {
2968 GLboolean *boolParams = NULL;
2969 boolParams = new GLboolean[numParams];
2970
2971 context->getBooleanv(pname, boolParams);
2972
2973 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002974 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002975 if (boolParams[i] == GL_FALSE)
2976 params[i] = 0;
2977 else
2978 params[i] = 1;
2979 }
2980
2981 delete [] boolParams;
2982 }
2983 else if (nativeType == GL_FLOAT)
2984 {
2985 GLfloat *floatParams = NULL;
2986 floatParams = new GLfloat[numParams];
2987
2988 context->getFloatv(pname, floatParams);
2989
2990 for (unsigned int i = 0; i < numParams; ++i)
2991 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002992 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 +00002993 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002994 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002995 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002996 else
2997 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 +00002998 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002999
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003000 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003001 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003002 }
3003 }
3004 }
3005 catch(std::bad_alloc&)
3006 {
3007 return error(GL_OUT_OF_MEMORY);
3008 }
3009}
3010
3011void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3012{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003013 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003014
3015 try
3016 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003017 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003018
3019 if (context)
3020 {
3021 gl::Program *programObject = context->getProgram(program);
3022
3023 if (!programObject)
3024 {
3025 return error(GL_INVALID_VALUE);
3026 }
3027
3028 switch (pname)
3029 {
3030 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003031 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003032 return;
3033 case GL_LINK_STATUS:
3034 *params = programObject->isLinked();
3035 return;
3036 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003037 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003038 return;
3039 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003040 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003041 return;
3042 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003043 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003044 return;
3045 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003046 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003047 return;
3048 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003049 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003050 return;
3051 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003052 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003053 return;
3054 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003055 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003056 return;
3057 default:
3058 return error(GL_INVALID_ENUM);
3059 }
3060 }
3061 }
3062 catch(std::bad_alloc&)
3063 {
3064 return error(GL_OUT_OF_MEMORY);
3065 }
3066}
3067
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003068void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003069{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003070 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 +00003071 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003072
3073 try
3074 {
3075 if (bufsize < 0)
3076 {
3077 return error(GL_INVALID_VALUE);
3078 }
3079
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003080 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003081
3082 if (context)
3083 {
3084 gl::Program *programObject = context->getProgram(program);
3085
3086 if (!programObject)
3087 {
3088 return error(GL_INVALID_VALUE);
3089 }
3090
3091 programObject->getInfoLog(bufsize, length, infolog);
3092 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003093 }
3094 catch(std::bad_alloc&)
3095 {
3096 return error(GL_OUT_OF_MEMORY);
3097 }
3098}
3099
3100void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3101{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003102 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 +00003103
3104 try
3105 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003106 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003107
3108 if (context)
3109 {
3110 if (target != GL_RENDERBUFFER)
3111 {
3112 return error(GL_INVALID_ENUM);
3113 }
3114
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003115 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003116 {
3117 return error(GL_INVALID_OPERATION);
3118 }
3119
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003120 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003121
3122 switch (pname)
3123 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003124 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3125 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3126 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3127 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3128 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3129 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3130 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3131 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3132 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003133 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003134 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003135 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003136 *params = renderbuffer->getSamples();
3137 }
3138 else
3139 {
3140 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003141 }
3142 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003143 default:
3144 return error(GL_INVALID_ENUM);
3145 }
3146 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003147 }
3148 catch(std::bad_alloc&)
3149 {
3150 return error(GL_OUT_OF_MEMORY);
3151 }
3152}
3153
3154void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3155{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003156 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003157
3158 try
3159 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003160 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003161
3162 if (context)
3163 {
3164 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003165
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003166 if (!shaderObject)
3167 {
3168 return error(GL_INVALID_VALUE);
3169 }
3170
3171 switch (pname)
3172 {
3173 case GL_SHADER_TYPE:
3174 *params = shaderObject->getType();
3175 return;
3176 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003177 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003178 return;
3179 case GL_COMPILE_STATUS:
3180 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3181 return;
3182 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003183 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003184 return;
3185 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003186 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003187 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003188 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3189 *params = shaderObject->getTranslatedSourceLength();
3190 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003191 default:
3192 return error(GL_INVALID_ENUM);
3193 }
3194 }
3195 }
3196 catch(std::bad_alloc&)
3197 {
3198 return error(GL_OUT_OF_MEMORY);
3199 }
3200}
3201
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003202void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003203{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003204 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 +00003205 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003206
3207 try
3208 {
3209 if (bufsize < 0)
3210 {
3211 return error(GL_INVALID_VALUE);
3212 }
3213
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003214 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003215
3216 if (context)
3217 {
3218 gl::Shader *shaderObject = context->getShader(shader);
3219
3220 if (!shaderObject)
3221 {
3222 return error(GL_INVALID_VALUE);
3223 }
3224
3225 shaderObject->getInfoLog(bufsize, length, infolog);
3226 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003227 }
3228 catch(std::bad_alloc&)
3229 {
3230 return error(GL_OUT_OF_MEMORY);
3231 }
3232}
3233
3234void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3235{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003236 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 +00003237 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003238
3239 try
3240 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003241 switch (shadertype)
3242 {
3243 case GL_VERTEX_SHADER:
3244 case GL_FRAGMENT_SHADER:
3245 break;
3246 default:
3247 return error(GL_INVALID_ENUM);
3248 }
3249
3250 switch (precisiontype)
3251 {
3252 case GL_LOW_FLOAT:
3253 case GL_MEDIUM_FLOAT:
3254 case GL_HIGH_FLOAT:
3255 // Assume IEEE 754 precision
3256 range[0] = 127;
3257 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003258 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003259 break;
3260 case GL_LOW_INT:
3261 case GL_MEDIUM_INT:
3262 case GL_HIGH_INT:
3263 // Some (most) hardware only supports single-precision floating-point numbers,
3264 // which can accurately represent integers up to +/-16777216
3265 range[0] = 24;
3266 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003267 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003268 break;
3269 default:
3270 return error(GL_INVALID_ENUM);
3271 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003272 }
3273 catch(std::bad_alloc&)
3274 {
3275 return error(GL_OUT_OF_MEMORY);
3276 }
3277}
3278
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003279void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003280{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003281 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 +00003282 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003283
3284 try
3285 {
3286 if (bufsize < 0)
3287 {
3288 return error(GL_INVALID_VALUE);
3289 }
3290
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003291 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003292
3293 if (context)
3294 {
3295 gl::Shader *shaderObject = context->getShader(shader);
3296
3297 if (!shaderObject)
3298 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003299 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003300 }
3301
3302 shaderObject->getSource(bufsize, length, source);
3303 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003304 }
3305 catch(std::bad_alloc&)
3306 {
3307 return error(GL_OUT_OF_MEMORY);
3308 }
3309}
3310
zmo@google.coma574f782011-10-03 21:45:23 +00003311void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3312{
3313 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3314 shader, bufsize, length, source);
3315
3316 try
3317 {
3318 if (bufsize < 0)
3319 {
3320 return error(GL_INVALID_VALUE);
3321 }
3322
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003323 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003324
3325 if (context)
3326 {
3327 gl::Shader *shaderObject = context->getShader(shader);
3328
3329 if (!shaderObject)
3330 {
3331 return error(GL_INVALID_OPERATION);
3332 }
3333
3334 shaderObject->getTranslatedSource(bufsize, length, source);
3335 }
3336 }
3337 catch(std::bad_alloc&)
3338 {
3339 return error(GL_OUT_OF_MEMORY);
3340 }
3341}
3342
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003343const GLubyte* __stdcall glGetString(GLenum name)
3344{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003345 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003346
3347 try
3348 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003349 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003350
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003351 switch (name)
3352 {
3353 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003354 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003355 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003356 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003357 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003358 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003359 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003360 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003361 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003362 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003363 default:
3364 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3365 }
3366 }
3367 catch(std::bad_alloc&)
3368 {
3369 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3370 }
3371
3372 return NULL;
3373}
3374
3375void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3376{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003377 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 +00003378
3379 try
3380 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003381 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003382
3383 if (context)
3384 {
3385 gl::Texture *texture;
3386
3387 switch (target)
3388 {
3389 case GL_TEXTURE_2D:
3390 texture = context->getTexture2D();
3391 break;
3392 case GL_TEXTURE_CUBE_MAP:
3393 texture = context->getTextureCubeMap();
3394 break;
3395 default:
3396 return error(GL_INVALID_ENUM);
3397 }
3398
3399 switch (pname)
3400 {
3401 case GL_TEXTURE_MAG_FILTER:
3402 *params = (GLfloat)texture->getMagFilter();
3403 break;
3404 case GL_TEXTURE_MIN_FILTER:
3405 *params = (GLfloat)texture->getMinFilter();
3406 break;
3407 case GL_TEXTURE_WRAP_S:
3408 *params = (GLfloat)texture->getWrapS();
3409 break;
3410 case GL_TEXTURE_WRAP_T:
3411 *params = (GLfloat)texture->getWrapT();
3412 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003413 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3414 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3415 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003416 case GL_TEXTURE_USAGE_ANGLE:
3417 *params = (GLfloat)texture->getUsage();
3418 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003419 default:
3420 return error(GL_INVALID_ENUM);
3421 }
3422 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003423 }
3424 catch(std::bad_alloc&)
3425 {
3426 return error(GL_OUT_OF_MEMORY);
3427 }
3428}
3429
3430void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3431{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003432 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 +00003433
3434 try
3435 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003436 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003437
3438 if (context)
3439 {
3440 gl::Texture *texture;
3441
3442 switch (target)
3443 {
3444 case GL_TEXTURE_2D:
3445 texture = context->getTexture2D();
3446 break;
3447 case GL_TEXTURE_CUBE_MAP:
3448 texture = context->getTextureCubeMap();
3449 break;
3450 default:
3451 return error(GL_INVALID_ENUM);
3452 }
3453
3454 switch (pname)
3455 {
3456 case GL_TEXTURE_MAG_FILTER:
3457 *params = texture->getMagFilter();
3458 break;
3459 case GL_TEXTURE_MIN_FILTER:
3460 *params = texture->getMinFilter();
3461 break;
3462 case GL_TEXTURE_WRAP_S:
3463 *params = texture->getWrapS();
3464 break;
3465 case GL_TEXTURE_WRAP_T:
3466 *params = texture->getWrapT();
3467 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003468 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3469 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3470 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003471 case GL_TEXTURE_USAGE_ANGLE:
3472 *params = texture->getUsage();
3473 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003474 default:
3475 return error(GL_INVALID_ENUM);
3476 }
3477 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003478 }
3479 catch(std::bad_alloc&)
3480 {
3481 return error(GL_OUT_OF_MEMORY);
3482 }
3483}
3484
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003485void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3486{
3487 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3488 program, location, bufSize, params);
3489
3490 try
3491 {
3492 if (bufSize < 0)
3493 {
3494 return error(GL_INVALID_VALUE);
3495 }
3496
3497 gl::Context *context = gl::getNonLostContext();
3498
3499 if (context)
3500 {
3501 if (program == 0)
3502 {
3503 return error(GL_INVALID_VALUE);
3504 }
3505
3506 gl::Program *programObject = context->getProgram(program);
3507
3508 if (!programObject || !programObject->isLinked())
3509 {
3510 return error(GL_INVALID_OPERATION);
3511 }
3512
3513 if (!programObject->getUniformfv(location, &bufSize, params))
3514 {
3515 return error(GL_INVALID_OPERATION);
3516 }
3517 }
3518 }
3519 catch(std::bad_alloc&)
3520 {
3521 return error(GL_OUT_OF_MEMORY);
3522 }
3523}
3524
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003525void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3526{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003527 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003528
3529 try
3530 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003531 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003532
3533 if (context)
3534 {
3535 if (program == 0)
3536 {
3537 return error(GL_INVALID_VALUE);
3538 }
3539
3540 gl::Program *programObject = context->getProgram(program);
3541
3542 if (!programObject || !programObject->isLinked())
3543 {
3544 return error(GL_INVALID_OPERATION);
3545 }
3546
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003547 if (!programObject->getUniformfv(location, NULL, params))
3548 {
3549 return error(GL_INVALID_OPERATION);
3550 }
3551 }
3552 }
3553 catch(std::bad_alloc&)
3554 {
3555 return error(GL_OUT_OF_MEMORY);
3556 }
3557}
3558
3559void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3560{
3561 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3562 program, location, bufSize, params);
3563
3564 try
3565 {
3566 if (bufSize < 0)
3567 {
3568 return error(GL_INVALID_VALUE);
3569 }
3570
3571 gl::Context *context = gl::getNonLostContext();
3572
3573 if (context)
3574 {
3575 if (program == 0)
3576 {
3577 return error(GL_INVALID_VALUE);
3578 }
3579
3580 gl::Program *programObject = context->getProgram(program);
3581
3582 if (!programObject || !programObject->isLinked())
3583 {
3584 return error(GL_INVALID_OPERATION);
3585 }
3586
3587 if (!programObject)
3588 {
3589 return error(GL_INVALID_OPERATION);
3590 }
3591
3592 if (!programObject->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003593 {
3594 return error(GL_INVALID_OPERATION);
3595 }
3596 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003597 }
3598 catch(std::bad_alloc&)
3599 {
3600 return error(GL_OUT_OF_MEMORY);
3601 }
3602}
3603
3604void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3605{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003606 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003607
3608 try
3609 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003610 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003611
3612 if (context)
3613 {
3614 if (program == 0)
3615 {
3616 return error(GL_INVALID_VALUE);
3617 }
3618
3619 gl::Program *programObject = context->getProgram(program);
3620
3621 if (!programObject || !programObject->isLinked())
3622 {
3623 return error(GL_INVALID_OPERATION);
3624 }
3625
3626 if (!programObject)
3627 {
3628 return error(GL_INVALID_OPERATION);
3629 }
3630
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003631 if (!programObject->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003632 {
3633 return error(GL_INVALID_OPERATION);
3634 }
3635 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003636 }
3637 catch(std::bad_alloc&)
3638 {
3639 return error(GL_OUT_OF_MEMORY);
3640 }
3641}
3642
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003643int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003644{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003645 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003646
3647 try
3648 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003649 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003650
3651 if (strstr(name, "gl_") == name)
3652 {
3653 return -1;
3654 }
3655
3656 if (context)
3657 {
3658 gl::Program *programObject = context->getProgram(program);
3659
3660 if (!programObject)
3661 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003662 if (context->getShader(program))
3663 {
3664 return error(GL_INVALID_OPERATION, -1);
3665 }
3666 else
3667 {
3668 return error(GL_INVALID_VALUE, -1);
3669 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003670 }
3671
3672 if (!programObject->isLinked())
3673 {
3674 return error(GL_INVALID_OPERATION, -1);
3675 }
3676
daniel@transgaming.com024f1a92011-09-20 16:06:25 +00003677 return programObject->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003678 }
3679 }
3680 catch(std::bad_alloc&)
3681 {
3682 return error(GL_OUT_OF_MEMORY, -1);
3683 }
3684
3685 return -1;
3686}
3687
3688void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3689{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003690 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003691
3692 try
3693 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003694 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003695
daniel@transgaming.come0078962010-04-15 20:45:08 +00003696 if (context)
3697 {
3698 if (index >= gl::MAX_VERTEX_ATTRIBS)
3699 {
3700 return error(GL_INVALID_VALUE);
3701 }
3702
daniel@transgaming.com83921382011-01-08 05:46:00 +00003703 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003704
daniel@transgaming.come0078962010-04-15 20:45:08 +00003705 switch (pname)
3706 {
3707 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003708 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003709 break;
3710 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003711 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003712 break;
3713 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003714 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003715 break;
3716 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003717 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003718 break;
3719 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003720 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003721 break;
3722 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003723 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003724 break;
3725 case GL_CURRENT_VERTEX_ATTRIB:
3726 for (int i = 0; i < 4; ++i)
3727 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003728 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003729 }
3730 break;
3731 default: return error(GL_INVALID_ENUM);
3732 }
3733 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003734 }
3735 catch(std::bad_alloc&)
3736 {
3737 return error(GL_OUT_OF_MEMORY);
3738 }
3739}
3740
3741void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3742{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003743 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003744
3745 try
3746 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003747 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003748
daniel@transgaming.come0078962010-04-15 20:45:08 +00003749 if (context)
3750 {
3751 if (index >= gl::MAX_VERTEX_ATTRIBS)
3752 {
3753 return error(GL_INVALID_VALUE);
3754 }
3755
daniel@transgaming.com83921382011-01-08 05:46:00 +00003756 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003757
daniel@transgaming.come0078962010-04-15 20:45:08 +00003758 switch (pname)
3759 {
3760 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003761 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003762 break;
3763 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003764 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003765 break;
3766 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003767 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003768 break;
3769 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003770 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003771 break;
3772 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003773 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003774 break;
3775 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003776 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003777 break;
3778 case GL_CURRENT_VERTEX_ATTRIB:
3779 for (int i = 0; i < 4; ++i)
3780 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003781 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003782 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3783 }
3784 break;
3785 default: return error(GL_INVALID_ENUM);
3786 }
3787 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003788 }
3789 catch(std::bad_alloc&)
3790 {
3791 return error(GL_OUT_OF_MEMORY);
3792 }
3793}
3794
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003795void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003796{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003797 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003798
3799 try
3800 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003801 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003802
daniel@transgaming.come0078962010-04-15 20:45:08 +00003803 if (context)
3804 {
3805 if (index >= gl::MAX_VERTEX_ATTRIBS)
3806 {
3807 return error(GL_INVALID_VALUE);
3808 }
3809
3810 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3811 {
3812 return error(GL_INVALID_ENUM);
3813 }
3814
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003815 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003816 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003817 }
3818 catch(std::bad_alloc&)
3819 {
3820 return error(GL_OUT_OF_MEMORY);
3821 }
3822}
3823
3824void __stdcall glHint(GLenum target, GLenum mode)
3825{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003826 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003827
3828 try
3829 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003830 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003831 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003832 case GL_FASTEST:
3833 case GL_NICEST:
3834 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003835 break;
3836 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003837 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003838 }
3839
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003840 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003841 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003842 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003843 case GL_GENERATE_MIPMAP_HINT:
3844 if (context) context->setGenerateMipmapHint(mode);
3845 break;
3846 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3847 if (context) context->setFragmentShaderDerivativeHint(mode);
3848 break;
3849 default:
3850 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003851 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003852 }
3853 catch(std::bad_alloc&)
3854 {
3855 return error(GL_OUT_OF_MEMORY);
3856 }
3857}
3858
3859GLboolean __stdcall glIsBuffer(GLuint buffer)
3860{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003861 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003862
3863 try
3864 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003865 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003866
3867 if (context && buffer)
3868 {
3869 gl::Buffer *bufferObject = context->getBuffer(buffer);
3870
3871 if (bufferObject)
3872 {
3873 return GL_TRUE;
3874 }
3875 }
3876 }
3877 catch(std::bad_alloc&)
3878 {
3879 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3880 }
3881
3882 return GL_FALSE;
3883}
3884
3885GLboolean __stdcall glIsEnabled(GLenum cap)
3886{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003887 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003888
3889 try
3890 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003891 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003892
3893 if (context)
3894 {
3895 switch (cap)
3896 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003897 case GL_CULL_FACE: return context->isCullFaceEnabled();
3898 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3899 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3900 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3901 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3902 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3903 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3904 case GL_BLEND: return context->isBlendEnabled();
3905 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003906 default:
3907 return error(GL_INVALID_ENUM, false);
3908 }
3909 }
3910 }
3911 catch(std::bad_alloc&)
3912 {
3913 return error(GL_OUT_OF_MEMORY, false);
3914 }
3915
3916 return false;
3917}
3918
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003919GLboolean __stdcall glIsFenceNV(GLuint fence)
3920{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003921 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003922
3923 try
3924 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003925 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003926
3927 if (context)
3928 {
3929 gl::Fence *fenceObject = context->getFence(fence);
3930
3931 if (fenceObject == NULL)
3932 {
3933 return GL_FALSE;
3934 }
3935
3936 return fenceObject->isFence();
3937 }
3938 }
3939 catch(std::bad_alloc&)
3940 {
3941 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3942 }
3943
3944 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003945}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003946
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003947GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3948{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003949 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003950
3951 try
3952 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003953 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003954
3955 if (context && framebuffer)
3956 {
3957 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3958
3959 if (framebufferObject)
3960 {
3961 return GL_TRUE;
3962 }
3963 }
3964 }
3965 catch(std::bad_alloc&)
3966 {
3967 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3968 }
3969
3970 return GL_FALSE;
3971}
3972
3973GLboolean __stdcall glIsProgram(GLuint program)
3974{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003975 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003976
3977 try
3978 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003979 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003980
3981 if (context && program)
3982 {
3983 gl::Program *programObject = context->getProgram(program);
3984
3985 if (programObject)
3986 {
3987 return GL_TRUE;
3988 }
3989 }
3990 }
3991 catch(std::bad_alloc&)
3992 {
3993 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3994 }
3995
3996 return GL_FALSE;
3997}
3998
3999GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
4000{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004001 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004002
4003 try
4004 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004005 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004006
4007 if (context && renderbuffer)
4008 {
4009 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4010
4011 if (renderbufferObject)
4012 {
4013 return GL_TRUE;
4014 }
4015 }
4016 }
4017 catch(std::bad_alloc&)
4018 {
4019 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4020 }
4021
4022 return GL_FALSE;
4023}
4024
4025GLboolean __stdcall glIsShader(GLuint shader)
4026{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004027 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004028
4029 try
4030 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004031 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004032
4033 if (context && shader)
4034 {
4035 gl::Shader *shaderObject = context->getShader(shader);
4036
4037 if (shaderObject)
4038 {
4039 return GL_TRUE;
4040 }
4041 }
4042 }
4043 catch(std::bad_alloc&)
4044 {
4045 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4046 }
4047
4048 return GL_FALSE;
4049}
4050
4051GLboolean __stdcall glIsTexture(GLuint texture)
4052{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004053 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004054
4055 try
4056 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004057 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004058
4059 if (context && texture)
4060 {
4061 gl::Texture *textureObject = context->getTexture(texture);
4062
4063 if (textureObject)
4064 {
4065 return GL_TRUE;
4066 }
4067 }
4068 }
4069 catch(std::bad_alloc&)
4070 {
4071 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4072 }
4073
4074 return GL_FALSE;
4075}
4076
4077void __stdcall glLineWidth(GLfloat width)
4078{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004079 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004080
4081 try
4082 {
4083 if (width <= 0.0f)
4084 {
4085 return error(GL_INVALID_VALUE);
4086 }
4087
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004088 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004089
4090 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004091 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004092 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004093 }
4094 }
4095 catch(std::bad_alloc&)
4096 {
4097 return error(GL_OUT_OF_MEMORY);
4098 }
4099}
4100
4101void __stdcall glLinkProgram(GLuint program)
4102{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004103 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004104
4105 try
4106 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004107 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004108
4109 if (context)
4110 {
4111 gl::Program *programObject = context->getProgram(program);
4112
4113 if (!programObject)
4114 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004115 if (context->getShader(program))
4116 {
4117 return error(GL_INVALID_OPERATION);
4118 }
4119 else
4120 {
4121 return error(GL_INVALID_VALUE);
4122 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004123 }
4124
4125 programObject->link();
4126 }
4127 }
4128 catch(std::bad_alloc&)
4129 {
4130 return error(GL_OUT_OF_MEMORY);
4131 }
4132}
4133
4134void __stdcall glPixelStorei(GLenum pname, GLint param)
4135{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004136 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004137
4138 try
4139 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004140 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004141
4142 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004143 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004144 switch (pname)
4145 {
4146 case GL_UNPACK_ALIGNMENT:
4147 if (param != 1 && param != 2 && param != 4 && param != 8)
4148 {
4149 return error(GL_INVALID_VALUE);
4150 }
4151
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004152 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004153 break;
4154
4155 case GL_PACK_ALIGNMENT:
4156 if (param != 1 && param != 2 && param != 4 && param != 8)
4157 {
4158 return error(GL_INVALID_VALUE);
4159 }
4160
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004161 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004162 break;
4163
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004164 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4165 context->setPackReverseRowOrder(param != 0);
4166 break;
4167
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004168 default:
4169 return error(GL_INVALID_ENUM);
4170 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004171 }
4172 }
4173 catch(std::bad_alloc&)
4174 {
4175 return error(GL_OUT_OF_MEMORY);
4176 }
4177}
4178
4179void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4180{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004181 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004182
4183 try
4184 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004185 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004186
4187 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004188 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004189 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004190 }
4191 }
4192 catch(std::bad_alloc&)
4193 {
4194 return error(GL_OUT_OF_MEMORY);
4195 }
4196}
4197
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004198void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4199 GLenum format, GLenum type, GLsizei bufSize,
4200 GLvoid *data)
4201{
4202 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4203 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4204 x, y, width, height, format, type, bufSize, data);
4205
4206 try
4207 {
4208 if (width < 0 || height < 0 || bufSize < 0)
4209 {
4210 return error(GL_INVALID_VALUE);
4211 }
4212
4213 if (!validReadFormatType(format, type))
4214 {
4215 return error(GL_INVALID_OPERATION);
4216 }
4217
4218 gl::Context *context = gl::getNonLostContext();
4219
4220 if (context)
4221 {
4222 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4223 }
4224 }
4225 catch(std::bad_alloc&)
4226 {
4227 return error(GL_OUT_OF_MEMORY);
4228 }
4229}
4230
4231void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4232 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004233{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004234 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004235 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004236 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004237
4238 try
4239 {
4240 if (width < 0 || height < 0)
4241 {
4242 return error(GL_INVALID_VALUE);
4243 }
4244
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004245 if (!validReadFormatType(format, type))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004246 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004247 return error(GL_INVALID_OPERATION);
4248 }
4249
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004250 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004251
4252 if (context)
4253 {
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004254 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004255 }
4256 }
4257 catch(std::bad_alloc&)
4258 {
4259 return error(GL_OUT_OF_MEMORY);
4260 }
4261}
4262
4263void __stdcall glReleaseShaderCompiler(void)
4264{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004265 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004266
4267 try
4268 {
4269 gl::Shader::releaseCompiler();
4270 }
4271 catch(std::bad_alloc&)
4272 {
4273 return error(GL_OUT_OF_MEMORY);
4274 }
4275}
4276
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004277void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004278{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004279 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 +00004280 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004281
4282 try
4283 {
4284 switch (target)
4285 {
4286 case GL_RENDERBUFFER:
4287 break;
4288 default:
4289 return error(GL_INVALID_ENUM);
4290 }
4291
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004292 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004293 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004294 return error(GL_INVALID_ENUM);
4295 }
4296
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004297 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004298 {
4299 return error(GL_INVALID_VALUE);
4300 }
4301
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004302 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004303
4304 if (context)
4305 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004306 if (width > context->getMaximumRenderbufferDimension() ||
4307 height > context->getMaximumRenderbufferDimension() ||
4308 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004309 {
4310 return error(GL_INVALID_VALUE);
4311 }
4312
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004313 GLuint handle = context->getRenderbufferHandle();
4314 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004315 {
4316 return error(GL_INVALID_OPERATION);
4317 }
4318
4319 switch (internalformat)
4320 {
4321 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004322 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004323 break;
4324 case GL_RGBA4:
4325 case GL_RGB5_A1:
4326 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004327 case GL_RGB8_OES:
4328 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004329 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004330 break;
4331 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004332 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004333 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004334 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004335 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004336 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004337 default:
4338 return error(GL_INVALID_ENUM);
4339 }
4340 }
4341 }
4342 catch(std::bad_alloc&)
4343 {
4344 return error(GL_OUT_OF_MEMORY);
4345 }
4346}
4347
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004348void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4349{
4350 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4351}
4352
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004353void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4354{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004355 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004356
4357 try
4358 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004359 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004360
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004361 if (context)
4362 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004363 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004364 }
4365 }
4366 catch(std::bad_alloc&)
4367 {
4368 return error(GL_OUT_OF_MEMORY);
4369 }
4370}
4371
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004372void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4373{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004374 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004375
4376 try
4377 {
4378 if (condition != GL_ALL_COMPLETED_NV)
4379 {
4380 return error(GL_INVALID_ENUM);
4381 }
4382
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004383 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004384
4385 if (context)
4386 {
4387 gl::Fence *fenceObject = context->getFence(fence);
4388
4389 if (fenceObject == NULL)
4390 {
4391 return error(GL_INVALID_OPERATION);
4392 }
4393
4394 fenceObject->setFence(condition);
4395 }
4396 }
4397 catch(std::bad_alloc&)
4398 {
4399 return error(GL_OUT_OF_MEMORY);
4400 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004401}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004402
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004403void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4404{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004405 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 +00004406
4407 try
4408 {
4409 if (width < 0 || height < 0)
4410 {
4411 return error(GL_INVALID_VALUE);
4412 }
4413
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004414 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004415
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004416 if (context)
4417 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004418 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004419 }
4420 }
4421 catch(std::bad_alloc&)
4422 {
4423 return error(GL_OUT_OF_MEMORY);
4424 }
4425}
4426
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004427void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004428{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004429 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004430 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004431 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004432
4433 try
4434 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004435 // No binary shader formats are supported.
4436 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004437 }
4438 catch(std::bad_alloc&)
4439 {
4440 return error(GL_OUT_OF_MEMORY);
4441 }
4442}
4443
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004444void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004445{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004446 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 +00004447 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004448
4449 try
4450 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004451 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004452 {
4453 return error(GL_INVALID_VALUE);
4454 }
4455
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004456 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004457
4458 if (context)
4459 {
4460 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004461
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004462 if (!shaderObject)
4463 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004464 if (context->getProgram(shader))
4465 {
4466 return error(GL_INVALID_OPERATION);
4467 }
4468 else
4469 {
4470 return error(GL_INVALID_VALUE);
4471 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004472 }
4473
4474 shaderObject->setSource(count, string, length);
4475 }
4476 }
4477 catch(std::bad_alloc&)
4478 {
4479 return error(GL_OUT_OF_MEMORY);
4480 }
4481}
4482
4483void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4484{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004485 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004486}
4487
4488void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4489{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004490 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 +00004491
4492 try
4493 {
4494 switch (face)
4495 {
4496 case GL_FRONT:
4497 case GL_BACK:
4498 case GL_FRONT_AND_BACK:
4499 break;
4500 default:
4501 return error(GL_INVALID_ENUM);
4502 }
4503
4504 switch (func)
4505 {
4506 case GL_NEVER:
4507 case GL_ALWAYS:
4508 case GL_LESS:
4509 case GL_LEQUAL:
4510 case GL_EQUAL:
4511 case GL_GEQUAL:
4512 case GL_GREATER:
4513 case GL_NOTEQUAL:
4514 break;
4515 default:
4516 return error(GL_INVALID_ENUM);
4517 }
4518
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004519 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004520
4521 if (context)
4522 {
4523 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4524 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004525 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004526 }
4527
4528 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4529 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004530 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004531 }
4532 }
4533 }
4534 catch(std::bad_alloc&)
4535 {
4536 return error(GL_OUT_OF_MEMORY);
4537 }
4538}
4539
4540void __stdcall glStencilMask(GLuint mask)
4541{
4542 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4543}
4544
4545void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4546{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004547 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004548
4549 try
4550 {
4551 switch (face)
4552 {
4553 case GL_FRONT:
4554 case GL_BACK:
4555 case GL_FRONT_AND_BACK:
4556 break;
4557 default:
4558 return error(GL_INVALID_ENUM);
4559 }
4560
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004561 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004562
4563 if (context)
4564 {
4565 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4566 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004567 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004568 }
4569
4570 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4571 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004572 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004573 }
4574 }
4575 }
4576 catch(std::bad_alloc&)
4577 {
4578 return error(GL_OUT_OF_MEMORY);
4579 }
4580}
4581
4582void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4583{
4584 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4585}
4586
4587void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4588{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004589 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 +00004590 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004591
4592 try
4593 {
4594 switch (face)
4595 {
4596 case GL_FRONT:
4597 case GL_BACK:
4598 case GL_FRONT_AND_BACK:
4599 break;
4600 default:
4601 return error(GL_INVALID_ENUM);
4602 }
4603
4604 switch (fail)
4605 {
4606 case GL_ZERO:
4607 case GL_KEEP:
4608 case GL_REPLACE:
4609 case GL_INCR:
4610 case GL_DECR:
4611 case GL_INVERT:
4612 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004613 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004614 break;
4615 default:
4616 return error(GL_INVALID_ENUM);
4617 }
4618
4619 switch (zfail)
4620 {
4621 case GL_ZERO:
4622 case GL_KEEP:
4623 case GL_REPLACE:
4624 case GL_INCR:
4625 case GL_DECR:
4626 case GL_INVERT:
4627 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004628 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004629 break;
4630 default:
4631 return error(GL_INVALID_ENUM);
4632 }
4633
4634 switch (zpass)
4635 {
4636 case GL_ZERO:
4637 case GL_KEEP:
4638 case GL_REPLACE:
4639 case GL_INCR:
4640 case GL_DECR:
4641 case GL_INVERT:
4642 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004643 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004644 break;
4645 default:
4646 return error(GL_INVALID_ENUM);
4647 }
4648
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004649 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004650
4651 if (context)
4652 {
4653 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4654 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004655 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004656 }
4657
4658 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4659 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004660 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004661 }
4662 }
4663 }
4664 catch(std::bad_alloc&)
4665 {
4666 return error(GL_OUT_OF_MEMORY);
4667 }
4668}
4669
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004670GLboolean __stdcall glTestFenceNV(GLuint fence)
4671{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004672 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004673
4674 try
4675 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004676 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004677
4678 if (context)
4679 {
4680 gl::Fence *fenceObject = context->getFence(fence);
4681
4682 if (fenceObject == NULL)
4683 {
4684 return error(GL_INVALID_OPERATION, GL_TRUE);
4685 }
4686
4687 return fenceObject->testFence();
4688 }
4689 }
4690 catch(std::bad_alloc&)
4691 {
4692 error(GL_OUT_OF_MEMORY);
4693 }
4694
4695 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004696}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004697
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004698void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4699 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004700{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004701 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 +00004702 "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 +00004703 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004704
4705 try
4706 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00004707 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004708 {
4709 return error(GL_INVALID_VALUE);
4710 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004711
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004712 if (internalformat != format)
4713 {
4714 return error(GL_INVALID_OPERATION);
4715 }
4716
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004717 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004718 {
4719 case GL_ALPHA:
4720 case GL_LUMINANCE:
4721 case GL_LUMINANCE_ALPHA:
4722 switch (type)
4723 {
4724 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004725 case GL_FLOAT:
4726 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004727 break;
4728 default:
4729 return error(GL_INVALID_ENUM);
4730 }
4731 break;
4732 case GL_RGB:
4733 switch (type)
4734 {
4735 case GL_UNSIGNED_BYTE:
4736 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004737 case GL_FLOAT:
4738 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004739 break;
4740 default:
4741 return error(GL_INVALID_ENUM);
4742 }
4743 break;
4744 case GL_RGBA:
4745 switch (type)
4746 {
4747 case GL_UNSIGNED_BYTE:
4748 case GL_UNSIGNED_SHORT_4_4_4_4:
4749 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004750 case GL_FLOAT:
4751 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004752 break;
4753 default:
4754 return error(GL_INVALID_ENUM);
4755 }
4756 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004757 case GL_BGRA_EXT:
4758 switch (type)
4759 {
4760 case GL_UNSIGNED_BYTE:
4761 break;
4762 default:
4763 return error(GL_INVALID_ENUM);
4764 }
4765 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004766 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4767 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00004768 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4769 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00004770 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004771 default:
4772 return error(GL_INVALID_VALUE);
4773 }
4774
4775 if (border != 0)
4776 {
4777 return error(GL_INVALID_VALUE);
4778 }
4779
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004780 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004781
4782 if (context)
4783 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00004784 if (level > context->getMaximumTextureLevel())
4785 {
4786 return error(GL_INVALID_VALUE);
4787 }
4788
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004789 switch (target)
4790 {
4791 case GL_TEXTURE_2D:
4792 if (width > (context->getMaximumTextureDimension() >> level) ||
4793 height > (context->getMaximumTextureDimension() >> level))
4794 {
4795 return error(GL_INVALID_VALUE);
4796 }
4797 break;
4798 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4799 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4800 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4801 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4802 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4803 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4804 if (width != height)
4805 {
4806 return error(GL_INVALID_VALUE);
4807 }
4808
4809 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4810 height > (context->getMaximumCubeTextureDimension() >> level))
4811 {
4812 return error(GL_INVALID_VALUE);
4813 }
4814 break;
4815 default:
4816 return error(GL_INVALID_ENUM);
4817 }
4818
gman@chromium.org50c526d2011-08-10 05:19:44 +00004819 switch (format) {
4820 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
4821 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4822 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00004823 {
4824 return error(GL_INVALID_OPERATION);
4825 }
4826 else
4827 {
4828 return error(GL_INVALID_ENUM);
4829 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00004830 break;
4831 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4832 if (context->supportsDXT3Textures())
4833 {
4834 return error(GL_INVALID_OPERATION);
4835 }
4836 else
4837 {
4838 return error(GL_INVALID_ENUM);
4839 }
4840 break;
4841 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
4842 if (context->supportsDXT5Textures())
4843 {
4844 return error(GL_INVALID_OPERATION);
4845 }
4846 else
4847 {
4848 return error(GL_INVALID_ENUM);
4849 }
4850 break;
4851 default:
4852 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004853 }
4854
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004855 if (type == GL_FLOAT)
4856 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004857 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004858 {
4859 return error(GL_INVALID_ENUM);
4860 }
4861 }
4862 else if (type == GL_HALF_FLOAT_OES)
4863 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004864 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004865 {
4866 return error(GL_INVALID_ENUM);
4867 }
4868 }
4869
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004870 if (target == GL_TEXTURE_2D)
4871 {
4872 gl::Texture2D *texture = context->getTexture2D();
4873
4874 if (!texture)
4875 {
4876 return error(GL_INVALID_OPERATION);
4877 }
4878
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004879 if (texture->isImmutable())
4880 {
4881 return error(GL_INVALID_OPERATION);
4882 }
4883
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004884 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004885 }
4886 else
4887 {
4888 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4889
4890 if (!texture)
4891 {
4892 return error(GL_INVALID_OPERATION);
4893 }
4894
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004895 if (texture->isImmutable())
4896 {
4897 return error(GL_INVALID_OPERATION);
4898 }
4899
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004900 switch (target)
4901 {
4902 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004903 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004904 break;
4905 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004906 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004907 break;
4908 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004909 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004910 break;
4911 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004912 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004913 break;
4914 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004915 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004916 break;
4917 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004918 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004919 break;
4920 default: UNREACHABLE();
4921 }
4922 }
4923 }
4924 }
4925 catch(std::bad_alloc&)
4926 {
4927 return error(GL_OUT_OF_MEMORY);
4928 }
4929}
4930
4931void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4932{
4933 glTexParameteri(target, pname, (GLint)param);
4934}
4935
4936void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4937{
4938 glTexParameteri(target, pname, (GLint)*params);
4939}
4940
4941void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4942{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004943 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004944
4945 try
4946 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004947 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004948
4949 if (context)
4950 {
4951 gl::Texture *texture;
4952
4953 switch (target)
4954 {
4955 case GL_TEXTURE_2D:
4956 texture = context->getTexture2D();
4957 break;
4958 case GL_TEXTURE_CUBE_MAP:
4959 texture = context->getTextureCubeMap();
4960 break;
4961 default:
4962 return error(GL_INVALID_ENUM);
4963 }
4964
4965 switch (pname)
4966 {
4967 case GL_TEXTURE_WRAP_S:
4968 if (!texture->setWrapS((GLenum)param))
4969 {
4970 return error(GL_INVALID_ENUM);
4971 }
4972 break;
4973 case GL_TEXTURE_WRAP_T:
4974 if (!texture->setWrapT((GLenum)param))
4975 {
4976 return error(GL_INVALID_ENUM);
4977 }
4978 break;
4979 case GL_TEXTURE_MIN_FILTER:
4980 if (!texture->setMinFilter((GLenum)param))
4981 {
4982 return error(GL_INVALID_ENUM);
4983 }
4984 break;
4985 case GL_TEXTURE_MAG_FILTER:
4986 if (!texture->setMagFilter((GLenum)param))
4987 {
4988 return error(GL_INVALID_ENUM);
4989 }
4990 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00004991 case GL_TEXTURE_USAGE_ANGLE:
4992 if (!texture->setUsage((GLenum)param))
4993 {
4994 return error(GL_INVALID_ENUM);
4995 }
4996 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004997 default:
4998 return error(GL_INVALID_ENUM);
4999 }
5000 }
5001 }
5002 catch(std::bad_alloc&)
5003 {
5004 return error(GL_OUT_OF_MEMORY);
5005 }
5006}
5007
5008void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5009{
5010 glTexParameteri(target, pname, *params);
5011}
5012
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005013void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5014{
5015 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5016 target, levels, internalformat, width, height);
5017
5018 try
5019 {
5020 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5021 {
5022 return error(GL_INVALID_ENUM);
5023 }
5024
5025 if (width < 1 || height < 1 || levels < 1)
5026 {
5027 return error(GL_INVALID_VALUE);
5028 }
5029
5030 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5031 {
5032 return error(GL_INVALID_VALUE);
5033 }
5034
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005035 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005036 {
5037 return error(GL_INVALID_OPERATION);
5038 }
5039
5040 GLenum format = gl::ExtractFormat(internalformat);
5041 GLenum type = gl::ExtractType(internalformat);
5042
5043 if (format == GL_NONE || type == GL_NONE)
5044 {
5045 return error(GL_INVALID_ENUM);
5046 }
5047
5048 gl::Context *context = gl::getNonLostContext();
5049
5050 if (context)
5051 {
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005052 switch (target)
5053 {
5054 case GL_TEXTURE_2D:
5055 if (width > context->getMaximumTextureDimension() ||
5056 height > context->getMaximumTextureDimension())
5057 {
5058 return error(GL_INVALID_VALUE);
5059 }
5060 break;
5061 case GL_TEXTURE_CUBE_MAP:
5062 if (width > context->getMaximumCubeTextureDimension() ||
5063 height > context->getMaximumCubeTextureDimension())
5064 {
5065 return error(GL_INVALID_VALUE);
5066 }
5067 break;
5068 default:
5069 return error(GL_INVALID_ENUM);
5070 }
5071
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005072 if (levels != 1 && !context->supportsNonPower2Texture())
5073 {
5074 if (!gl::isPow2(width) || !gl::isPow2(height))
5075 {
5076 return error(GL_INVALID_OPERATION);
5077 }
5078 }
5079
daniel@transgaming.come1077362011-11-11 04:16:50 +00005080 switch (internalformat)
5081 {
5082 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5083 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5084 if (!context->supportsDXT1Textures())
5085 {
5086 return error(GL_INVALID_ENUM);
5087 }
5088 break;
5089 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5090 if (!context->supportsDXT3Textures())
5091 {
5092 return error(GL_INVALID_ENUM);
5093 }
5094 break;
5095 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5096 if (!context->supportsDXT5Textures())
5097 {
5098 return error(GL_INVALID_ENUM);
5099 }
5100 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005101 case GL_RGBA32F_EXT:
5102 case GL_RGB32F_EXT:
5103 case GL_ALPHA32F_EXT:
5104 case GL_LUMINANCE32F_EXT:
5105 case GL_LUMINANCE_ALPHA32F_EXT:
5106 if (!context->supportsFloat32Textures())
5107 {
5108 return error(GL_INVALID_ENUM);
5109 }
5110 break;
5111 case GL_RGBA16F_EXT:
5112 case GL_RGB16F_EXT:
5113 case GL_ALPHA16F_EXT:
5114 case GL_LUMINANCE16F_EXT:
5115 case GL_LUMINANCE_ALPHA16F_EXT:
5116 if (!context->supportsFloat16Textures())
5117 {
5118 return error(GL_INVALID_ENUM);
5119 }
5120 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005121 }
5122
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005123 if (target == GL_TEXTURE_2D)
5124 {
5125 gl::Texture2D *texture = context->getTexture2D();
5126
5127 if (!texture || texture->id() == 0)
5128 {
5129 return error(GL_INVALID_OPERATION);
5130 }
5131
5132 if (texture->isImmutable())
5133 {
5134 return error(GL_INVALID_OPERATION);
5135 }
5136
5137 texture->storage(levels, internalformat, width, height);
5138 }
5139 else if (target == GL_TEXTURE_CUBE_MAP)
5140 {
5141 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5142
5143 if (!texture || texture->id() == 0)
5144 {
5145 return error(GL_INVALID_OPERATION);
5146 }
5147
5148 if (texture->isImmutable())
5149 {
5150 return error(GL_INVALID_OPERATION);
5151 }
5152
5153 texture->storage(levels, internalformat, width);
5154 }
5155 else UNREACHABLE();
5156 }
5157 }
5158 catch(std::bad_alloc&)
5159 {
5160 return error(GL_OUT_OF_MEMORY);
5161 }
5162}
5163
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005164void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5165 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005166{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005167 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005168 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005169 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005170 target, level, xoffset, yoffset, width, height, format, type, pixels);
5171
5172 try
5173 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005174 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005175 {
5176 return error(GL_INVALID_ENUM);
5177 }
5178
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005179 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005180 {
5181 return error(GL_INVALID_VALUE);
5182 }
5183
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005184 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5185 {
5186 return error(GL_INVALID_VALUE);
5187 }
5188
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005189 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005190 {
5191 return error(GL_INVALID_ENUM);
5192 }
5193
5194 if (width == 0 || height == 0 || pixels == NULL)
5195 {
5196 return;
5197 }
5198
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005199 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005200
5201 if (context)
5202 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005203 if (level > context->getMaximumTextureLevel())
5204 {
5205 return error(GL_INVALID_VALUE);
5206 }
5207
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005208 if (format == GL_FLOAT)
5209 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005210 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005211 {
5212 return error(GL_INVALID_ENUM);
5213 }
5214 }
5215 else if (format == GL_HALF_FLOAT_OES)
5216 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005217 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005218 {
5219 return error(GL_INVALID_ENUM);
5220 }
5221 }
5222
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005223 if (target == GL_TEXTURE_2D)
5224 {
5225 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005226 if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005227 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005228 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005229 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005230 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005231 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005232 {
5233 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005234 if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005235 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005236 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005237 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005238 }
5239 else
5240 {
5241 UNREACHABLE();
5242 }
5243 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005244 }
5245 catch(std::bad_alloc&)
5246 {
5247 return error(GL_OUT_OF_MEMORY);
5248 }
5249}
5250
5251void __stdcall glUniform1f(GLint location, GLfloat x)
5252{
5253 glUniform1fv(location, 1, &x);
5254}
5255
5256void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5257{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005258 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005259
5260 try
5261 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005262 if (count < 0)
5263 {
5264 return error(GL_INVALID_VALUE);
5265 }
5266
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005267 if (location == -1)
5268 {
5269 return;
5270 }
5271
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005272 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005273
5274 if (context)
5275 {
5276 gl::Program *program = context->getCurrentProgram();
5277
5278 if (!program)
5279 {
5280 return error(GL_INVALID_OPERATION);
5281 }
5282
5283 if (!program->setUniform1fv(location, count, v))
5284 {
5285 return error(GL_INVALID_OPERATION);
5286 }
5287 }
5288 }
5289 catch(std::bad_alloc&)
5290 {
5291 return error(GL_OUT_OF_MEMORY);
5292 }
5293}
5294
5295void __stdcall glUniform1i(GLint location, GLint x)
5296{
5297 glUniform1iv(location, 1, &x);
5298}
5299
5300void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5301{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005302 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005303
5304 try
5305 {
5306 if (count < 0)
5307 {
5308 return error(GL_INVALID_VALUE);
5309 }
5310
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005311 if (location == -1)
5312 {
5313 return;
5314 }
5315
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005316 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005317
5318 if (context)
5319 {
5320 gl::Program *program = context->getCurrentProgram();
5321
5322 if (!program)
5323 {
5324 return error(GL_INVALID_OPERATION);
5325 }
5326
5327 if (!program->setUniform1iv(location, count, v))
5328 {
5329 return error(GL_INVALID_OPERATION);
5330 }
5331 }
5332 }
5333 catch(std::bad_alloc&)
5334 {
5335 return error(GL_OUT_OF_MEMORY);
5336 }
5337}
5338
5339void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5340{
5341 GLfloat xy[2] = {x, y};
5342
5343 glUniform2fv(location, 1, (GLfloat*)&xy);
5344}
5345
5346void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5347{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005348 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005349
5350 try
5351 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005352 if (count < 0)
5353 {
5354 return error(GL_INVALID_VALUE);
5355 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005356
5357 if (location == -1)
5358 {
5359 return;
5360 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005361
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005362 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005363
5364 if (context)
5365 {
5366 gl::Program *program = context->getCurrentProgram();
5367
5368 if (!program)
5369 {
5370 return error(GL_INVALID_OPERATION);
5371 }
5372
5373 if (!program->setUniform2fv(location, count, v))
5374 {
5375 return error(GL_INVALID_OPERATION);
5376 }
5377 }
5378 }
5379 catch(std::bad_alloc&)
5380 {
5381 return error(GL_OUT_OF_MEMORY);
5382 }
5383}
5384
5385void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5386{
5387 GLint xy[4] = {x, y};
5388
5389 glUniform2iv(location, 1, (GLint*)&xy);
5390}
5391
5392void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5393{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005394 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005395
5396 try
5397 {
5398 if (count < 0)
5399 {
5400 return error(GL_INVALID_VALUE);
5401 }
5402
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005403 if (location == -1)
5404 {
5405 return;
5406 }
5407
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005408 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005409
5410 if (context)
5411 {
5412 gl::Program *program = context->getCurrentProgram();
5413
5414 if (!program)
5415 {
5416 return error(GL_INVALID_OPERATION);
5417 }
5418
5419 if (!program->setUniform2iv(location, count, v))
5420 {
5421 return error(GL_INVALID_OPERATION);
5422 }
5423 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005424 }
5425 catch(std::bad_alloc&)
5426 {
5427 return error(GL_OUT_OF_MEMORY);
5428 }
5429}
5430
5431void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5432{
5433 GLfloat xyz[3] = {x, y, z};
5434
5435 glUniform3fv(location, 1, (GLfloat*)&xyz);
5436}
5437
5438void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5439{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005440 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005441
5442 try
5443 {
5444 if (count < 0)
5445 {
5446 return error(GL_INVALID_VALUE);
5447 }
5448
5449 if (location == -1)
5450 {
5451 return;
5452 }
5453
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005454 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005455
5456 if (context)
5457 {
5458 gl::Program *program = context->getCurrentProgram();
5459
5460 if (!program)
5461 {
5462 return error(GL_INVALID_OPERATION);
5463 }
5464
5465 if (!program->setUniform3fv(location, count, v))
5466 {
5467 return error(GL_INVALID_OPERATION);
5468 }
5469 }
5470 }
5471 catch(std::bad_alloc&)
5472 {
5473 return error(GL_OUT_OF_MEMORY);
5474 }
5475}
5476
5477void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5478{
5479 GLint xyz[3] = {x, y, z};
5480
5481 glUniform3iv(location, 1, (GLint*)&xyz);
5482}
5483
5484void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5485{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005486 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005487
5488 try
5489 {
5490 if (count < 0)
5491 {
5492 return error(GL_INVALID_VALUE);
5493 }
5494
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005495 if (location == -1)
5496 {
5497 return;
5498 }
5499
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005500 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005501
5502 if (context)
5503 {
5504 gl::Program *program = context->getCurrentProgram();
5505
5506 if (!program)
5507 {
5508 return error(GL_INVALID_OPERATION);
5509 }
5510
5511 if (!program->setUniform3iv(location, count, v))
5512 {
5513 return error(GL_INVALID_OPERATION);
5514 }
5515 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005516 }
5517 catch(std::bad_alloc&)
5518 {
5519 return error(GL_OUT_OF_MEMORY);
5520 }
5521}
5522
5523void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5524{
5525 GLfloat xyzw[4] = {x, y, z, w};
5526
5527 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5528}
5529
5530void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5531{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005532 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005533
5534 try
5535 {
5536 if (count < 0)
5537 {
5538 return error(GL_INVALID_VALUE);
5539 }
5540
5541 if (location == -1)
5542 {
5543 return;
5544 }
5545
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005546 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005547
5548 if (context)
5549 {
5550 gl::Program *program = context->getCurrentProgram();
5551
5552 if (!program)
5553 {
5554 return error(GL_INVALID_OPERATION);
5555 }
5556
5557 if (!program->setUniform4fv(location, count, v))
5558 {
5559 return error(GL_INVALID_OPERATION);
5560 }
5561 }
5562 }
5563 catch(std::bad_alloc&)
5564 {
5565 return error(GL_OUT_OF_MEMORY);
5566 }
5567}
5568
5569void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5570{
5571 GLint xyzw[4] = {x, y, z, w};
5572
5573 glUniform4iv(location, 1, (GLint*)&xyzw);
5574}
5575
5576void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5577{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005578 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005579
5580 try
5581 {
5582 if (count < 0)
5583 {
5584 return error(GL_INVALID_VALUE);
5585 }
5586
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005587 if (location == -1)
5588 {
5589 return;
5590 }
5591
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005592 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005593
5594 if (context)
5595 {
5596 gl::Program *program = context->getCurrentProgram();
5597
5598 if (!program)
5599 {
5600 return error(GL_INVALID_OPERATION);
5601 }
5602
5603 if (!program->setUniform4iv(location, count, v))
5604 {
5605 return error(GL_INVALID_OPERATION);
5606 }
5607 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005608 }
5609 catch(std::bad_alloc&)
5610 {
5611 return error(GL_OUT_OF_MEMORY);
5612 }
5613}
5614
5615void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5616{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005617 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005618 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005619
5620 try
5621 {
5622 if (count < 0 || transpose != GL_FALSE)
5623 {
5624 return error(GL_INVALID_VALUE);
5625 }
5626
5627 if (location == -1)
5628 {
5629 return;
5630 }
5631
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005632 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005633
5634 if (context)
5635 {
5636 gl::Program *program = context->getCurrentProgram();
5637
5638 if (!program)
5639 {
5640 return error(GL_INVALID_OPERATION);
5641 }
5642
5643 if (!program->setUniformMatrix2fv(location, count, value))
5644 {
5645 return error(GL_INVALID_OPERATION);
5646 }
5647 }
5648 }
5649 catch(std::bad_alloc&)
5650 {
5651 return error(GL_OUT_OF_MEMORY);
5652 }
5653}
5654
5655void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5656{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005657 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005658 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005659
5660 try
5661 {
5662 if (count < 0 || transpose != GL_FALSE)
5663 {
5664 return error(GL_INVALID_VALUE);
5665 }
5666
5667 if (location == -1)
5668 {
5669 return;
5670 }
5671
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005672 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005673
5674 if (context)
5675 {
5676 gl::Program *program = context->getCurrentProgram();
5677
5678 if (!program)
5679 {
5680 return error(GL_INVALID_OPERATION);
5681 }
5682
5683 if (!program->setUniformMatrix3fv(location, count, value))
5684 {
5685 return error(GL_INVALID_OPERATION);
5686 }
5687 }
5688 }
5689 catch(std::bad_alloc&)
5690 {
5691 return error(GL_OUT_OF_MEMORY);
5692 }
5693}
5694
5695void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5696{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005697 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005698 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005699
5700 try
5701 {
5702 if (count < 0 || transpose != GL_FALSE)
5703 {
5704 return error(GL_INVALID_VALUE);
5705 }
5706
5707 if (location == -1)
5708 {
5709 return;
5710 }
5711
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005712 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005713
5714 if (context)
5715 {
5716 gl::Program *program = context->getCurrentProgram();
5717
5718 if (!program)
5719 {
5720 return error(GL_INVALID_OPERATION);
5721 }
5722
5723 if (!program->setUniformMatrix4fv(location, count, value))
5724 {
5725 return error(GL_INVALID_OPERATION);
5726 }
5727 }
5728 }
5729 catch(std::bad_alloc&)
5730 {
5731 return error(GL_OUT_OF_MEMORY);
5732 }
5733}
5734
5735void __stdcall glUseProgram(GLuint program)
5736{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005737 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005738
5739 try
5740 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005741 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005742
5743 if (context)
5744 {
5745 gl::Program *programObject = context->getProgram(program);
5746
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005747 if (!programObject && program != 0)
5748 {
5749 if (context->getShader(program))
5750 {
5751 return error(GL_INVALID_OPERATION);
5752 }
5753 else
5754 {
5755 return error(GL_INVALID_VALUE);
5756 }
5757 }
5758
5759 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005760 {
5761 return error(GL_INVALID_OPERATION);
5762 }
5763
5764 context->useProgram(program);
5765 }
5766 }
5767 catch(std::bad_alloc&)
5768 {
5769 return error(GL_OUT_OF_MEMORY);
5770 }
5771}
5772
5773void __stdcall glValidateProgram(GLuint program)
5774{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005775 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005776
5777 try
5778 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005779 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005780
5781 if (context)
5782 {
5783 gl::Program *programObject = context->getProgram(program);
5784
5785 if (!programObject)
5786 {
5787 if (context->getShader(program))
5788 {
5789 return error(GL_INVALID_OPERATION);
5790 }
5791 else
5792 {
5793 return error(GL_INVALID_VALUE);
5794 }
5795 }
5796
5797 programObject->validate();
5798 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005799 }
5800 catch(std::bad_alloc&)
5801 {
5802 return error(GL_OUT_OF_MEMORY);
5803 }
5804}
5805
5806void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5807{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005808 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005809
5810 try
5811 {
5812 if (index >= gl::MAX_VERTEX_ATTRIBS)
5813 {
5814 return error(GL_INVALID_VALUE);
5815 }
5816
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005817 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005818
5819 if (context)
5820 {
5821 GLfloat vals[4] = { x, 0, 0, 1 };
5822 context->setVertexAttrib(index, vals);
5823 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005824 }
5825 catch(std::bad_alloc&)
5826 {
5827 return error(GL_OUT_OF_MEMORY);
5828 }
5829}
5830
5831void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5832{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005833 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005834
5835 try
5836 {
5837 if (index >= gl::MAX_VERTEX_ATTRIBS)
5838 {
5839 return error(GL_INVALID_VALUE);
5840 }
5841
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005842 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005843
5844 if (context)
5845 {
5846 GLfloat vals[4] = { values[0], 0, 0, 1 };
5847 context->setVertexAttrib(index, vals);
5848 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005849 }
5850 catch(std::bad_alloc&)
5851 {
5852 return error(GL_OUT_OF_MEMORY);
5853 }
5854}
5855
5856void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5857{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005858 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005859
5860 try
5861 {
5862 if (index >= gl::MAX_VERTEX_ATTRIBS)
5863 {
5864 return error(GL_INVALID_VALUE);
5865 }
5866
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005867 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005868
5869 if (context)
5870 {
5871 GLfloat vals[4] = { x, y, 0, 1 };
5872 context->setVertexAttrib(index, vals);
5873 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005874 }
5875 catch(std::bad_alloc&)
5876 {
5877 return error(GL_OUT_OF_MEMORY);
5878 }
5879}
5880
5881void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5882{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005883 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005884
5885 try
5886 {
5887 if (index >= gl::MAX_VERTEX_ATTRIBS)
5888 {
5889 return error(GL_INVALID_VALUE);
5890 }
5891
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005892 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005893
5894 if (context)
5895 {
5896 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5897 context->setVertexAttrib(index, vals);
5898 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005899 }
5900 catch(std::bad_alloc&)
5901 {
5902 return error(GL_OUT_OF_MEMORY);
5903 }
5904}
5905
5906void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5907{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005908 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 +00005909
5910 try
5911 {
5912 if (index >= gl::MAX_VERTEX_ATTRIBS)
5913 {
5914 return error(GL_INVALID_VALUE);
5915 }
5916
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005917 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005918
5919 if (context)
5920 {
5921 GLfloat vals[4] = { x, y, z, 1 };
5922 context->setVertexAttrib(index, vals);
5923 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005924 }
5925 catch(std::bad_alloc&)
5926 {
5927 return error(GL_OUT_OF_MEMORY);
5928 }
5929}
5930
5931void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5932{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005933 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005934
5935 try
5936 {
5937 if (index >= gl::MAX_VERTEX_ATTRIBS)
5938 {
5939 return error(GL_INVALID_VALUE);
5940 }
5941
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005942 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005943
5944 if (context)
5945 {
5946 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5947 context->setVertexAttrib(index, vals);
5948 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005949 }
5950 catch(std::bad_alloc&)
5951 {
5952 return error(GL_OUT_OF_MEMORY);
5953 }
5954}
5955
5956void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5957{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005958 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 +00005959
5960 try
5961 {
5962 if (index >= gl::MAX_VERTEX_ATTRIBS)
5963 {
5964 return error(GL_INVALID_VALUE);
5965 }
5966
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005967 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005968
5969 if (context)
5970 {
5971 GLfloat vals[4] = { x, y, z, w };
5972 context->setVertexAttrib(index, vals);
5973 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005974 }
5975 catch(std::bad_alloc&)
5976 {
5977 return error(GL_OUT_OF_MEMORY);
5978 }
5979}
5980
5981void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5982{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005983 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005984
5985 try
5986 {
5987 if (index >= gl::MAX_VERTEX_ATTRIBS)
5988 {
5989 return error(GL_INVALID_VALUE);
5990 }
5991
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005992 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005993
5994 if (context)
5995 {
5996 context->setVertexAttrib(index, values);
5997 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005998 }
5999 catch(std::bad_alloc&)
6000 {
6001 return error(GL_OUT_OF_MEMORY);
6002 }
6003}
6004
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006005void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006006{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006007 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006008 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006009 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006010
6011 try
6012 {
6013 if (index >= gl::MAX_VERTEX_ATTRIBS)
6014 {
6015 return error(GL_INVALID_VALUE);
6016 }
6017
6018 if (size < 1 || size > 4)
6019 {
6020 return error(GL_INVALID_VALUE);
6021 }
6022
6023 switch (type)
6024 {
6025 case GL_BYTE:
6026 case GL_UNSIGNED_BYTE:
6027 case GL_SHORT:
6028 case GL_UNSIGNED_SHORT:
6029 case GL_FIXED:
6030 case GL_FLOAT:
6031 break;
6032 default:
6033 return error(GL_INVALID_ENUM);
6034 }
6035
6036 if (stride < 0)
6037 {
6038 return error(GL_INVALID_VALUE);
6039 }
6040
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006041 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006042
6043 if (context)
6044 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006045 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006046 }
6047 }
6048 catch(std::bad_alloc&)
6049 {
6050 return error(GL_OUT_OF_MEMORY);
6051 }
6052}
6053
6054void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6055{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006056 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 +00006057
6058 try
6059 {
6060 if (width < 0 || height < 0)
6061 {
6062 return error(GL_INVALID_VALUE);
6063 }
6064
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006065 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006066
6067 if (context)
6068 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006069 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006070 }
6071 }
6072 catch(std::bad_alloc&)
6073 {
6074 return error(GL_OUT_OF_MEMORY);
6075 }
6076}
6077
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006078void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6079 GLbitfield mask, GLenum filter)
6080{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006081 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006082 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6083 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6084 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6085
6086 try
6087 {
6088 switch (filter)
6089 {
6090 case GL_NEAREST:
6091 break;
6092 default:
6093 return error(GL_INVALID_ENUM);
6094 }
6095
6096 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6097 {
6098 return error(GL_INVALID_VALUE);
6099 }
6100
6101 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6102 {
6103 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6104 return error(GL_INVALID_OPERATION);
6105 }
6106
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006107 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006108
6109 if (context)
6110 {
6111 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6112 {
6113 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6114 return error(GL_INVALID_OPERATION);
6115 }
6116
6117 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6118 }
6119 }
6120 catch(std::bad_alloc&)
6121 {
6122 return error(GL_OUT_OF_MEMORY);
6123 }
6124}
6125
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006126void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6127 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006128{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006129 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006130 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006131 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006132 target, level, internalformat, width, height, depth, border, format, type, pixels);
6133
6134 try
6135 {
6136 UNIMPLEMENTED(); // FIXME
6137 }
6138 catch(std::bad_alloc&)
6139 {
6140 return error(GL_OUT_OF_MEMORY);
6141 }
6142}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006143
6144__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6145{
6146 struct Extension
6147 {
6148 const char *name;
6149 __eglMustCastToProperFunctionPointerType address;
6150 };
6151
6152 static const Extension glExtensions[] =
6153 {
6154 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006155 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006156 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006157 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6158 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6159 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6160 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6161 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6162 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6163 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006164 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006165 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006166 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6167 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6168 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6169 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006170 };
6171
6172 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6173 {
6174 if (strcmp(procname, glExtensions[ext].name) == 0)
6175 {
6176 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6177 }
6178 }
6179
6180 return NULL;
6181}
6182
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006183// Non-public functions used by EGL
6184
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006185bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006186{
6187 EVENT("(egl::Surface* surface = 0x%0.8p)",
6188 surface);
6189
6190 try
6191 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006192 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006193
6194 if (context)
6195 {
6196 gl::Texture2D *textureObject = context->getTexture2D();
6197
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006198 if (textureObject->isImmutable())
6199 {
6200 return false;
6201 }
6202
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006203 if (textureObject)
6204 {
6205 textureObject->bindTexImage(surface);
6206 }
6207 }
6208 }
6209 catch(std::bad_alloc&)
6210 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006211 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006212 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006213
6214 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006215}
6216
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006217}