blob: 23957fe6d2ea6ff925a3cbc49aa20e771f7fe36e [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.com4f39fd92010-03-08 20:26:45 +000056extern "C"
57{
58
59void __stdcall glActiveTexture(GLenum texture)
60{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +000061 EVENT("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000062
63 try
64 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000065 gl::Context *context = gl::getContext();
66
67 if (context)
68 {
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +000069 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
70 {
71 return error(GL_INVALID_ENUM);
72 }
73
daniel@transgaming.com428d1582010-05-04 03:35:25 +000074 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000075 }
76 }
77 catch(std::bad_alloc&)
78 {
79 return error(GL_OUT_OF_MEMORY);
80 }
81}
82
83void __stdcall glAttachShader(GLuint program, GLuint shader)
84{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +000085 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000086
87 try
88 {
89 gl::Context *context = gl::getContext();
90
91 if (context)
92 {
93 gl::Program *programObject = context->getProgram(program);
94 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000095
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000096 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000097 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000098 if (context->getShader(program))
99 {
100 return error(GL_INVALID_OPERATION);
101 }
102 else
103 {
104 return error(GL_INVALID_VALUE);
105 }
106 }
107
108 if (!shaderObject)
109 {
110 if (context->getProgram(shader))
111 {
112 return error(GL_INVALID_OPERATION);
113 }
114 else
115 {
116 return error(GL_INVALID_VALUE);
117 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000118 }
119
120 if (!programObject->attachShader(shaderObject))
121 {
122 return error(GL_INVALID_OPERATION);
123 }
124 }
125 }
126 catch(std::bad_alloc&)
127 {
128 return error(GL_OUT_OF_MEMORY);
129 }
130}
131
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000132void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000133{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000134 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000135
136 try
137 {
138 if (index >= gl::MAX_VERTEX_ATTRIBS)
139 {
140 return error(GL_INVALID_VALUE);
141 }
142
143 gl::Context *context = gl::getContext();
144
145 if (context)
146 {
147 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000148
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000149 if (!programObject)
150 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000151 if (context->getShader(program))
152 {
153 return error(GL_INVALID_OPERATION);
154 }
155 else
156 {
157 return error(GL_INVALID_VALUE);
158 }
159 }
160
161 if (strncmp(name, "gl_", 3) == 0)
162 {
163 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164 }
165
166 programObject->bindAttributeLocation(index, name);
167 }
168 }
169 catch(std::bad_alloc&)
170 {
171 return error(GL_OUT_OF_MEMORY);
172 }
173}
174
175void __stdcall glBindBuffer(GLenum target, GLuint buffer)
176{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000177 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000178
179 try
180 {
181 gl::Context *context = gl::getContext();
182
183 if (context)
184 {
185 switch (target)
186 {
187 case GL_ARRAY_BUFFER:
188 context->bindArrayBuffer(buffer);
189 return;
190 case GL_ELEMENT_ARRAY_BUFFER:
191 context->bindElementArrayBuffer(buffer);
192 return;
193 default:
194 return error(GL_INVALID_ENUM);
195 }
196 }
197 }
198 catch(std::bad_alloc&)
199 {
200 return error(GL_OUT_OF_MEMORY);
201 }
202}
203
204void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
205{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000206 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000207
208 try
209 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000210 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000211 {
212 return error(GL_INVALID_ENUM);
213 }
214
215 gl::Context *context = gl::getContext();
216
217 if (context)
218 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000219 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
220 {
221 context->bindReadFramebuffer(framebuffer);
222 }
223
224 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
225 {
226 context->bindDrawFramebuffer(framebuffer);
227 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228 }
229 }
230 catch(std::bad_alloc&)
231 {
232 return error(GL_OUT_OF_MEMORY);
233 }
234}
235
236void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
237{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000238 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000239
240 try
241 {
242 if (target != GL_RENDERBUFFER)
243 {
244 return error(GL_INVALID_ENUM);
245 }
246
247 gl::Context *context = gl::getContext();
248
249 if (context)
250 {
251 context->bindRenderbuffer(renderbuffer);
252 }
253 }
254 catch(std::bad_alloc&)
255 {
256 return error(GL_OUT_OF_MEMORY);
257 }
258}
259
260void __stdcall glBindTexture(GLenum target, GLuint texture)
261{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000262 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000263
264 try
265 {
266 gl::Context *context = gl::getContext();
267
268 if (context)
269 {
270 gl::Texture *textureObject = context->getTexture(texture);
271
272 if (textureObject && textureObject->getTarget() != target && texture != 0)
273 {
274 return error(GL_INVALID_OPERATION);
275 }
276
277 switch (target)
278 {
279 case GL_TEXTURE_2D:
280 context->bindTexture2D(texture);
281 return;
282 case GL_TEXTURE_CUBE_MAP:
283 context->bindTextureCubeMap(texture);
284 return;
285 default:
286 return error(GL_INVALID_ENUM);
287 }
288 }
289 }
290 catch(std::bad_alloc&)
291 {
292 return error(GL_OUT_OF_MEMORY);
293 }
294}
295
296void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
297{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000298 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000299 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000300
301 try
302 {
303 gl::Context* context = gl::getContext();
304
305 if (context)
306 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000307 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000308 }
309 }
310 catch(std::bad_alloc&)
311 {
312 return error(GL_OUT_OF_MEMORY);
313 }
314}
315
316void __stdcall glBlendEquation(GLenum mode)
317{
318 glBlendEquationSeparate(mode, mode);
319}
320
321void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
322{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000323 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000324
325 try
326 {
327 switch (modeRGB)
328 {
329 case GL_FUNC_ADD:
330 case GL_FUNC_SUBTRACT:
331 case GL_FUNC_REVERSE_SUBTRACT:
332 break;
333 default:
334 return error(GL_INVALID_ENUM);
335 }
336
337 switch (modeAlpha)
338 {
339 case GL_FUNC_ADD:
340 case GL_FUNC_SUBTRACT:
341 case GL_FUNC_REVERSE_SUBTRACT:
342 break;
343 default:
344 return error(GL_INVALID_ENUM);
345 }
346
347 gl::Context *context = gl::getContext();
348
349 if (context)
350 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000351 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000352 }
353 }
354 catch(std::bad_alloc&)
355 {
356 return error(GL_OUT_OF_MEMORY);
357 }
358}
359
360void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
361{
362 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
363}
364
365void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
366{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000367 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 +0000368 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000369
370 try
371 {
372 switch (srcRGB)
373 {
374 case GL_ZERO:
375 case GL_ONE:
376 case GL_SRC_COLOR:
377 case GL_ONE_MINUS_SRC_COLOR:
378 case GL_DST_COLOR:
379 case GL_ONE_MINUS_DST_COLOR:
380 case GL_SRC_ALPHA:
381 case GL_ONE_MINUS_SRC_ALPHA:
382 case GL_DST_ALPHA:
383 case GL_ONE_MINUS_DST_ALPHA:
384 case GL_CONSTANT_COLOR:
385 case GL_ONE_MINUS_CONSTANT_COLOR:
386 case GL_CONSTANT_ALPHA:
387 case GL_ONE_MINUS_CONSTANT_ALPHA:
388 case GL_SRC_ALPHA_SATURATE:
389 break;
390 default:
391 return error(GL_INVALID_ENUM);
392 }
393
394 switch (dstRGB)
395 {
396 case GL_ZERO:
397 case GL_ONE:
398 case GL_SRC_COLOR:
399 case GL_ONE_MINUS_SRC_COLOR:
400 case GL_DST_COLOR:
401 case GL_ONE_MINUS_DST_COLOR:
402 case GL_SRC_ALPHA:
403 case GL_ONE_MINUS_SRC_ALPHA:
404 case GL_DST_ALPHA:
405 case GL_ONE_MINUS_DST_ALPHA:
406 case GL_CONSTANT_COLOR:
407 case GL_ONE_MINUS_CONSTANT_COLOR:
408 case GL_CONSTANT_ALPHA:
409 case GL_ONE_MINUS_CONSTANT_ALPHA:
410 break;
411 default:
412 return error(GL_INVALID_ENUM);
413 }
414
415 switch (srcAlpha)
416 {
417 case GL_ZERO:
418 case GL_ONE:
419 case GL_SRC_COLOR:
420 case GL_ONE_MINUS_SRC_COLOR:
421 case GL_DST_COLOR:
422 case GL_ONE_MINUS_DST_COLOR:
423 case GL_SRC_ALPHA:
424 case GL_ONE_MINUS_SRC_ALPHA:
425 case GL_DST_ALPHA:
426 case GL_ONE_MINUS_DST_ALPHA:
427 case GL_CONSTANT_COLOR:
428 case GL_ONE_MINUS_CONSTANT_COLOR:
429 case GL_CONSTANT_ALPHA:
430 case GL_ONE_MINUS_CONSTANT_ALPHA:
431 case GL_SRC_ALPHA_SATURATE:
432 break;
433 default:
434 return error(GL_INVALID_ENUM);
435 }
436
437 switch (dstAlpha)
438 {
439 case GL_ZERO:
440 case GL_ONE:
441 case GL_SRC_COLOR:
442 case GL_ONE_MINUS_SRC_COLOR:
443 case GL_DST_COLOR:
444 case GL_ONE_MINUS_DST_COLOR:
445 case GL_SRC_ALPHA:
446 case GL_ONE_MINUS_SRC_ALPHA:
447 case GL_DST_ALPHA:
448 case GL_ONE_MINUS_DST_ALPHA:
449 case GL_CONSTANT_COLOR:
450 case GL_ONE_MINUS_CONSTANT_COLOR:
451 case GL_CONSTANT_ALPHA:
452 case GL_ONE_MINUS_CONSTANT_ALPHA:
453 break;
454 default:
455 return error(GL_INVALID_ENUM);
456 }
457
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000458 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
459 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
460
461 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
462 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
463
464 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000465 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000466 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
467 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000468 }
469
470 gl::Context *context = gl::getContext();
471
472 if (context)
473 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000474 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000475 }
476 }
477 catch(std::bad_alloc&)
478 {
479 return error(GL_OUT_OF_MEMORY);
480 }
481}
482
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000483void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000484{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000485 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 +0000486 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000487
488 try
489 {
490 if (size < 0)
491 {
492 return error(GL_INVALID_VALUE);
493 }
494
495 switch (usage)
496 {
497 case GL_STREAM_DRAW:
498 case GL_STATIC_DRAW:
499 case GL_DYNAMIC_DRAW:
500 break;
501 default:
502 return error(GL_INVALID_ENUM);
503 }
504
505 gl::Context *context = gl::getContext();
506
507 if (context)
508 {
509 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000510
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000511 switch (target)
512 {
513 case GL_ARRAY_BUFFER:
514 buffer = context->getArrayBuffer();
515 break;
516 case GL_ELEMENT_ARRAY_BUFFER:
517 buffer = context->getElementArrayBuffer();
518 break;
519 default:
520 return error(GL_INVALID_ENUM);
521 }
522
523 if (!buffer)
524 {
525 return error(GL_INVALID_OPERATION);
526 }
527
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000528 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000529 }
530 }
531 catch(std::bad_alloc&)
532 {
533 return error(GL_OUT_OF_MEMORY);
534 }
535}
536
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000537void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000538{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000539 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 +0000540 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000541
542 try
543 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000544 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000545 {
546 return error(GL_INVALID_VALUE);
547 }
548
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000549 if (data == NULL)
550 {
551 return;
552 }
553
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000554 gl::Context *context = gl::getContext();
555
556 if (context)
557 {
558 gl::Buffer *buffer;
559
560 switch (target)
561 {
562 case GL_ARRAY_BUFFER:
563 buffer = context->getArrayBuffer();
564 break;
565 case GL_ELEMENT_ARRAY_BUFFER:
566 buffer = context->getElementArrayBuffer();
567 break;
568 default:
569 return error(GL_INVALID_ENUM);
570 }
571
572 if (!buffer)
573 {
574 return error(GL_INVALID_OPERATION);
575 }
576
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000577 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000578 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000579 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000580 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000581
582 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000583 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000584 }
585 catch(std::bad_alloc&)
586 {
587 return error(GL_OUT_OF_MEMORY);
588 }
589}
590
591GLenum __stdcall glCheckFramebufferStatus(GLenum target)
592{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000593 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000594
595 try
596 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000597 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000598 {
599 return error(GL_INVALID_ENUM, 0);
600 }
601
602 gl::Context *context = gl::getContext();
603
604 if (context)
605 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000606 gl::Framebuffer *framebuffer = NULL;
607 if (target == GL_READ_FRAMEBUFFER_ANGLE)
608 {
609 framebuffer = context->getReadFramebuffer();
610 }
611 else
612 {
613 framebuffer = context->getDrawFramebuffer();
614 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000615
616 return framebuffer->completeness();
617 }
618 }
619 catch(std::bad_alloc&)
620 {
621 return error(GL_OUT_OF_MEMORY, 0);
622 }
623
624 return 0;
625}
626
627void __stdcall glClear(GLbitfield mask)
628{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000629 EVENT("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000630
631 try
632 {
633 gl::Context *context = gl::getContext();
634
635 if (context)
636 {
637 context->clear(mask);
638 }
639 }
640 catch(std::bad_alloc&)
641 {
642 return error(GL_OUT_OF_MEMORY);
643 }
644}
645
646void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
647{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000648 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000649 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000650
651 try
652 {
653 gl::Context *context = gl::getContext();
654
655 if (context)
656 {
657 context->setClearColor(red, green, blue, alpha);
658 }
659 }
660 catch(std::bad_alloc&)
661 {
662 return error(GL_OUT_OF_MEMORY);
663 }
664}
665
666void __stdcall glClearDepthf(GLclampf depth)
667{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000668 EVENT("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000669
670 try
671 {
672 gl::Context *context = gl::getContext();
673
674 if (context)
675 {
676 context->setClearDepth(depth);
677 }
678 }
679 catch(std::bad_alloc&)
680 {
681 return error(GL_OUT_OF_MEMORY);
682 }
683}
684
685void __stdcall glClearStencil(GLint s)
686{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000687 EVENT("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000688
689 try
690 {
691 gl::Context *context = gl::getContext();
692
693 if (context)
694 {
695 context->setClearStencil(s);
696 }
697 }
698 catch(std::bad_alloc&)
699 {
700 return error(GL_OUT_OF_MEMORY);
701 }
702}
703
704void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
705{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000706 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000707 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000708
709 try
710 {
711 gl::Context *context = gl::getContext();
712
713 if (context)
714 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000715 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000716 }
717 }
718 catch(std::bad_alloc&)
719 {
720 return error(GL_OUT_OF_MEMORY);
721 }
722}
723
724void __stdcall glCompileShader(GLuint shader)
725{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000726 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000727
728 try
729 {
730 gl::Context *context = gl::getContext();
731
732 if (context)
733 {
734 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000735
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000736 if (!shaderObject)
737 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000738 if (context->getProgram(shader))
739 {
740 return error(GL_INVALID_OPERATION);
741 }
742 else
743 {
744 return error(GL_INVALID_VALUE);
745 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000746 }
747
748 shaderObject->compile();
749 }
750 }
751 catch(std::bad_alloc&)
752 {
753 return error(GL_OUT_OF_MEMORY);
754 }
755}
756
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000757void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
758 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000759{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000760 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000761 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000762 target, level, internalformat, width, height, border, imageSize, data);
763
764 try
765 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000766 if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000767 {
768 return error(GL_INVALID_VALUE);
769 }
770
daniel@transgaming.com01868132010-08-24 19:21:17 +0000771 switch (internalformat)
772 {
773 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
774 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
775 break;
776 default:
777 return error(GL_INVALID_ENUM);
778 }
779
780 if (border != 0)
781 {
782 return error(GL_INVALID_VALUE);
783 }
784
785 gl::Context *context = gl::getContext();
786
787 if (context)
788 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000789 if (level > context->getMaximumTextureLevel())
790 {
791 return error(GL_INVALID_VALUE);
792 }
793
794 switch (target)
795 {
796 case GL_TEXTURE_2D:
797 if (width > (context->getMaximumTextureDimension() >> level) ||
798 height > (context->getMaximumTextureDimension() >> level))
799 {
800 return error(GL_INVALID_VALUE);
801 }
802 break;
803 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
804 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
805 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
806 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
807 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
808 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
809 if (width != height)
810 {
811 return error(GL_INVALID_VALUE);
812 }
813
814 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
815 height > (context->getMaximumCubeTextureDimension() >> level))
816 {
817 return error(GL_INVALID_VALUE);
818 }
819 break;
820 default:
821 return error(GL_INVALID_ENUM);
822 }
823
daniel@transgaming.com01868132010-08-24 19:21:17 +0000824 if (!context->supportsCompressedTextures())
825 {
826 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
827 }
828
829 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
830 {
831 return error(GL_INVALID_VALUE);
832 }
833
834 if (target == GL_TEXTURE_2D)
835 {
836 gl::Texture2D *texture = context->getTexture2D();
837
838 if (!texture)
839 {
840 return error(GL_INVALID_OPERATION);
841 }
842
843 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
844 }
845 else
846 {
847 gl::TextureCubeMap *texture = context->getTextureCubeMap();
848
849 if (!texture)
850 {
851 return error(GL_INVALID_OPERATION);
852 }
853
854 switch (target)
855 {
856 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
857 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
858 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
859 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
860 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
861 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
862 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
863 break;
864 default: UNREACHABLE();
865 }
866 }
867 }
868
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000869 }
870 catch(std::bad_alloc&)
871 {
872 return error(GL_OUT_OF_MEMORY);
873 }
874}
875
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000876void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
877 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000878{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000879 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000880 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000881 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000882 target, level, xoffset, yoffset, width, height, format, imageSize, data);
883
884 try
885 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000886 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000887 {
888 return error(GL_INVALID_ENUM);
889 }
890
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000891 if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000892 {
893 return error(GL_INVALID_VALUE);
894 }
895
daniel@transgaming.com01868132010-08-24 19:21:17 +0000896 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000897 {
daniel@transgaming.com01868132010-08-24 19:21:17 +0000898 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
899 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
900 break;
901 default:
902 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +0000903 }
904
daniel@transgaming.com01868132010-08-24 19:21:17 +0000905 if (width == 0 || height == 0 || data == NULL)
906 {
907 return;
908 }
909
910 gl::Context *context = gl::getContext();
911
912 if (context)
913 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000914 if (level > context->getMaximumTextureLevel())
915 {
916 return error(GL_INVALID_VALUE);
917 }
918
daniel@transgaming.com01868132010-08-24 19:21:17 +0000919 if (!context->supportsCompressedTextures())
920 {
921 return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
922 }
923
924 if (imageSize != gl::ComputeCompressedSize(width, height, format))
925 {
926 return error(GL_INVALID_VALUE);
927 }
928
929 if (xoffset % 4 != 0 || yoffset % 4 != 0)
930 {
931 return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
932 // does not exist unless DXT1 textures are supported.
933 }
934
935 if (target == GL_TEXTURE_2D)
936 {
937 gl::Texture2D *texture = context->getTexture2D();
938
939 if (!texture)
940 {
941 return error(GL_INVALID_OPERATION);
942 }
943
944 if (!texture->isCompressed())
945 {
946 return error(GL_INVALID_OPERATION);
947 }
948
949 if ((width % 4 != 0 && width != texture->getWidth()) ||
950 (height % 4 != 0 && height != texture->getHeight()))
951 {
952 return error(GL_INVALID_OPERATION);
953 }
954
955 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
956 }
957 else if (gl::IsCubemapTextureTarget(target))
958 {
959 gl::TextureCubeMap *texture = context->getTextureCubeMap();
960
961 if (!texture)
962 {
963 return error(GL_INVALID_OPERATION);
964 }
965
966 if (!texture->isCompressed())
967 {
968 return error(GL_INVALID_OPERATION);
969 }
970
971 if ((width % 4 != 0 && width != texture->getWidth()) ||
972 (height % 4 != 0 && height != texture->getHeight()))
973 {
974 return error(GL_INVALID_OPERATION);
975 }
976
977 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
978 }
979 else
980 {
981 UNREACHABLE();
982 }
983 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000984 }
985 catch(std::bad_alloc&)
986 {
987 return error(GL_OUT_OF_MEMORY);
988 }
989}
990
991void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
992{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000993 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000994 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000995 target, level, internalformat, x, y, width, height, border);
996
997 try
998 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000999 if (!validImageSize(level, width, height))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001000 {
1001 return error(GL_INVALID_VALUE);
1002 }
1003
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001004 if (border != 0)
1005 {
1006 return error(GL_INVALID_VALUE);
1007 }
1008
1009 gl::Context *context = gl::getContext();
1010
1011 if (context)
1012 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001013 switch (target)
1014 {
1015 case GL_TEXTURE_2D:
1016 if (width > (context->getMaximumTextureDimension() >> level) ||
1017 height > (context->getMaximumTextureDimension() >> level))
1018 {
1019 return error(GL_INVALID_VALUE);
1020 }
1021 break;
1022 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1023 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1024 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1025 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1026 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1027 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1028 if (width != height)
1029 {
1030 return error(GL_INVALID_VALUE);
1031 }
1032
1033 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1034 height > (context->getMaximumCubeTextureDimension() >> level))
1035 {
1036 return error(GL_INVALID_VALUE);
1037 }
1038 break;
1039 default:
1040 return error(GL_INVALID_ENUM);
1041 }
1042
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001043 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001044
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001045 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1046 {
1047 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1048 }
1049
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001050 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1051 {
1052 return error(GL_INVALID_OPERATION);
1053 }
1054
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001055 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001056 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001057
1058 // [OpenGL ES 2.0.24] table 3.9
1059 switch (internalformat)
1060 {
1061 case GL_ALPHA:
1062 if (colorbufferFormat != GL_ALPHA &&
1063 colorbufferFormat != GL_RGBA &&
1064 colorbufferFormat != GL_RGBA4 &&
1065 colorbufferFormat != GL_RGB5_A1 &&
1066 colorbufferFormat != GL_RGBA8_OES)
1067 {
1068 return error(GL_INVALID_OPERATION);
1069 }
1070 break;
1071 case GL_LUMINANCE:
1072 case GL_RGB:
1073 if (colorbufferFormat != GL_RGB &&
1074 colorbufferFormat != GL_RGB565 &&
1075 colorbufferFormat != GL_RGB8_OES &&
1076 colorbufferFormat != GL_RGBA &&
1077 colorbufferFormat != GL_RGBA4 &&
1078 colorbufferFormat != GL_RGB5_A1 &&
1079 colorbufferFormat != GL_RGBA8_OES)
1080 {
1081 return error(GL_INVALID_OPERATION);
1082 }
1083 break;
1084 case GL_LUMINANCE_ALPHA:
1085 case GL_RGBA:
1086 if (colorbufferFormat != GL_RGBA &&
1087 colorbufferFormat != GL_RGBA4 &&
1088 colorbufferFormat != GL_RGB5_A1 &&
1089 colorbufferFormat != GL_RGBA8_OES)
1090 {
1091 return error(GL_INVALID_OPERATION);
1092 }
1093 break;
1094 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1095 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1096 if (context->supportsCompressedTextures())
1097 {
1098 return error(GL_INVALID_OPERATION);
1099 }
1100 else
1101 {
1102 return error(GL_INVALID_ENUM);
1103 }
1104 break;
1105 default:
1106 return error(GL_INVALID_ENUM);
1107 }
1108
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001109 if (target == GL_TEXTURE_2D)
1110 {
1111 gl::Texture2D *texture = context->getTexture2D();
1112
1113 if (!texture)
1114 {
1115 return error(GL_INVALID_OPERATION);
1116 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001117
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001118 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001119 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001120 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001121 {
1122 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1123
1124 if (!texture)
1125 {
1126 return error(GL_INVALID_OPERATION);
1127 }
1128
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001129 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001130 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001131 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001132 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001133 }
1134 catch(std::bad_alloc&)
1135 {
1136 return error(GL_OUT_OF_MEMORY);
1137 }
1138}
1139
1140void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1141{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001142 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001143 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001144 target, level, xoffset, yoffset, x, y, width, height);
1145
1146 try
1147 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001148 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001149 {
1150 return error(GL_INVALID_ENUM);
1151 }
1152
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001153 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001154 {
1155 return error(GL_INVALID_VALUE);
1156 }
1157
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001158 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1159 {
1160 return error(GL_INVALID_VALUE);
1161 }
1162
1163 if (width == 0 || height == 0)
1164 {
1165 return;
1166 }
1167
1168 gl::Context *context = gl::getContext();
1169
1170 if (context)
1171 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001172 if (level > context->getMaximumTextureLevel())
1173 {
1174 return error(GL_INVALID_VALUE);
1175 }
1176
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001177 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001178
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001179 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1180 {
1181 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1182 }
1183
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001184 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1185 {
1186 return error(GL_INVALID_OPERATION);
1187 }
1188
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001189 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001190 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001191 gl::Texture *texture = NULL;
1192
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001193 if (target == GL_TEXTURE_2D)
1194 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001195 texture = context->getTexture2D();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001196 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001197 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001198 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001199 texture = context->getTextureCubeMap();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001200 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001201 else UNREACHABLE();
1202
1203 if (!texture)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001204 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001205 return error(GL_INVALID_OPERATION);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001206 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001207
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001208 GLenum textureFormat = texture->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001209
1210 // [OpenGL ES 2.0.24] table 3.9
1211 switch (textureFormat)
1212 {
1213 case GL_ALPHA:
1214 if (colorbufferFormat != GL_ALPHA &&
1215 colorbufferFormat != GL_RGBA &&
1216 colorbufferFormat != GL_RGBA4 &&
1217 colorbufferFormat != GL_RGB5_A1 &&
1218 colorbufferFormat != GL_RGBA8_OES)
1219 {
1220 return error(GL_INVALID_OPERATION);
1221 }
1222 break;
1223 case GL_LUMINANCE:
1224 case GL_RGB:
1225 if (colorbufferFormat != GL_RGB &&
1226 colorbufferFormat != GL_RGB565 &&
1227 colorbufferFormat != GL_RGB8_OES &&
1228 colorbufferFormat != GL_RGBA &&
1229 colorbufferFormat != GL_RGBA4 &&
1230 colorbufferFormat != GL_RGB5_A1 &&
1231 colorbufferFormat != GL_RGBA8_OES)
1232 {
1233 return error(GL_INVALID_OPERATION);
1234 }
1235 break;
1236 case GL_LUMINANCE_ALPHA:
1237 case GL_RGBA:
1238 if (colorbufferFormat != GL_RGBA &&
1239 colorbufferFormat != GL_RGBA4 &&
1240 colorbufferFormat != GL_RGB5_A1 &&
1241 colorbufferFormat != GL_RGBA8_OES)
1242 {
1243 return error(GL_INVALID_OPERATION);
1244 }
1245 break;
1246 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1247 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1248 return error(GL_INVALID_OPERATION);
1249 default:
1250 return error(GL_INVALID_OPERATION);
1251 }
1252
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001253 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001254 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001255 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001256
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001257 catch(std::bad_alloc&)
1258 {
1259 return error(GL_OUT_OF_MEMORY);
1260 }
1261}
1262
1263GLuint __stdcall glCreateProgram(void)
1264{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001265 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001266
1267 try
1268 {
1269 gl::Context *context = gl::getContext();
1270
1271 if (context)
1272 {
1273 return context->createProgram();
1274 }
1275 }
1276 catch(std::bad_alloc&)
1277 {
1278 return error(GL_OUT_OF_MEMORY, 0);
1279 }
1280
1281 return 0;
1282}
1283
1284GLuint __stdcall glCreateShader(GLenum type)
1285{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001286 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001287
1288 try
1289 {
1290 gl::Context *context = gl::getContext();
1291
1292 if (context)
1293 {
1294 switch (type)
1295 {
1296 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001297 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001298 return context->createShader(type);
1299 default:
1300 return error(GL_INVALID_ENUM, 0);
1301 }
1302 }
1303 }
1304 catch(std::bad_alloc&)
1305 {
1306 return error(GL_OUT_OF_MEMORY, 0);
1307 }
1308
1309 return 0;
1310}
1311
1312void __stdcall glCullFace(GLenum mode)
1313{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001314 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001315
1316 try
1317 {
1318 switch (mode)
1319 {
1320 case GL_FRONT:
1321 case GL_BACK:
1322 case GL_FRONT_AND_BACK:
1323 {
1324 gl::Context *context = gl::getContext();
1325
1326 if (context)
1327 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001328 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001329 }
1330 }
1331 break;
1332 default:
1333 return error(GL_INVALID_ENUM);
1334 }
1335 }
1336 catch(std::bad_alloc&)
1337 {
1338 return error(GL_OUT_OF_MEMORY);
1339 }
1340}
1341
1342void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1343{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001344 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001345
1346 try
1347 {
1348 if (n < 0)
1349 {
1350 return error(GL_INVALID_VALUE);
1351 }
1352
1353 gl::Context *context = gl::getContext();
1354
1355 if (context)
1356 {
1357 for (int i = 0; i < n; i++)
1358 {
1359 context->deleteBuffer(buffers[i]);
1360 }
1361 }
1362 }
1363 catch(std::bad_alloc&)
1364 {
1365 return error(GL_OUT_OF_MEMORY);
1366 }
1367}
1368
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001369void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1370{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001371 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001372
1373 try
1374 {
1375 if (n < 0)
1376 {
1377 return error(GL_INVALID_VALUE);
1378 }
1379
1380 gl::Context *context = gl::getContext();
1381
1382 if (context)
1383 {
1384 for (int i = 0; i < n; i++)
1385 {
1386 context->deleteFence(fences[i]);
1387 }
1388 }
1389 }
1390 catch(std::bad_alloc&)
1391 {
1392 return error(GL_OUT_OF_MEMORY);
1393 }
1394}
1395
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001396void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1397{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001398 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001399
1400 try
1401 {
1402 if (n < 0)
1403 {
1404 return error(GL_INVALID_VALUE);
1405 }
1406
1407 gl::Context *context = gl::getContext();
1408
1409 if (context)
1410 {
1411 for (int i = 0; i < n; i++)
1412 {
1413 if (framebuffers[i] != 0)
1414 {
1415 context->deleteFramebuffer(framebuffers[i]);
1416 }
1417 }
1418 }
1419 }
1420 catch(std::bad_alloc&)
1421 {
1422 return error(GL_OUT_OF_MEMORY);
1423 }
1424}
1425
1426void __stdcall glDeleteProgram(GLuint program)
1427{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001428 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001429
1430 try
1431 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001432 if (program == 0)
1433 {
1434 return;
1435 }
1436
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001437 gl::Context *context = gl::getContext();
1438
1439 if (context)
1440 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001441 if (!context->getProgram(program))
1442 {
1443 if(context->getShader(program))
1444 {
1445 return error(GL_INVALID_OPERATION);
1446 }
1447 else
1448 {
1449 return error(GL_INVALID_VALUE);
1450 }
1451 }
1452
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001453 context->deleteProgram(program);
1454 }
1455 }
1456 catch(std::bad_alloc&)
1457 {
1458 return error(GL_OUT_OF_MEMORY);
1459 }
1460}
1461
1462void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1463{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001464 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001465
1466 try
1467 {
1468 if (n < 0)
1469 {
1470 return error(GL_INVALID_VALUE);
1471 }
1472
1473 gl::Context *context = gl::getContext();
1474
1475 if (context)
1476 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001477 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001478 {
1479 context->deleteRenderbuffer(renderbuffers[i]);
1480 }
1481 }
1482 }
1483 catch(std::bad_alloc&)
1484 {
1485 return error(GL_OUT_OF_MEMORY);
1486 }
1487}
1488
1489void __stdcall glDeleteShader(GLuint shader)
1490{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001491 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001492
1493 try
1494 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001495 if (shader == 0)
1496 {
1497 return;
1498 }
1499
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001500 gl::Context *context = gl::getContext();
1501
1502 if (context)
1503 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001504 if (!context->getShader(shader))
1505 {
1506 if(context->getProgram(shader))
1507 {
1508 return error(GL_INVALID_OPERATION);
1509 }
1510 else
1511 {
1512 return error(GL_INVALID_VALUE);
1513 }
1514 }
1515
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001516 context->deleteShader(shader);
1517 }
1518 }
1519 catch(std::bad_alloc&)
1520 {
1521 return error(GL_OUT_OF_MEMORY);
1522 }
1523}
1524
1525void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1526{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001527 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001528
1529 try
1530 {
1531 if (n < 0)
1532 {
1533 return error(GL_INVALID_VALUE);
1534 }
1535
1536 gl::Context *context = gl::getContext();
1537
1538 if (context)
1539 {
1540 for (int i = 0; i < n; i++)
1541 {
1542 if (textures[i] != 0)
1543 {
1544 context->deleteTexture(textures[i]);
1545 }
1546 }
1547 }
1548 }
1549 catch(std::bad_alloc&)
1550 {
1551 return error(GL_OUT_OF_MEMORY);
1552 }
1553}
1554
1555void __stdcall glDepthFunc(GLenum func)
1556{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001557 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001558
1559 try
1560 {
1561 switch (func)
1562 {
1563 case GL_NEVER:
1564 case GL_ALWAYS:
1565 case GL_LESS:
1566 case GL_LEQUAL:
1567 case GL_EQUAL:
1568 case GL_GREATER:
1569 case GL_GEQUAL:
1570 case GL_NOTEQUAL:
1571 break;
1572 default:
1573 return error(GL_INVALID_ENUM);
1574 }
1575
1576 gl::Context *context = gl::getContext();
1577
1578 if (context)
1579 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001580 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001581 }
1582 }
1583 catch(std::bad_alloc&)
1584 {
1585 return error(GL_OUT_OF_MEMORY);
1586 }
1587}
1588
1589void __stdcall glDepthMask(GLboolean flag)
1590{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001591 EVENT("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001592
1593 try
1594 {
1595 gl::Context *context = gl::getContext();
1596
1597 if (context)
1598 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001599 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001600 }
1601 }
1602 catch(std::bad_alloc&)
1603 {
1604 return error(GL_OUT_OF_MEMORY);
1605 }
1606}
1607
1608void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1609{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001610 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001611
1612 try
1613 {
1614 gl::Context *context = gl::getContext();
1615
1616 if (context)
1617 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001618 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001619 }
1620 }
1621 catch(std::bad_alloc&)
1622 {
1623 return error(GL_OUT_OF_MEMORY);
1624 }
1625}
1626
1627void __stdcall glDetachShader(GLuint program, GLuint shader)
1628{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001629 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001630
1631 try
1632 {
1633 gl::Context *context = gl::getContext();
1634
1635 if (context)
1636 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001637
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001638 gl::Program *programObject = context->getProgram(program);
1639 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001640
1641 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001642 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001643 gl::Shader *shaderByProgramHandle;
1644 shaderByProgramHandle = context->getShader(program);
1645 if (!shaderByProgramHandle)
1646 {
1647 return error(GL_INVALID_VALUE);
1648 }
1649 else
1650 {
1651 return error(GL_INVALID_OPERATION);
1652 }
1653 }
1654
1655 if (!shaderObject)
1656 {
1657 gl::Program *programByShaderHandle = context->getProgram(shader);
1658 if (!programByShaderHandle)
1659 {
1660 return error(GL_INVALID_VALUE);
1661 }
1662 else
1663 {
1664 return error(GL_INVALID_OPERATION);
1665 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001666 }
1667
1668 if (!programObject->detachShader(shaderObject))
1669 {
1670 return error(GL_INVALID_OPERATION);
1671 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001672 }
1673 }
1674 catch(std::bad_alloc&)
1675 {
1676 return error(GL_OUT_OF_MEMORY);
1677 }
1678}
1679
1680void __stdcall glDisable(GLenum cap)
1681{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001682 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001683
1684 try
1685 {
1686 gl::Context *context = gl::getContext();
1687
1688 if (context)
1689 {
1690 switch (cap)
1691 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001692 case GL_CULL_FACE: context->setCullFace(false); break;
1693 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1694 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1695 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1696 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1697 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1698 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1699 case GL_BLEND: context->setBlend(false); break;
1700 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001701 default:
1702 return error(GL_INVALID_ENUM);
1703 }
1704 }
1705 }
1706 catch(std::bad_alloc&)
1707 {
1708 return error(GL_OUT_OF_MEMORY);
1709 }
1710}
1711
1712void __stdcall glDisableVertexAttribArray(GLuint index)
1713{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001714 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001715
1716 try
1717 {
1718 if (index >= gl::MAX_VERTEX_ATTRIBS)
1719 {
1720 return error(GL_INVALID_VALUE);
1721 }
1722
1723 gl::Context *context = gl::getContext();
1724
1725 if (context)
1726 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001727 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001728 }
1729 }
1730 catch(std::bad_alloc&)
1731 {
1732 return error(GL_OUT_OF_MEMORY);
1733 }
1734}
1735
1736void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1737{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001738 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001739
1740 try
1741 {
1742 if (count < 0 || first < 0)
1743 {
1744 return error(GL_INVALID_VALUE);
1745 }
1746
1747 gl::Context *context = gl::getContext();
1748
1749 if (context)
1750 {
1751 context->drawArrays(mode, first, count);
1752 }
1753 }
1754 catch(std::bad_alloc&)
1755 {
1756 return error(GL_OUT_OF_MEMORY);
1757 }
1758}
1759
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001760void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001761{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001762 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 +00001763 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001764
1765 try
1766 {
1767 if (count < 0)
1768 {
1769 return error(GL_INVALID_VALUE);
1770 }
1771
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001772 gl::Context *context = gl::getContext();
1773
1774 if (context)
1775 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001776 switch (type)
1777 {
1778 case GL_UNSIGNED_BYTE:
1779 case GL_UNSIGNED_SHORT:
1780 break;
1781 case GL_UNSIGNED_INT:
1782 if (!context->supports32bitIndices())
1783 {
1784 return error(GL_INVALID_ENUM);
1785 }
1786 break;
1787 default:
1788 return error(GL_INVALID_ENUM);
1789 }
1790
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001791 context->drawElements(mode, count, type, indices);
1792 }
1793 }
1794 catch(std::bad_alloc&)
1795 {
1796 return error(GL_OUT_OF_MEMORY);
1797 }
1798}
1799
1800void __stdcall glEnable(GLenum cap)
1801{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001802 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001803
1804 try
1805 {
1806 gl::Context *context = gl::getContext();
1807
1808 if (context)
1809 {
1810 switch (cap)
1811 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001812 case GL_CULL_FACE: context->setCullFace(true); break;
1813 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1814 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1815 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1816 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1817 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1818 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1819 case GL_BLEND: context->setBlend(true); break;
1820 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001821 default:
1822 return error(GL_INVALID_ENUM);
1823 }
1824 }
1825 }
1826 catch(std::bad_alloc&)
1827 {
1828 return error(GL_OUT_OF_MEMORY);
1829 }
1830}
1831
1832void __stdcall glEnableVertexAttribArray(GLuint index)
1833{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001834 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001835
1836 try
1837 {
1838 if (index >= gl::MAX_VERTEX_ATTRIBS)
1839 {
1840 return error(GL_INVALID_VALUE);
1841 }
1842
1843 gl::Context *context = gl::getContext();
1844
1845 if (context)
1846 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001847 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001848 }
1849 }
1850 catch(std::bad_alloc&)
1851 {
1852 return error(GL_OUT_OF_MEMORY);
1853 }
1854}
1855
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001856void __stdcall glFinishFenceNV(GLuint fence)
1857{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001858 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001859
1860 try
1861 {
1862 gl::Context *context = gl::getContext();
1863
1864 if (context)
1865 {
1866 gl::Fence* fenceObject = context->getFence(fence);
1867
1868 if (fenceObject == NULL)
1869 {
1870 return error(GL_INVALID_OPERATION);
1871 }
1872
1873 fenceObject->finishFence();
1874 }
1875 }
1876 catch(std::bad_alloc&)
1877 {
1878 return error(GL_OUT_OF_MEMORY);
1879 }
1880}
1881
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001882void __stdcall glFinish(void)
1883{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001884 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001885
1886 try
1887 {
1888 gl::Context *context = gl::getContext();
1889
1890 if (context)
1891 {
1892 context->finish();
1893 }
1894 }
1895 catch(std::bad_alloc&)
1896 {
1897 return error(GL_OUT_OF_MEMORY);
1898 }
1899}
1900
1901void __stdcall glFlush(void)
1902{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001903 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001904
1905 try
1906 {
1907 gl::Context *context = gl::getContext();
1908
1909 if (context)
1910 {
1911 context->flush();
1912 }
1913 }
1914 catch(std::bad_alloc&)
1915 {
1916 return error(GL_OUT_OF_MEMORY);
1917 }
1918}
1919
1920void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1921{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001922 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001923 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001924
1925 try
1926 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001927 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1928 || renderbuffertarget != GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001929 {
1930 return error(GL_INVALID_ENUM);
1931 }
1932
1933 gl::Context *context = gl::getContext();
1934
1935 if (context)
1936 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001937 gl::Framebuffer *framebuffer = NULL;
1938 GLuint framebufferHandle = 0;
1939 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1940 {
1941 framebuffer = context->getReadFramebuffer();
1942 framebufferHandle = context->getReadFramebufferHandle();
1943 }
1944 else
1945 {
1946 framebuffer = context->getDrawFramebuffer();
1947 framebufferHandle = context->getDrawFramebufferHandle();
1948 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001949
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001950 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001951 {
1952 return error(GL_INVALID_OPERATION);
1953 }
1954
1955 switch (attachment)
1956 {
1957 case GL_COLOR_ATTACHMENT0:
1958 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1959 break;
1960 case GL_DEPTH_ATTACHMENT:
1961 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1962 break;
1963 case GL_STENCIL_ATTACHMENT:
1964 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1965 break;
1966 default:
1967 return error(GL_INVALID_ENUM);
1968 }
1969 }
1970 }
1971 catch(std::bad_alloc&)
1972 {
1973 return error(GL_OUT_OF_MEMORY);
1974 }
1975}
1976
1977void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1978{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001979 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001980 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001981
1982 try
1983 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001984 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001985 {
1986 return error(GL_INVALID_ENUM);
1987 }
1988
1989 switch (attachment)
1990 {
1991 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001992 case GL_DEPTH_ATTACHMENT:
1993 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001994 break;
1995 default:
1996 return error(GL_INVALID_ENUM);
1997 }
1998
1999 gl::Context *context = gl::getContext();
2000
2001 if (context)
2002 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002003 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002004 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002005 textarget = GL_NONE;
2006 }
2007 else
2008 {
2009 gl::Texture *tex = context->getTexture(texture);
2010
2011 if (tex == NULL)
2012 {
2013 return error(GL_INVALID_OPERATION);
2014 }
2015
daniel@transgaming.com01868132010-08-24 19:21:17 +00002016 if (tex->isCompressed())
2017 {
2018 return error(GL_INVALID_OPERATION);
2019 }
2020
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002021 switch (textarget)
2022 {
2023 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002024 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002025 {
2026 return error(GL_INVALID_OPERATION);
2027 }
2028 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002029
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002030 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002031 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002032 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002033 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002034 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002035 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002036 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2037 {
2038 return error(GL_INVALID_OPERATION);
2039 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002040 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002041
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002042 default:
2043 return error(GL_INVALID_ENUM);
2044 }
2045
2046 if (level != 0)
2047 {
2048 return error(GL_INVALID_VALUE);
2049 }
2050 }
2051
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002052 gl::Framebuffer *framebuffer = NULL;
2053 GLuint framebufferHandle = 0;
2054 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2055 {
2056 framebuffer = context->getReadFramebuffer();
2057 framebufferHandle = context->getReadFramebufferHandle();
2058 }
2059 else
2060 {
2061 framebuffer = context->getDrawFramebuffer();
2062 framebufferHandle = context->getDrawFramebufferHandle();
2063 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002064
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002065 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002066 {
2067 return error(GL_INVALID_OPERATION);
2068 }
2069
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002070 switch (attachment)
2071 {
2072 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2073 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2074 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2075 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002076 }
2077 }
2078 catch(std::bad_alloc&)
2079 {
2080 return error(GL_OUT_OF_MEMORY);
2081 }
2082}
2083
2084void __stdcall glFrontFace(GLenum mode)
2085{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002086 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002087
2088 try
2089 {
2090 switch (mode)
2091 {
2092 case GL_CW:
2093 case GL_CCW:
2094 {
2095 gl::Context *context = gl::getContext();
2096
2097 if (context)
2098 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002099 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002100 }
2101 }
2102 break;
2103 default:
2104 return error(GL_INVALID_ENUM);
2105 }
2106 }
2107 catch(std::bad_alloc&)
2108 {
2109 return error(GL_OUT_OF_MEMORY);
2110 }
2111}
2112
2113void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2114{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002115 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002116
2117 try
2118 {
2119 if (n < 0)
2120 {
2121 return error(GL_INVALID_VALUE);
2122 }
2123
2124 gl::Context *context = gl::getContext();
2125
2126 if (context)
2127 {
2128 for (int i = 0; i < n; i++)
2129 {
2130 buffers[i] = context->createBuffer();
2131 }
2132 }
2133 }
2134 catch(std::bad_alloc&)
2135 {
2136 return error(GL_OUT_OF_MEMORY);
2137 }
2138}
2139
2140void __stdcall glGenerateMipmap(GLenum target)
2141{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002142 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002143
2144 try
2145 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002146 gl::Context *context = gl::getContext();
2147
2148 if (context)
2149 {
2150 gl::Texture *texture;
2151
2152 switch (target)
2153 {
2154 case GL_TEXTURE_2D:
2155 texture = context->getTexture2D();
2156 break;
2157
2158 case GL_TEXTURE_CUBE_MAP:
2159 texture = context->getTextureCubeMap();
2160 break;
2161
2162 default:
2163 return error(GL_INVALID_ENUM);
2164 }
2165
daniel@transgaming.com01868132010-08-24 19:21:17 +00002166 if (texture->isCompressed())
2167 {
2168 return error(GL_INVALID_OPERATION);
2169 }
2170
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002171 texture->generateMipmaps();
2172 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002173 }
2174 catch(std::bad_alloc&)
2175 {
2176 return error(GL_OUT_OF_MEMORY);
2177 }
2178}
2179
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002180void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2181{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002182 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002183
2184 try
2185 {
2186 if (n < 0)
2187 {
2188 return error(GL_INVALID_VALUE);
2189 }
2190
2191 gl::Context *context = gl::getContext();
2192
2193 if (context)
2194 {
2195 for (int i = 0; i < n; i++)
2196 {
2197 fences[i] = context->createFence();
2198 }
2199 }
2200 }
2201 catch(std::bad_alloc&)
2202 {
2203 return error(GL_OUT_OF_MEMORY);
2204 }
2205}
2206
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002207void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2208{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002209 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002210
2211 try
2212 {
2213 if (n < 0)
2214 {
2215 return error(GL_INVALID_VALUE);
2216 }
2217
2218 gl::Context *context = gl::getContext();
2219
2220 if (context)
2221 {
2222 for (int i = 0; i < n; i++)
2223 {
2224 framebuffers[i] = context->createFramebuffer();
2225 }
2226 }
2227 }
2228 catch(std::bad_alloc&)
2229 {
2230 return error(GL_OUT_OF_MEMORY);
2231 }
2232}
2233
2234void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2235{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002236 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002237
2238 try
2239 {
2240 if (n < 0)
2241 {
2242 return error(GL_INVALID_VALUE);
2243 }
2244
2245 gl::Context *context = gl::getContext();
2246
2247 if (context)
2248 {
2249 for (int i = 0; i < n; i++)
2250 {
2251 renderbuffers[i] = context->createRenderbuffer();
2252 }
2253 }
2254 }
2255 catch(std::bad_alloc&)
2256 {
2257 return error(GL_OUT_OF_MEMORY);
2258 }
2259}
2260
2261void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2262{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002263 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002264
2265 try
2266 {
2267 if (n < 0)
2268 {
2269 return error(GL_INVALID_VALUE);
2270 }
2271
2272 gl::Context *context = gl::getContext();
2273
2274 if (context)
2275 {
2276 for (int i = 0; i < n; i++)
2277 {
2278 textures[i] = context->createTexture();
2279 }
2280 }
2281 }
2282 catch(std::bad_alloc&)
2283 {
2284 return error(GL_OUT_OF_MEMORY);
2285 }
2286}
2287
daniel@transgaming.com85423182010-04-22 13:35:27 +00002288void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002289{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002290 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002291 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002292 program, index, bufsize, length, size, type, name);
2293
2294 try
2295 {
2296 if (bufsize < 0)
2297 {
2298 return error(GL_INVALID_VALUE);
2299 }
2300
daniel@transgaming.com85423182010-04-22 13:35:27 +00002301 gl::Context *context = gl::getContext();
2302
2303 if (context)
2304 {
2305 gl::Program *programObject = context->getProgram(program);
2306
2307 if (!programObject)
2308 {
2309 if (context->getShader(program))
2310 {
2311 return error(GL_INVALID_OPERATION);
2312 }
2313 else
2314 {
2315 return error(GL_INVALID_VALUE);
2316 }
2317 }
2318
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002319 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002320 {
2321 return error(GL_INVALID_VALUE);
2322 }
2323
2324 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2325 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002326 }
2327 catch(std::bad_alloc&)
2328 {
2329 return error(GL_OUT_OF_MEMORY);
2330 }
2331}
2332
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002333void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002334{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002335 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002336 "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 +00002337 program, index, bufsize, length, size, type, name);
2338
2339 try
2340 {
2341 if (bufsize < 0)
2342 {
2343 return error(GL_INVALID_VALUE);
2344 }
2345
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002346 gl::Context *context = gl::getContext();
2347
2348 if (context)
2349 {
2350 gl::Program *programObject = context->getProgram(program);
2351
2352 if (!programObject)
2353 {
2354 if (context->getShader(program))
2355 {
2356 return error(GL_INVALID_OPERATION);
2357 }
2358 else
2359 {
2360 return error(GL_INVALID_VALUE);
2361 }
2362 }
2363
2364 if (index >= (GLuint)programObject->getActiveUniformCount())
2365 {
2366 return error(GL_INVALID_VALUE);
2367 }
2368
2369 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2370 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002371 }
2372 catch(std::bad_alloc&)
2373 {
2374 return error(GL_OUT_OF_MEMORY);
2375 }
2376}
2377
2378void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2379{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002380 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 +00002381 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002382
2383 try
2384 {
2385 if (maxcount < 0)
2386 {
2387 return error(GL_INVALID_VALUE);
2388 }
2389
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002390 gl::Context *context = gl::getContext();
2391
2392 if (context)
2393 {
2394 gl::Program *programObject = context->getProgram(program);
2395
2396 if (!programObject)
2397 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002398 if (context->getShader(program))
2399 {
2400 return error(GL_INVALID_OPERATION);
2401 }
2402 else
2403 {
2404 return error(GL_INVALID_VALUE);
2405 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002406 }
2407
2408 return programObject->getAttachedShaders(maxcount, count, shaders);
2409 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002410 }
2411 catch(std::bad_alloc&)
2412 {
2413 return error(GL_OUT_OF_MEMORY);
2414 }
2415}
2416
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002417int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002418{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002419 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002420
2421 try
2422 {
2423 gl::Context *context = gl::getContext();
2424
2425 if (context)
2426 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002427
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002428 gl::Program *programObject = context->getProgram(program);
2429
2430 if (!programObject)
2431 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002432 if (context->getShader(program))
2433 {
2434 return error(GL_INVALID_OPERATION, -1);
2435 }
2436 else
2437 {
2438 return error(GL_INVALID_VALUE, -1);
2439 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002440 }
2441
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002442 if (!programObject->isLinked())
2443 {
2444 return error(GL_INVALID_OPERATION, -1);
2445 }
2446
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002447 return programObject->getAttributeLocation(name);
2448 }
2449 }
2450 catch(std::bad_alloc&)
2451 {
2452 return error(GL_OUT_OF_MEMORY, -1);
2453 }
2454
2455 return -1;
2456}
2457
2458void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2459{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002460 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002461
2462 try
2463 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002464 gl::Context *context = gl::getContext();
2465
2466 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002467 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002468 if (!(context->getBooleanv(pname, params)))
2469 {
2470 GLenum nativeType;
2471 unsigned int numParams = 0;
2472 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2473 return error(GL_INVALID_ENUM);
2474
2475 if (numParams == 0)
2476 return; // it is known that the pname is valid, but there are no parameters to return
2477
2478 if (nativeType == GL_FLOAT)
2479 {
2480 GLfloat *floatParams = NULL;
2481 floatParams = new GLfloat[numParams];
2482
2483 context->getFloatv(pname, floatParams);
2484
2485 for (unsigned int i = 0; i < numParams; ++i)
2486 {
2487 if (floatParams[i] == 0.0f)
2488 params[i] = GL_FALSE;
2489 else
2490 params[i] = GL_TRUE;
2491 }
2492
2493 delete [] floatParams;
2494 }
2495 else if (nativeType == GL_INT)
2496 {
2497 GLint *intParams = NULL;
2498 intParams = new GLint[numParams];
2499
2500 context->getIntegerv(pname, intParams);
2501
2502 for (unsigned int i = 0; i < numParams; ++i)
2503 {
2504 if (intParams[i] == 0)
2505 params[i] = GL_FALSE;
2506 else
2507 params[i] = GL_TRUE;
2508 }
2509
2510 delete [] intParams;
2511 }
2512 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002513 }
2514 }
2515 catch(std::bad_alloc&)
2516 {
2517 return error(GL_OUT_OF_MEMORY);
2518 }
2519}
2520
2521void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2522{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002523 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 +00002524
2525 try
2526 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002527 gl::Context *context = gl::getContext();
2528
2529 if (context)
2530 {
2531 gl::Buffer *buffer;
2532
2533 switch (target)
2534 {
2535 case GL_ARRAY_BUFFER:
2536 buffer = context->getArrayBuffer();
2537 break;
2538 case GL_ELEMENT_ARRAY_BUFFER:
2539 buffer = context->getElementArrayBuffer();
2540 break;
2541 default: return error(GL_INVALID_ENUM);
2542 }
2543
2544 if (!buffer)
2545 {
2546 // A null buffer means that "0" is bound to the requested buffer target
2547 return error(GL_INVALID_OPERATION);
2548 }
2549
2550 switch (pname)
2551 {
2552 case GL_BUFFER_USAGE:
2553 *params = buffer->usage();
2554 break;
2555 case GL_BUFFER_SIZE:
2556 *params = buffer->size();
2557 break;
2558 default: return error(GL_INVALID_ENUM);
2559 }
2560 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002561 }
2562 catch(std::bad_alloc&)
2563 {
2564 return error(GL_OUT_OF_MEMORY);
2565 }
2566}
2567
2568GLenum __stdcall glGetError(void)
2569{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002570 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002571
2572 gl::Context *context = gl::getContext();
2573
2574 if (context)
2575 {
2576 return context->getError();
2577 }
2578
2579 return GL_NO_ERROR;
2580}
2581
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002582void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2583{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002584 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002585
2586 try
2587 {
2588
2589 gl::Context *context = gl::getContext();
2590
2591 if (context)
2592 {
2593 gl::Fence *fenceObject = context->getFence(fence);
2594
2595 if (fenceObject == NULL)
2596 {
2597 return error(GL_INVALID_OPERATION);
2598 }
2599
2600 fenceObject->getFenceiv(pname, params);
2601 }
2602 }
2603 catch(std::bad_alloc&)
2604 {
2605 return error(GL_OUT_OF_MEMORY);
2606 }
2607}
2608
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002609void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2610{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002611 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002612
2613 try
2614 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002615 gl::Context *context = gl::getContext();
2616
2617 if (context)
2618 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002619 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002620 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002621 GLenum nativeType;
2622 unsigned int numParams = 0;
2623 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2624 return error(GL_INVALID_ENUM);
2625
2626 if (numParams == 0)
2627 return; // it is known that the pname is valid, but that there are no parameters to return.
2628
2629 if (nativeType == GL_BOOL)
2630 {
2631 GLboolean *boolParams = NULL;
2632 boolParams = new GLboolean[numParams];
2633
2634 context->getBooleanv(pname, boolParams);
2635
2636 for (unsigned int i = 0; i < numParams; ++i)
2637 {
2638 if (boolParams[i] == GL_FALSE)
2639 params[i] = 0.0f;
2640 else
2641 params[i] = 1.0f;
2642 }
2643
2644 delete [] boolParams;
2645 }
2646 else if (nativeType == GL_INT)
2647 {
2648 GLint *intParams = NULL;
2649 intParams = new GLint[numParams];
2650
2651 context->getIntegerv(pname, intParams);
2652
2653 for (unsigned int i = 0; i < numParams; ++i)
2654 {
2655 params[i] = (GLfloat)intParams[i];
2656 }
2657
2658 delete [] intParams;
2659 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002660 }
2661 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002662 }
2663 catch(std::bad_alloc&)
2664 {
2665 return error(GL_OUT_OF_MEMORY);
2666 }
2667}
2668
2669void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2670{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002671 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 +00002672 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002673
2674 try
2675 {
2676 gl::Context *context = gl::getContext();
2677
2678 if (context)
2679 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002680 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002681 {
2682 return error(GL_INVALID_ENUM);
2683 }
2684
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002685 gl::Framebuffer *framebuffer = NULL;
2686 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2687 {
2688 if(context->getReadFramebufferHandle() == 0)
2689 {
2690 return error(GL_INVALID_OPERATION);
2691 }
2692
2693 framebuffer = context->getReadFramebuffer();
2694 }
2695 else
2696 {
2697 if (context->getDrawFramebufferHandle() == 0)
2698 {
2699 return error(GL_INVALID_OPERATION);
2700 }
2701
2702 framebuffer = context->getDrawFramebuffer();
2703 }
2704
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002705 GLenum attachmentType;
2706 GLuint attachmentHandle;
2707 switch (attachment)
2708 {
2709 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002710 attachmentType = framebuffer->getColorbufferType();
2711 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002712 break;
2713 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002714 attachmentType = framebuffer->getDepthbufferType();
2715 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002716 break;
2717 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002718 attachmentType = framebuffer->getStencilbufferType();
2719 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002720 break;
2721 default: return error(GL_INVALID_ENUM);
2722 }
2723
2724 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002725 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002726 {
2727 attachmentObjectType = attachmentType;
2728 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002729 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002730 {
2731 attachmentObjectType = GL_TEXTURE;
2732 }
2733 else UNREACHABLE();
2734
2735 switch (pname)
2736 {
2737 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2738 *params = attachmentObjectType;
2739 break;
2740 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2741 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2742 {
2743 *params = attachmentHandle;
2744 }
2745 else
2746 {
2747 return error(GL_INVALID_ENUM);
2748 }
2749 break;
2750 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2751 if (attachmentObjectType == GL_TEXTURE)
2752 {
2753 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2754 }
2755 else
2756 {
2757 return error(GL_INVALID_ENUM);
2758 }
2759 break;
2760 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2761 if (attachmentObjectType == GL_TEXTURE)
2762 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002763 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002764 {
2765 *params = attachmentType;
2766 }
2767 else
2768 {
2769 *params = 0;
2770 }
2771 }
2772 else
2773 {
2774 return error(GL_INVALID_ENUM);
2775 }
2776 break;
2777 default:
2778 return error(GL_INVALID_ENUM);
2779 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002780 }
2781 }
2782 catch(std::bad_alloc&)
2783 {
2784 return error(GL_OUT_OF_MEMORY);
2785 }
2786}
2787
2788void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2789{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002790 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002791
2792 try
2793 {
2794 gl::Context *context = gl::getContext();
2795
2796 if (context)
2797 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002798 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002799 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002800 GLenum nativeType;
2801 unsigned int numParams = 0;
2802 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2803 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002804
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002805 if (numParams == 0)
2806 return; // it is known that pname is valid, but there are no parameters to return
2807
2808 if (nativeType == GL_BOOL)
2809 {
2810 GLboolean *boolParams = NULL;
2811 boolParams = new GLboolean[numParams];
2812
2813 context->getBooleanv(pname, boolParams);
2814
2815 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002816 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002817 if (boolParams[i] == GL_FALSE)
2818 params[i] = 0;
2819 else
2820 params[i] = 1;
2821 }
2822
2823 delete [] boolParams;
2824 }
2825 else if (nativeType == GL_FLOAT)
2826 {
2827 GLfloat *floatParams = NULL;
2828 floatParams = new GLfloat[numParams];
2829
2830 context->getFloatv(pname, floatParams);
2831
2832 for (unsigned int i = 0; i < numParams; ++i)
2833 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002834 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 +00002835 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002836 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002837 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002838 else
2839 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 +00002840 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002841
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002842 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002843 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002844 }
2845 }
2846 }
2847 catch(std::bad_alloc&)
2848 {
2849 return error(GL_OUT_OF_MEMORY);
2850 }
2851}
2852
2853void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2854{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002855 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002856
2857 try
2858 {
2859 gl::Context *context = gl::getContext();
2860
2861 if (context)
2862 {
2863 gl::Program *programObject = context->getProgram(program);
2864
2865 if (!programObject)
2866 {
2867 return error(GL_INVALID_VALUE);
2868 }
2869
2870 switch (pname)
2871 {
2872 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002873 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002874 return;
2875 case GL_LINK_STATUS:
2876 *params = programObject->isLinked();
2877 return;
2878 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002879 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002880 return;
2881 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002882 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002883 return;
2884 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002885 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002886 return;
2887 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002888 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002889 return;
2890 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002891 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002892 return;
2893 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002894 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002895 return;
2896 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002897 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002898 return;
2899 default:
2900 return error(GL_INVALID_ENUM);
2901 }
2902 }
2903 }
2904 catch(std::bad_alloc&)
2905 {
2906 return error(GL_OUT_OF_MEMORY);
2907 }
2908}
2909
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002910void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002911{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002912 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 +00002913 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002914
2915 try
2916 {
2917 if (bufsize < 0)
2918 {
2919 return error(GL_INVALID_VALUE);
2920 }
2921
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002922 gl::Context *context = gl::getContext();
2923
2924 if (context)
2925 {
2926 gl::Program *programObject = context->getProgram(program);
2927
2928 if (!programObject)
2929 {
2930 return error(GL_INVALID_VALUE);
2931 }
2932
2933 programObject->getInfoLog(bufsize, length, infolog);
2934 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002935 }
2936 catch(std::bad_alloc&)
2937 {
2938 return error(GL_OUT_OF_MEMORY);
2939 }
2940}
2941
2942void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2943{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002944 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 +00002945
2946 try
2947 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002948 gl::Context *context = gl::getContext();
2949
2950 if (context)
2951 {
2952 if (target != GL_RENDERBUFFER)
2953 {
2954 return error(GL_INVALID_ENUM);
2955 }
2956
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002957 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002958 {
2959 return error(GL_INVALID_OPERATION);
2960 }
2961
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002962 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002963
2964 switch (pname)
2965 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00002966 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
2967 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
2968 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
2969 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
2970 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
2971 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
2972 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
2973 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
2974 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00002975 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00002976 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00002977 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00002978 *params = renderbuffer->getSamples();
2979 }
2980 else
2981 {
2982 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00002983 }
2984 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002985 default:
2986 return error(GL_INVALID_ENUM);
2987 }
2988 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002989 }
2990 catch(std::bad_alloc&)
2991 {
2992 return error(GL_OUT_OF_MEMORY);
2993 }
2994}
2995
2996void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2997{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002998 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002999
3000 try
3001 {
3002 gl::Context *context = gl::getContext();
3003
3004 if (context)
3005 {
3006 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003007
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003008 if (!shaderObject)
3009 {
3010 return error(GL_INVALID_VALUE);
3011 }
3012
3013 switch (pname)
3014 {
3015 case GL_SHADER_TYPE:
3016 *params = shaderObject->getType();
3017 return;
3018 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003019 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003020 return;
3021 case GL_COMPILE_STATUS:
3022 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3023 return;
3024 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003025 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003026 return;
3027 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003028 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003029 return;
3030 default:
3031 return error(GL_INVALID_ENUM);
3032 }
3033 }
3034 }
3035 catch(std::bad_alloc&)
3036 {
3037 return error(GL_OUT_OF_MEMORY);
3038 }
3039}
3040
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003041void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003042{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003043 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 +00003044 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003045
3046 try
3047 {
3048 if (bufsize < 0)
3049 {
3050 return error(GL_INVALID_VALUE);
3051 }
3052
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003053 gl::Context *context = gl::getContext();
3054
3055 if (context)
3056 {
3057 gl::Shader *shaderObject = context->getShader(shader);
3058
3059 if (!shaderObject)
3060 {
3061 return error(GL_INVALID_VALUE);
3062 }
3063
3064 shaderObject->getInfoLog(bufsize, length, infolog);
3065 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003066 }
3067 catch(std::bad_alloc&)
3068 {
3069 return error(GL_OUT_OF_MEMORY);
3070 }
3071}
3072
3073void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3074{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003075 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 +00003076 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003077
3078 try
3079 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003080 switch (shadertype)
3081 {
3082 case GL_VERTEX_SHADER:
3083 case GL_FRAGMENT_SHADER:
3084 break;
3085 default:
3086 return error(GL_INVALID_ENUM);
3087 }
3088
3089 switch (precisiontype)
3090 {
3091 case GL_LOW_FLOAT:
3092 case GL_MEDIUM_FLOAT:
3093 case GL_HIGH_FLOAT:
3094 // Assume IEEE 754 precision
3095 range[0] = 127;
3096 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003097 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003098 break;
3099 case GL_LOW_INT:
3100 case GL_MEDIUM_INT:
3101 case GL_HIGH_INT:
3102 // Some (most) hardware only supports single-precision floating-point numbers,
3103 // which can accurately represent integers up to +/-16777216
3104 range[0] = 24;
3105 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003106 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003107 break;
3108 default:
3109 return error(GL_INVALID_ENUM);
3110 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003111 }
3112 catch(std::bad_alloc&)
3113 {
3114 return error(GL_OUT_OF_MEMORY);
3115 }
3116}
3117
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003118void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003119{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003120 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 +00003121 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003122
3123 try
3124 {
3125 if (bufsize < 0)
3126 {
3127 return error(GL_INVALID_VALUE);
3128 }
3129
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003130 gl::Context *context = gl::getContext();
3131
3132 if (context)
3133 {
3134 gl::Shader *shaderObject = context->getShader(shader);
3135
3136 if (!shaderObject)
3137 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003138 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003139 }
3140
3141 shaderObject->getSource(bufsize, length, source);
3142 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003143 }
3144 catch(std::bad_alloc&)
3145 {
3146 return error(GL_OUT_OF_MEMORY);
3147 }
3148}
3149
3150const GLubyte* __stdcall glGetString(GLenum name)
3151{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003152 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003153
3154 try
3155 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003156 gl::Context *context = gl::getContext();
3157
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003158 switch (name)
3159 {
3160 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003161 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003162 case GL_RENDERER:
3163 return (GLubyte*)"ANGLE";
3164 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003165 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003166 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003167 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003168 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003169 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003170 default:
3171 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3172 }
3173 }
3174 catch(std::bad_alloc&)
3175 {
3176 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3177 }
3178
3179 return NULL;
3180}
3181
3182void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3183{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003184 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 +00003185
3186 try
3187 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003188 gl::Context *context = gl::getContext();
3189
3190 if (context)
3191 {
3192 gl::Texture *texture;
3193
3194 switch (target)
3195 {
3196 case GL_TEXTURE_2D:
3197 texture = context->getTexture2D();
3198 break;
3199 case GL_TEXTURE_CUBE_MAP:
3200 texture = context->getTextureCubeMap();
3201 break;
3202 default:
3203 return error(GL_INVALID_ENUM);
3204 }
3205
3206 switch (pname)
3207 {
3208 case GL_TEXTURE_MAG_FILTER:
3209 *params = (GLfloat)texture->getMagFilter();
3210 break;
3211 case GL_TEXTURE_MIN_FILTER:
3212 *params = (GLfloat)texture->getMinFilter();
3213 break;
3214 case GL_TEXTURE_WRAP_S:
3215 *params = (GLfloat)texture->getWrapS();
3216 break;
3217 case GL_TEXTURE_WRAP_T:
3218 *params = (GLfloat)texture->getWrapT();
3219 break;
3220 default:
3221 return error(GL_INVALID_ENUM);
3222 }
3223 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003224 }
3225 catch(std::bad_alloc&)
3226 {
3227 return error(GL_OUT_OF_MEMORY);
3228 }
3229}
3230
3231void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3232{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003233 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 +00003234
3235 try
3236 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003237 gl::Context *context = gl::getContext();
3238
3239 if (context)
3240 {
3241 gl::Texture *texture;
3242
3243 switch (target)
3244 {
3245 case GL_TEXTURE_2D:
3246 texture = context->getTexture2D();
3247 break;
3248 case GL_TEXTURE_CUBE_MAP:
3249 texture = context->getTextureCubeMap();
3250 break;
3251 default:
3252 return error(GL_INVALID_ENUM);
3253 }
3254
3255 switch (pname)
3256 {
3257 case GL_TEXTURE_MAG_FILTER:
3258 *params = texture->getMagFilter();
3259 break;
3260 case GL_TEXTURE_MIN_FILTER:
3261 *params = texture->getMinFilter();
3262 break;
3263 case GL_TEXTURE_WRAP_S:
3264 *params = texture->getWrapS();
3265 break;
3266 case GL_TEXTURE_WRAP_T:
3267 *params = texture->getWrapT();
3268 break;
3269 default:
3270 return error(GL_INVALID_ENUM);
3271 }
3272 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003273 }
3274 catch(std::bad_alloc&)
3275 {
3276 return error(GL_OUT_OF_MEMORY);
3277 }
3278}
3279
3280void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3281{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003282 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003283
3284 try
3285 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003286 gl::Context *context = gl::getContext();
3287
3288 if (context)
3289 {
3290 if (program == 0)
3291 {
3292 return error(GL_INVALID_VALUE);
3293 }
3294
3295 gl::Program *programObject = context->getProgram(program);
3296
3297 if (!programObject || !programObject->isLinked())
3298 {
3299 return error(GL_INVALID_OPERATION);
3300 }
3301
3302 if (!programObject->getUniformfv(location, params))
3303 {
3304 return error(GL_INVALID_OPERATION);
3305 }
3306 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003307 }
3308 catch(std::bad_alloc&)
3309 {
3310 return error(GL_OUT_OF_MEMORY);
3311 }
3312}
3313
3314void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3315{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003316 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003317
3318 try
3319 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003320 gl::Context *context = gl::getContext();
3321
3322 if (context)
3323 {
3324 if (program == 0)
3325 {
3326 return error(GL_INVALID_VALUE);
3327 }
3328
3329 gl::Program *programObject = context->getProgram(program);
3330
3331 if (!programObject || !programObject->isLinked())
3332 {
3333 return error(GL_INVALID_OPERATION);
3334 }
3335
3336 if (!programObject)
3337 {
3338 return error(GL_INVALID_OPERATION);
3339 }
3340
3341 if (!programObject->getUniformiv(location, params))
3342 {
3343 return error(GL_INVALID_OPERATION);
3344 }
3345 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003346 }
3347 catch(std::bad_alloc&)
3348 {
3349 return error(GL_OUT_OF_MEMORY);
3350 }
3351}
3352
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003353int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003354{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003355 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003356
3357 try
3358 {
3359 gl::Context *context = gl::getContext();
3360
3361 if (strstr(name, "gl_") == name)
3362 {
3363 return -1;
3364 }
3365
3366 if (context)
3367 {
3368 gl::Program *programObject = context->getProgram(program);
3369
3370 if (!programObject)
3371 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003372 if (context->getShader(program))
3373 {
3374 return error(GL_INVALID_OPERATION, -1);
3375 }
3376 else
3377 {
3378 return error(GL_INVALID_VALUE, -1);
3379 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003380 }
3381
3382 if (!programObject->isLinked())
3383 {
3384 return error(GL_INVALID_OPERATION, -1);
3385 }
3386
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00003387 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003388 }
3389 }
3390 catch(std::bad_alloc&)
3391 {
3392 return error(GL_OUT_OF_MEMORY, -1);
3393 }
3394
3395 return -1;
3396}
3397
3398void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3399{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003400 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003401
3402 try
3403 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003404 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003405
daniel@transgaming.come0078962010-04-15 20:45:08 +00003406 if (context)
3407 {
3408 if (index >= gl::MAX_VERTEX_ATTRIBS)
3409 {
3410 return error(GL_INVALID_VALUE);
3411 }
3412
daniel@transgaming.com83921382011-01-08 05:46:00 +00003413 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003414
daniel@transgaming.come0078962010-04-15 20:45:08 +00003415 switch (pname)
3416 {
3417 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003418 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003419 break;
3420 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003421 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003422 break;
3423 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003424 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003425 break;
3426 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003427 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003428 break;
3429 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003430 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003431 break;
3432 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003433 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003434 break;
3435 case GL_CURRENT_VERTEX_ATTRIB:
3436 for (int i = 0; i < 4; ++i)
3437 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003438 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003439 }
3440 break;
3441 default: return error(GL_INVALID_ENUM);
3442 }
3443 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003444 }
3445 catch(std::bad_alloc&)
3446 {
3447 return error(GL_OUT_OF_MEMORY);
3448 }
3449}
3450
3451void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3452{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003453 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003454
3455 try
3456 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003457 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003458
daniel@transgaming.come0078962010-04-15 20:45:08 +00003459 if (context)
3460 {
3461 if (index >= gl::MAX_VERTEX_ATTRIBS)
3462 {
3463 return error(GL_INVALID_VALUE);
3464 }
3465
daniel@transgaming.com83921382011-01-08 05:46:00 +00003466 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003467
daniel@transgaming.come0078962010-04-15 20:45:08 +00003468 switch (pname)
3469 {
3470 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003471 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003472 break;
3473 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003474 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003475 break;
3476 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003477 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003478 break;
3479 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003480 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003481 break;
3482 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003483 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003484 break;
3485 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003486 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003487 break;
3488 case GL_CURRENT_VERTEX_ATTRIB:
3489 for (int i = 0; i < 4; ++i)
3490 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003491 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003492 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3493 }
3494 break;
3495 default: return error(GL_INVALID_ENUM);
3496 }
3497 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003498 }
3499 catch(std::bad_alloc&)
3500 {
3501 return error(GL_OUT_OF_MEMORY);
3502 }
3503}
3504
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003505void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003506{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003507 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003508
3509 try
3510 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003511 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003512
daniel@transgaming.come0078962010-04-15 20:45:08 +00003513 if (context)
3514 {
3515 if (index >= gl::MAX_VERTEX_ATTRIBS)
3516 {
3517 return error(GL_INVALID_VALUE);
3518 }
3519
3520 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3521 {
3522 return error(GL_INVALID_ENUM);
3523 }
3524
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003525 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003526 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003527 }
3528 catch(std::bad_alloc&)
3529 {
3530 return error(GL_OUT_OF_MEMORY);
3531 }
3532}
3533
3534void __stdcall glHint(GLenum target, GLenum mode)
3535{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003536 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003537
3538 try
3539 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003540 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003541 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003542 case GL_FASTEST:
3543 case GL_NICEST:
3544 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003545 break;
3546 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003547 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003548 }
3549
3550 gl::Context *context = gl::getContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003551 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003552 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003553 case GL_GENERATE_MIPMAP_HINT:
3554 if (context) context->setGenerateMipmapHint(mode);
3555 break;
3556 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3557 if (context) context->setFragmentShaderDerivativeHint(mode);
3558 break;
3559 default:
3560 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003561 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003562 }
3563 catch(std::bad_alloc&)
3564 {
3565 return error(GL_OUT_OF_MEMORY);
3566 }
3567}
3568
3569GLboolean __stdcall glIsBuffer(GLuint buffer)
3570{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003571 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003572
3573 try
3574 {
3575 gl::Context *context = gl::getContext();
3576
3577 if (context && buffer)
3578 {
3579 gl::Buffer *bufferObject = context->getBuffer(buffer);
3580
3581 if (bufferObject)
3582 {
3583 return GL_TRUE;
3584 }
3585 }
3586 }
3587 catch(std::bad_alloc&)
3588 {
3589 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3590 }
3591
3592 return GL_FALSE;
3593}
3594
3595GLboolean __stdcall glIsEnabled(GLenum cap)
3596{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003597 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003598
3599 try
3600 {
3601 gl::Context *context = gl::getContext();
3602
3603 if (context)
3604 {
3605 switch (cap)
3606 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003607 case GL_CULL_FACE: return context->isCullFaceEnabled();
3608 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3609 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3610 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3611 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3612 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3613 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3614 case GL_BLEND: return context->isBlendEnabled();
3615 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003616 default:
3617 return error(GL_INVALID_ENUM, false);
3618 }
3619 }
3620 }
3621 catch(std::bad_alloc&)
3622 {
3623 return error(GL_OUT_OF_MEMORY, false);
3624 }
3625
3626 return false;
3627}
3628
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003629GLboolean __stdcall glIsFenceNV(GLuint fence)
3630{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003631 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003632
3633 try
3634 {
3635 gl::Context *context = gl::getContext();
3636
3637 if (context)
3638 {
3639 gl::Fence *fenceObject = context->getFence(fence);
3640
3641 if (fenceObject == NULL)
3642 {
3643 return GL_FALSE;
3644 }
3645
3646 return fenceObject->isFence();
3647 }
3648 }
3649 catch(std::bad_alloc&)
3650 {
3651 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3652 }
3653
3654 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003655}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003656
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003657GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3658{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003659 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003660
3661 try
3662 {
3663 gl::Context *context = gl::getContext();
3664
3665 if (context && framebuffer)
3666 {
3667 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3668
3669 if (framebufferObject)
3670 {
3671 return GL_TRUE;
3672 }
3673 }
3674 }
3675 catch(std::bad_alloc&)
3676 {
3677 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3678 }
3679
3680 return GL_FALSE;
3681}
3682
3683GLboolean __stdcall glIsProgram(GLuint program)
3684{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003685 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003686
3687 try
3688 {
3689 gl::Context *context = gl::getContext();
3690
3691 if (context && program)
3692 {
3693 gl::Program *programObject = context->getProgram(program);
3694
3695 if (programObject)
3696 {
3697 return GL_TRUE;
3698 }
3699 }
3700 }
3701 catch(std::bad_alloc&)
3702 {
3703 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3704 }
3705
3706 return GL_FALSE;
3707}
3708
3709GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3710{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003711 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003712
3713 try
3714 {
3715 gl::Context *context = gl::getContext();
3716
3717 if (context && renderbuffer)
3718 {
3719 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3720
3721 if (renderbufferObject)
3722 {
3723 return GL_TRUE;
3724 }
3725 }
3726 }
3727 catch(std::bad_alloc&)
3728 {
3729 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3730 }
3731
3732 return GL_FALSE;
3733}
3734
3735GLboolean __stdcall glIsShader(GLuint shader)
3736{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003737 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003738
3739 try
3740 {
3741 gl::Context *context = gl::getContext();
3742
3743 if (context && shader)
3744 {
3745 gl::Shader *shaderObject = context->getShader(shader);
3746
3747 if (shaderObject)
3748 {
3749 return GL_TRUE;
3750 }
3751 }
3752 }
3753 catch(std::bad_alloc&)
3754 {
3755 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3756 }
3757
3758 return GL_FALSE;
3759}
3760
3761GLboolean __stdcall glIsTexture(GLuint texture)
3762{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003763 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003764
3765 try
3766 {
3767 gl::Context *context = gl::getContext();
3768
3769 if (context && texture)
3770 {
3771 gl::Texture *textureObject = context->getTexture(texture);
3772
3773 if (textureObject)
3774 {
3775 return GL_TRUE;
3776 }
3777 }
3778 }
3779 catch(std::bad_alloc&)
3780 {
3781 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3782 }
3783
3784 return GL_FALSE;
3785}
3786
3787void __stdcall glLineWidth(GLfloat width)
3788{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003789 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003790
3791 try
3792 {
3793 if (width <= 0.0f)
3794 {
3795 return error(GL_INVALID_VALUE);
3796 }
3797
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003798 gl::Context *context = gl::getContext();
3799
3800 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003801 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003802 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003803 }
3804 }
3805 catch(std::bad_alloc&)
3806 {
3807 return error(GL_OUT_OF_MEMORY);
3808 }
3809}
3810
3811void __stdcall glLinkProgram(GLuint program)
3812{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003813 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003814
3815 try
3816 {
3817 gl::Context *context = gl::getContext();
3818
3819 if (context)
3820 {
3821 gl::Program *programObject = context->getProgram(program);
3822
3823 if (!programObject)
3824 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003825 if (context->getShader(program))
3826 {
3827 return error(GL_INVALID_OPERATION);
3828 }
3829 else
3830 {
3831 return error(GL_INVALID_VALUE);
3832 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003833 }
3834
3835 programObject->link();
3836 }
3837 }
3838 catch(std::bad_alloc&)
3839 {
3840 return error(GL_OUT_OF_MEMORY);
3841 }
3842}
3843
3844void __stdcall glPixelStorei(GLenum pname, GLint param)
3845{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003846 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003847
3848 try
3849 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003850 gl::Context *context = gl::getContext();
3851
3852 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003853 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003854 switch (pname)
3855 {
3856 case GL_UNPACK_ALIGNMENT:
3857 if (param != 1 && param != 2 && param != 4 && param != 8)
3858 {
3859 return error(GL_INVALID_VALUE);
3860 }
3861
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003862 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003863 break;
3864
3865 case GL_PACK_ALIGNMENT:
3866 if (param != 1 && param != 2 && param != 4 && param != 8)
3867 {
3868 return error(GL_INVALID_VALUE);
3869 }
3870
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003871 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003872 break;
3873
3874 default:
3875 return error(GL_INVALID_ENUM);
3876 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003877 }
3878 }
3879 catch(std::bad_alloc&)
3880 {
3881 return error(GL_OUT_OF_MEMORY);
3882 }
3883}
3884
3885void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3886{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003887 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003888
3889 try
3890 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003891 gl::Context *context = gl::getContext();
3892
3893 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003894 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003895 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003896 }
3897 }
3898 catch(std::bad_alloc&)
3899 {
3900 return error(GL_OUT_OF_MEMORY);
3901 }
3902}
3903
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003904void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003905{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003906 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003907 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003908 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003909
3910 try
3911 {
3912 if (width < 0 || height < 0)
3913 {
3914 return error(GL_INVALID_VALUE);
3915 }
3916
3917 switch (format)
3918 {
3919 case GL_RGBA:
3920 switch (type)
3921 {
3922 case GL_UNSIGNED_BYTE:
3923 break;
3924 default:
3925 return error(GL_INVALID_OPERATION);
3926 }
3927 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003928 case GL_BGRA_EXT:
3929 switch (type)
3930 {
3931 case GL_UNSIGNED_BYTE:
3932 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3933 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3934 break;
3935 default:
3936 return error(GL_INVALID_OPERATION);
3937 }
3938 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003939 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3940 switch (type)
3941 {
3942 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3943 break;
3944 default:
3945 return error(GL_INVALID_OPERATION);
3946 }
3947 break;
3948 default:
3949 return error(GL_INVALID_OPERATION);
3950 }
3951
3952 gl::Context *context = gl::getContext();
3953
3954 if (context)
3955 {
3956 context->readPixels(x, y, width, height, format, type, pixels);
3957 }
3958 }
3959 catch(std::bad_alloc&)
3960 {
3961 return error(GL_OUT_OF_MEMORY);
3962 }
3963}
3964
3965void __stdcall glReleaseShaderCompiler(void)
3966{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003967 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003968
3969 try
3970 {
3971 gl::Shader::releaseCompiler();
3972 }
3973 catch(std::bad_alloc&)
3974 {
3975 return error(GL_OUT_OF_MEMORY);
3976 }
3977}
3978
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003979void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003980{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003981 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 +00003982 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003983
3984 try
3985 {
3986 switch (target)
3987 {
3988 case GL_RENDERBUFFER:
3989 break;
3990 default:
3991 return error(GL_INVALID_ENUM);
3992 }
3993
daniel@transgaming.comedc19182010-10-15 17:57:55 +00003994 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003995 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003996 return error(GL_INVALID_ENUM);
3997 }
3998
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00003999 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004000 {
4001 return error(GL_INVALID_VALUE);
4002 }
4003
4004 gl::Context *context = gl::getContext();
4005
4006 if (context)
4007 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004008 if (width > context->getMaximumRenderbufferDimension() ||
4009 height > context->getMaximumRenderbufferDimension() ||
4010 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004011 {
4012 return error(GL_INVALID_VALUE);
4013 }
4014
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004015 GLuint handle = context->getRenderbufferHandle();
4016 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004017 {
4018 return error(GL_INVALID_OPERATION);
4019 }
4020
4021 switch (internalformat)
4022 {
4023 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004024 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004025 break;
4026 case GL_RGBA4:
4027 case GL_RGB5_A1:
4028 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004029 case GL_RGB8_OES:
4030 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004031 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004032 break;
4033 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004034 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004035 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004036 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004037 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004038 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004039 default:
4040 return error(GL_INVALID_ENUM);
4041 }
4042 }
4043 }
4044 catch(std::bad_alloc&)
4045 {
4046 return error(GL_OUT_OF_MEMORY);
4047 }
4048}
4049
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004050void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4051{
4052 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4053}
4054
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004055void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4056{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004057 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004058
4059 try
4060 {
4061 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004062
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004063 if (context)
4064 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004065 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004066 }
4067 }
4068 catch(std::bad_alloc&)
4069 {
4070 return error(GL_OUT_OF_MEMORY);
4071 }
4072}
4073
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004074void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4075{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004076 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004077
4078 try
4079 {
4080 if (condition != GL_ALL_COMPLETED_NV)
4081 {
4082 return error(GL_INVALID_ENUM);
4083 }
4084
4085 gl::Context *context = gl::getContext();
4086
4087 if (context)
4088 {
4089 gl::Fence *fenceObject = context->getFence(fence);
4090
4091 if (fenceObject == NULL)
4092 {
4093 return error(GL_INVALID_OPERATION);
4094 }
4095
4096 fenceObject->setFence(condition);
4097 }
4098 }
4099 catch(std::bad_alloc&)
4100 {
4101 return error(GL_OUT_OF_MEMORY);
4102 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004103}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004104
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004105void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4106{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004107 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 +00004108
4109 try
4110 {
4111 if (width < 0 || height < 0)
4112 {
4113 return error(GL_INVALID_VALUE);
4114 }
4115
4116 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004117
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004118 if (context)
4119 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004120 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004121 }
4122 }
4123 catch(std::bad_alloc&)
4124 {
4125 return error(GL_OUT_OF_MEMORY);
4126 }
4127}
4128
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004129void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004130{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004131 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004132 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004133 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004134
4135 try
4136 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004137 // No binary shader formats are supported.
4138 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004139 }
4140 catch(std::bad_alloc&)
4141 {
4142 return error(GL_OUT_OF_MEMORY);
4143 }
4144}
4145
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004146void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004147{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004148 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 +00004149 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004150
4151 try
4152 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004153 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004154 {
4155 return error(GL_INVALID_VALUE);
4156 }
4157
4158 gl::Context *context = gl::getContext();
4159
4160 if (context)
4161 {
4162 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004163
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004164 if (!shaderObject)
4165 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004166 if (context->getProgram(shader))
4167 {
4168 return error(GL_INVALID_OPERATION);
4169 }
4170 else
4171 {
4172 return error(GL_INVALID_VALUE);
4173 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004174 }
4175
4176 shaderObject->setSource(count, string, length);
4177 }
4178 }
4179 catch(std::bad_alloc&)
4180 {
4181 return error(GL_OUT_OF_MEMORY);
4182 }
4183}
4184
4185void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4186{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004187 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004188}
4189
4190void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4191{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004192 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 +00004193
4194 try
4195 {
4196 switch (face)
4197 {
4198 case GL_FRONT:
4199 case GL_BACK:
4200 case GL_FRONT_AND_BACK:
4201 break;
4202 default:
4203 return error(GL_INVALID_ENUM);
4204 }
4205
4206 switch (func)
4207 {
4208 case GL_NEVER:
4209 case GL_ALWAYS:
4210 case GL_LESS:
4211 case GL_LEQUAL:
4212 case GL_EQUAL:
4213 case GL_GEQUAL:
4214 case GL_GREATER:
4215 case GL_NOTEQUAL:
4216 break;
4217 default:
4218 return error(GL_INVALID_ENUM);
4219 }
4220
4221 gl::Context *context = gl::getContext();
4222
4223 if (context)
4224 {
4225 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4226 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004227 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004228 }
4229
4230 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4231 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004232 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004233 }
4234 }
4235 }
4236 catch(std::bad_alloc&)
4237 {
4238 return error(GL_OUT_OF_MEMORY);
4239 }
4240}
4241
4242void __stdcall glStencilMask(GLuint mask)
4243{
4244 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4245}
4246
4247void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4248{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004249 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004250
4251 try
4252 {
4253 switch (face)
4254 {
4255 case GL_FRONT:
4256 case GL_BACK:
4257 case GL_FRONT_AND_BACK:
4258 break;
4259 default:
4260 return error(GL_INVALID_ENUM);
4261 }
4262
4263 gl::Context *context = gl::getContext();
4264
4265 if (context)
4266 {
4267 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4268 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004269 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004270 }
4271
4272 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4273 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004274 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004275 }
4276 }
4277 }
4278 catch(std::bad_alloc&)
4279 {
4280 return error(GL_OUT_OF_MEMORY);
4281 }
4282}
4283
4284void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4285{
4286 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4287}
4288
4289void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4290{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004291 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 +00004292 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004293
4294 try
4295 {
4296 switch (face)
4297 {
4298 case GL_FRONT:
4299 case GL_BACK:
4300 case GL_FRONT_AND_BACK:
4301 break;
4302 default:
4303 return error(GL_INVALID_ENUM);
4304 }
4305
4306 switch (fail)
4307 {
4308 case GL_ZERO:
4309 case GL_KEEP:
4310 case GL_REPLACE:
4311 case GL_INCR:
4312 case GL_DECR:
4313 case GL_INVERT:
4314 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004315 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004316 break;
4317 default:
4318 return error(GL_INVALID_ENUM);
4319 }
4320
4321 switch (zfail)
4322 {
4323 case GL_ZERO:
4324 case GL_KEEP:
4325 case GL_REPLACE:
4326 case GL_INCR:
4327 case GL_DECR:
4328 case GL_INVERT:
4329 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004330 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004331 break;
4332 default:
4333 return error(GL_INVALID_ENUM);
4334 }
4335
4336 switch (zpass)
4337 {
4338 case GL_ZERO:
4339 case GL_KEEP:
4340 case GL_REPLACE:
4341 case GL_INCR:
4342 case GL_DECR:
4343 case GL_INVERT:
4344 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004345 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004346 break;
4347 default:
4348 return error(GL_INVALID_ENUM);
4349 }
4350
4351 gl::Context *context = gl::getContext();
4352
4353 if (context)
4354 {
4355 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4356 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004357 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004358 }
4359
4360 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4361 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004362 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004363 }
4364 }
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 +00004372GLboolean __stdcall glTestFenceNV(GLuint fence)
4373{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004374 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004375
4376 try
4377 {
4378 gl::Context *context = gl::getContext();
4379
4380 if (context)
4381 {
4382 gl::Fence *fenceObject = context->getFence(fence);
4383
4384 if (fenceObject == NULL)
4385 {
4386 return error(GL_INVALID_OPERATION, GL_TRUE);
4387 }
4388
4389 return fenceObject->testFence();
4390 }
4391 }
4392 catch(std::bad_alloc&)
4393 {
4394 error(GL_OUT_OF_MEMORY);
4395 }
4396
4397 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004398}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004399
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004400void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4401 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004402{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004403 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 +00004404 "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 +00004405 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004406
4407 try
4408 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00004409 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004410 {
4411 return error(GL_INVALID_VALUE);
4412 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004413
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004414 if (internalformat != format)
4415 {
4416 return error(GL_INVALID_OPERATION);
4417 }
4418
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004419 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004420 {
4421 case GL_ALPHA:
4422 case GL_LUMINANCE:
4423 case GL_LUMINANCE_ALPHA:
4424 switch (type)
4425 {
4426 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004427 case GL_FLOAT:
4428 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004429 break;
4430 default:
4431 return error(GL_INVALID_ENUM);
4432 }
4433 break;
4434 case GL_RGB:
4435 switch (type)
4436 {
4437 case GL_UNSIGNED_BYTE:
4438 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004439 case GL_FLOAT:
4440 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004441 break;
4442 default:
4443 return error(GL_INVALID_ENUM);
4444 }
4445 break;
4446 case GL_RGBA:
4447 switch (type)
4448 {
4449 case GL_UNSIGNED_BYTE:
4450 case GL_UNSIGNED_SHORT_4_4_4_4:
4451 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004452 case GL_FLOAT:
4453 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004454 break;
4455 default:
4456 return error(GL_INVALID_ENUM);
4457 }
4458 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004459 case GL_BGRA_EXT:
4460 switch (type)
4461 {
4462 case GL_UNSIGNED_BYTE:
4463 break;
4464 default:
4465 return error(GL_INVALID_ENUM);
4466 }
4467 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004468 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4469 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4470 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004471 default:
4472 return error(GL_INVALID_VALUE);
4473 }
4474
4475 if (border != 0)
4476 {
4477 return error(GL_INVALID_VALUE);
4478 }
4479
4480 gl::Context *context = gl::getContext();
4481
4482 if (context)
4483 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004484 switch (target)
4485 {
4486 case GL_TEXTURE_2D:
4487 if (width > (context->getMaximumTextureDimension() >> level) ||
4488 height > (context->getMaximumTextureDimension() >> level))
4489 {
4490 return error(GL_INVALID_VALUE);
4491 }
4492 break;
4493 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4494 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4495 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4496 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4497 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4498 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4499 if (width != height)
4500 {
4501 return error(GL_INVALID_VALUE);
4502 }
4503
4504 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4505 height > (context->getMaximumCubeTextureDimension() >> level))
4506 {
4507 return error(GL_INVALID_VALUE);
4508 }
4509 break;
4510 default:
4511 return error(GL_INVALID_ENUM);
4512 }
4513
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004514 if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4515 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
daniel@transgaming.com01868132010-08-24 19:21:17 +00004516 {
4517 if (context->supportsCompressedTextures())
4518 {
4519 return error(GL_INVALID_OPERATION);
4520 }
4521 else
4522 {
4523 return error(GL_INVALID_ENUM);
4524 }
4525 }
4526
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004527 if (type == GL_FLOAT)
4528 {
4529 if (!context->supportsFloatTextures())
4530 {
4531 return error(GL_INVALID_ENUM);
4532 }
4533 }
4534 else if (type == GL_HALF_FLOAT_OES)
4535 {
4536 if (!context->supportsHalfFloatTextures())
4537 {
4538 return error(GL_INVALID_ENUM);
4539 }
4540 }
4541
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004542 if (target == GL_TEXTURE_2D)
4543 {
4544 gl::Texture2D *texture = context->getTexture2D();
4545
4546 if (!texture)
4547 {
4548 return error(GL_INVALID_OPERATION);
4549 }
4550
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004551 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004552 }
4553 else
4554 {
4555 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4556
4557 if (!texture)
4558 {
4559 return error(GL_INVALID_OPERATION);
4560 }
4561
4562 switch (target)
4563 {
4564 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004565 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004566 break;
4567 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004568 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004569 break;
4570 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004571 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004572 break;
4573 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004574 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004575 break;
4576 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004577 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004578 break;
4579 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004580 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004581 break;
4582 default: UNREACHABLE();
4583 }
4584 }
4585 }
4586 }
4587 catch(std::bad_alloc&)
4588 {
4589 return error(GL_OUT_OF_MEMORY);
4590 }
4591}
4592
4593void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4594{
4595 glTexParameteri(target, pname, (GLint)param);
4596}
4597
4598void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4599{
4600 glTexParameteri(target, pname, (GLint)*params);
4601}
4602
4603void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4604{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004605 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004606
4607 try
4608 {
4609 gl::Context *context = gl::getContext();
4610
4611 if (context)
4612 {
4613 gl::Texture *texture;
4614
4615 switch (target)
4616 {
4617 case GL_TEXTURE_2D:
4618 texture = context->getTexture2D();
4619 break;
4620 case GL_TEXTURE_CUBE_MAP:
4621 texture = context->getTextureCubeMap();
4622 break;
4623 default:
4624 return error(GL_INVALID_ENUM);
4625 }
4626
4627 switch (pname)
4628 {
4629 case GL_TEXTURE_WRAP_S:
4630 if (!texture->setWrapS((GLenum)param))
4631 {
4632 return error(GL_INVALID_ENUM);
4633 }
4634 break;
4635 case GL_TEXTURE_WRAP_T:
4636 if (!texture->setWrapT((GLenum)param))
4637 {
4638 return error(GL_INVALID_ENUM);
4639 }
4640 break;
4641 case GL_TEXTURE_MIN_FILTER:
4642 if (!texture->setMinFilter((GLenum)param))
4643 {
4644 return error(GL_INVALID_ENUM);
4645 }
4646 break;
4647 case GL_TEXTURE_MAG_FILTER:
4648 if (!texture->setMagFilter((GLenum)param))
4649 {
4650 return error(GL_INVALID_ENUM);
4651 }
4652 break;
4653 default:
4654 return error(GL_INVALID_ENUM);
4655 }
4656 }
4657 }
4658 catch(std::bad_alloc&)
4659 {
4660 return error(GL_OUT_OF_MEMORY);
4661 }
4662}
4663
4664void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4665{
4666 glTexParameteri(target, pname, *params);
4667}
4668
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004669void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4670 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004671{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004672 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004673 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004674 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004675 target, level, xoffset, yoffset, width, height, format, type, pixels);
4676
4677 try
4678 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004679 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004680 {
4681 return error(GL_INVALID_ENUM);
4682 }
4683
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004684 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004685 {
4686 return error(GL_INVALID_VALUE);
4687 }
4688
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004689 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4690 {
4691 return error(GL_INVALID_VALUE);
4692 }
4693
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004694 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004695 {
4696 return error(GL_INVALID_ENUM);
4697 }
4698
4699 if (width == 0 || height == 0 || pixels == NULL)
4700 {
4701 return;
4702 }
4703
4704 gl::Context *context = gl::getContext();
4705
4706 if (context)
4707 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004708 if (level > context->getMaximumTextureLevel())
4709 {
4710 return error(GL_INVALID_VALUE);
4711 }
4712
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004713 if (format == GL_FLOAT)
4714 {
4715 if (!context->supportsFloatTextures())
4716 {
4717 return error(GL_INVALID_ENUM);
4718 }
4719 }
4720 else if (format == GL_HALF_FLOAT_OES)
4721 {
4722 if (!context->supportsHalfFloatTextures())
4723 {
4724 return error(GL_INVALID_ENUM);
4725 }
4726 }
4727
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004728 if (target == GL_TEXTURE_2D)
4729 {
4730 gl::Texture2D *texture = context->getTexture2D();
4731
4732 if (!texture)
4733 {
4734 return error(GL_INVALID_OPERATION);
4735 }
4736
daniel@transgaming.com01868132010-08-24 19:21:17 +00004737 if (texture->isCompressed())
4738 {
4739 return error(GL_INVALID_OPERATION);
4740 }
4741
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00004742 if (format != texture->getInternalFormat())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004743 {
4744 return error(GL_INVALID_OPERATION);
4745 }
4746
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004747 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004748 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004749 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004750 {
4751 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4752
4753 if (!texture)
4754 {
4755 return error(GL_INVALID_OPERATION);
4756 }
4757
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004758 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004759 }
4760 else
4761 {
4762 UNREACHABLE();
4763 }
4764 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004765 }
4766 catch(std::bad_alloc&)
4767 {
4768 return error(GL_OUT_OF_MEMORY);
4769 }
4770}
4771
4772void __stdcall glUniform1f(GLint location, GLfloat x)
4773{
4774 glUniform1fv(location, 1, &x);
4775}
4776
4777void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4778{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004779 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004780
4781 try
4782 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004783 if (count < 0)
4784 {
4785 return error(GL_INVALID_VALUE);
4786 }
4787
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004788 if (location == -1)
4789 {
4790 return;
4791 }
4792
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004793 gl::Context *context = gl::getContext();
4794
4795 if (context)
4796 {
4797 gl::Program *program = context->getCurrentProgram();
4798
4799 if (!program)
4800 {
4801 return error(GL_INVALID_OPERATION);
4802 }
4803
4804 if (!program->setUniform1fv(location, count, v))
4805 {
4806 return error(GL_INVALID_OPERATION);
4807 }
4808 }
4809 }
4810 catch(std::bad_alloc&)
4811 {
4812 return error(GL_OUT_OF_MEMORY);
4813 }
4814}
4815
4816void __stdcall glUniform1i(GLint location, GLint x)
4817{
4818 glUniform1iv(location, 1, &x);
4819}
4820
4821void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4822{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004823 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004824
4825 try
4826 {
4827 if (count < 0)
4828 {
4829 return error(GL_INVALID_VALUE);
4830 }
4831
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004832 if (location == -1)
4833 {
4834 return;
4835 }
4836
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004837 gl::Context *context = gl::getContext();
4838
4839 if (context)
4840 {
4841 gl::Program *program = context->getCurrentProgram();
4842
4843 if (!program)
4844 {
4845 return error(GL_INVALID_OPERATION);
4846 }
4847
4848 if (!program->setUniform1iv(location, count, v))
4849 {
4850 return error(GL_INVALID_OPERATION);
4851 }
4852 }
4853 }
4854 catch(std::bad_alloc&)
4855 {
4856 return error(GL_OUT_OF_MEMORY);
4857 }
4858}
4859
4860void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4861{
4862 GLfloat xy[2] = {x, y};
4863
4864 glUniform2fv(location, 1, (GLfloat*)&xy);
4865}
4866
4867void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4868{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004869 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004870
4871 try
4872 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004873 if (count < 0)
4874 {
4875 return error(GL_INVALID_VALUE);
4876 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004877
4878 if (location == -1)
4879 {
4880 return;
4881 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004882
4883 gl::Context *context = gl::getContext();
4884
4885 if (context)
4886 {
4887 gl::Program *program = context->getCurrentProgram();
4888
4889 if (!program)
4890 {
4891 return error(GL_INVALID_OPERATION);
4892 }
4893
4894 if (!program->setUniform2fv(location, count, v))
4895 {
4896 return error(GL_INVALID_OPERATION);
4897 }
4898 }
4899 }
4900 catch(std::bad_alloc&)
4901 {
4902 return error(GL_OUT_OF_MEMORY);
4903 }
4904}
4905
4906void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4907{
4908 GLint xy[4] = {x, y};
4909
4910 glUniform2iv(location, 1, (GLint*)&xy);
4911}
4912
4913void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4914{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004915 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004916
4917 try
4918 {
4919 if (count < 0)
4920 {
4921 return error(GL_INVALID_VALUE);
4922 }
4923
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004924 if (location == -1)
4925 {
4926 return;
4927 }
4928
4929 gl::Context *context = gl::getContext();
4930
4931 if (context)
4932 {
4933 gl::Program *program = context->getCurrentProgram();
4934
4935 if (!program)
4936 {
4937 return error(GL_INVALID_OPERATION);
4938 }
4939
4940 if (!program->setUniform2iv(location, count, v))
4941 {
4942 return error(GL_INVALID_OPERATION);
4943 }
4944 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004945 }
4946 catch(std::bad_alloc&)
4947 {
4948 return error(GL_OUT_OF_MEMORY);
4949 }
4950}
4951
4952void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4953{
4954 GLfloat xyz[3] = {x, y, z};
4955
4956 glUniform3fv(location, 1, (GLfloat*)&xyz);
4957}
4958
4959void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4960{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004961 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004962
4963 try
4964 {
4965 if (count < 0)
4966 {
4967 return error(GL_INVALID_VALUE);
4968 }
4969
4970 if (location == -1)
4971 {
4972 return;
4973 }
4974
4975 gl::Context *context = gl::getContext();
4976
4977 if (context)
4978 {
4979 gl::Program *program = context->getCurrentProgram();
4980
4981 if (!program)
4982 {
4983 return error(GL_INVALID_OPERATION);
4984 }
4985
4986 if (!program->setUniform3fv(location, count, v))
4987 {
4988 return error(GL_INVALID_OPERATION);
4989 }
4990 }
4991 }
4992 catch(std::bad_alloc&)
4993 {
4994 return error(GL_OUT_OF_MEMORY);
4995 }
4996}
4997
4998void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4999{
5000 GLint xyz[3] = {x, y, z};
5001
5002 glUniform3iv(location, 1, (GLint*)&xyz);
5003}
5004
5005void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5006{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005007 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005008
5009 try
5010 {
5011 if (count < 0)
5012 {
5013 return error(GL_INVALID_VALUE);
5014 }
5015
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005016 if (location == -1)
5017 {
5018 return;
5019 }
5020
5021 gl::Context *context = gl::getContext();
5022
5023 if (context)
5024 {
5025 gl::Program *program = context->getCurrentProgram();
5026
5027 if (!program)
5028 {
5029 return error(GL_INVALID_OPERATION);
5030 }
5031
5032 if (!program->setUniform3iv(location, count, v))
5033 {
5034 return error(GL_INVALID_OPERATION);
5035 }
5036 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005037 }
5038 catch(std::bad_alloc&)
5039 {
5040 return error(GL_OUT_OF_MEMORY);
5041 }
5042}
5043
5044void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5045{
5046 GLfloat xyzw[4] = {x, y, z, w};
5047
5048 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5049}
5050
5051void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5052{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005053 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005054
5055 try
5056 {
5057 if (count < 0)
5058 {
5059 return error(GL_INVALID_VALUE);
5060 }
5061
5062 if (location == -1)
5063 {
5064 return;
5065 }
5066
5067 gl::Context *context = gl::getContext();
5068
5069 if (context)
5070 {
5071 gl::Program *program = context->getCurrentProgram();
5072
5073 if (!program)
5074 {
5075 return error(GL_INVALID_OPERATION);
5076 }
5077
5078 if (!program->setUniform4fv(location, count, v))
5079 {
5080 return error(GL_INVALID_OPERATION);
5081 }
5082 }
5083 }
5084 catch(std::bad_alloc&)
5085 {
5086 return error(GL_OUT_OF_MEMORY);
5087 }
5088}
5089
5090void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5091{
5092 GLint xyzw[4] = {x, y, z, w};
5093
5094 glUniform4iv(location, 1, (GLint*)&xyzw);
5095}
5096
5097void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5098{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005099 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005100
5101 try
5102 {
5103 if (count < 0)
5104 {
5105 return error(GL_INVALID_VALUE);
5106 }
5107
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005108 if (location == -1)
5109 {
5110 return;
5111 }
5112
5113 gl::Context *context = gl::getContext();
5114
5115 if (context)
5116 {
5117 gl::Program *program = context->getCurrentProgram();
5118
5119 if (!program)
5120 {
5121 return error(GL_INVALID_OPERATION);
5122 }
5123
5124 if (!program->setUniform4iv(location, count, v))
5125 {
5126 return error(GL_INVALID_OPERATION);
5127 }
5128 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005129 }
5130 catch(std::bad_alloc&)
5131 {
5132 return error(GL_OUT_OF_MEMORY);
5133 }
5134}
5135
5136void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5137{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005138 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005139 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005140
5141 try
5142 {
5143 if (count < 0 || transpose != GL_FALSE)
5144 {
5145 return error(GL_INVALID_VALUE);
5146 }
5147
5148 if (location == -1)
5149 {
5150 return;
5151 }
5152
5153 gl::Context *context = gl::getContext();
5154
5155 if (context)
5156 {
5157 gl::Program *program = context->getCurrentProgram();
5158
5159 if (!program)
5160 {
5161 return error(GL_INVALID_OPERATION);
5162 }
5163
5164 if (!program->setUniformMatrix2fv(location, count, value))
5165 {
5166 return error(GL_INVALID_OPERATION);
5167 }
5168 }
5169 }
5170 catch(std::bad_alloc&)
5171 {
5172 return error(GL_OUT_OF_MEMORY);
5173 }
5174}
5175
5176void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5177{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005178 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005179 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005180
5181 try
5182 {
5183 if (count < 0 || transpose != GL_FALSE)
5184 {
5185 return error(GL_INVALID_VALUE);
5186 }
5187
5188 if (location == -1)
5189 {
5190 return;
5191 }
5192
5193 gl::Context *context = gl::getContext();
5194
5195 if (context)
5196 {
5197 gl::Program *program = context->getCurrentProgram();
5198
5199 if (!program)
5200 {
5201 return error(GL_INVALID_OPERATION);
5202 }
5203
5204 if (!program->setUniformMatrix3fv(location, count, value))
5205 {
5206 return error(GL_INVALID_OPERATION);
5207 }
5208 }
5209 }
5210 catch(std::bad_alloc&)
5211 {
5212 return error(GL_OUT_OF_MEMORY);
5213 }
5214}
5215
5216void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5217{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005218 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005219 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005220
5221 try
5222 {
5223 if (count < 0 || transpose != GL_FALSE)
5224 {
5225 return error(GL_INVALID_VALUE);
5226 }
5227
5228 if (location == -1)
5229 {
5230 return;
5231 }
5232
5233 gl::Context *context = gl::getContext();
5234
5235 if (context)
5236 {
5237 gl::Program *program = context->getCurrentProgram();
5238
5239 if (!program)
5240 {
5241 return error(GL_INVALID_OPERATION);
5242 }
5243
5244 if (!program->setUniformMatrix4fv(location, count, value))
5245 {
5246 return error(GL_INVALID_OPERATION);
5247 }
5248 }
5249 }
5250 catch(std::bad_alloc&)
5251 {
5252 return error(GL_OUT_OF_MEMORY);
5253 }
5254}
5255
5256void __stdcall glUseProgram(GLuint program)
5257{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005258 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005259
5260 try
5261 {
5262 gl::Context *context = gl::getContext();
5263
5264 if (context)
5265 {
5266 gl::Program *programObject = context->getProgram(program);
5267
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005268 if (!programObject && program != 0)
5269 {
5270 if (context->getShader(program))
5271 {
5272 return error(GL_INVALID_OPERATION);
5273 }
5274 else
5275 {
5276 return error(GL_INVALID_VALUE);
5277 }
5278 }
5279
5280 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005281 {
5282 return error(GL_INVALID_OPERATION);
5283 }
5284
5285 context->useProgram(program);
5286 }
5287 }
5288 catch(std::bad_alloc&)
5289 {
5290 return error(GL_OUT_OF_MEMORY);
5291 }
5292}
5293
5294void __stdcall glValidateProgram(GLuint program)
5295{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005296 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005297
5298 try
5299 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005300 gl::Context *context = gl::getContext();
5301
5302 if (context)
5303 {
5304 gl::Program *programObject = context->getProgram(program);
5305
5306 if (!programObject)
5307 {
5308 if (context->getShader(program))
5309 {
5310 return error(GL_INVALID_OPERATION);
5311 }
5312 else
5313 {
5314 return error(GL_INVALID_VALUE);
5315 }
5316 }
5317
5318 programObject->validate();
5319 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005320 }
5321 catch(std::bad_alloc&)
5322 {
5323 return error(GL_OUT_OF_MEMORY);
5324 }
5325}
5326
5327void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5328{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005329 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005330
5331 try
5332 {
5333 if (index >= gl::MAX_VERTEX_ATTRIBS)
5334 {
5335 return error(GL_INVALID_VALUE);
5336 }
5337
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005338 gl::Context *context = gl::getContext();
5339
5340 if (context)
5341 {
5342 GLfloat vals[4] = { x, 0, 0, 1 };
5343 context->setVertexAttrib(index, vals);
5344 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005345 }
5346 catch(std::bad_alloc&)
5347 {
5348 return error(GL_OUT_OF_MEMORY);
5349 }
5350}
5351
5352void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5353{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005354 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005355
5356 try
5357 {
5358 if (index >= gl::MAX_VERTEX_ATTRIBS)
5359 {
5360 return error(GL_INVALID_VALUE);
5361 }
5362
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005363 gl::Context *context = gl::getContext();
5364
5365 if (context)
5366 {
5367 GLfloat vals[4] = { values[0], 0, 0, 1 };
5368 context->setVertexAttrib(index, vals);
5369 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005370 }
5371 catch(std::bad_alloc&)
5372 {
5373 return error(GL_OUT_OF_MEMORY);
5374 }
5375}
5376
5377void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5378{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005379 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005380
5381 try
5382 {
5383 if (index >= gl::MAX_VERTEX_ATTRIBS)
5384 {
5385 return error(GL_INVALID_VALUE);
5386 }
5387
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005388 gl::Context *context = gl::getContext();
5389
5390 if (context)
5391 {
5392 GLfloat vals[4] = { x, y, 0, 1 };
5393 context->setVertexAttrib(index, vals);
5394 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005395 }
5396 catch(std::bad_alloc&)
5397 {
5398 return error(GL_OUT_OF_MEMORY);
5399 }
5400}
5401
5402void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5403{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005404 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005405
5406 try
5407 {
5408 if (index >= gl::MAX_VERTEX_ATTRIBS)
5409 {
5410 return error(GL_INVALID_VALUE);
5411 }
5412
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005413 gl::Context *context = gl::getContext();
5414
5415 if (context)
5416 {
5417 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5418 context->setVertexAttrib(index, vals);
5419 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005420 }
5421 catch(std::bad_alloc&)
5422 {
5423 return error(GL_OUT_OF_MEMORY);
5424 }
5425}
5426
5427void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5428{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005429 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 +00005430
5431 try
5432 {
5433 if (index >= gl::MAX_VERTEX_ATTRIBS)
5434 {
5435 return error(GL_INVALID_VALUE);
5436 }
5437
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005438 gl::Context *context = gl::getContext();
5439
5440 if (context)
5441 {
5442 GLfloat vals[4] = { x, y, z, 1 };
5443 context->setVertexAttrib(index, vals);
5444 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005445 }
5446 catch(std::bad_alloc&)
5447 {
5448 return error(GL_OUT_OF_MEMORY);
5449 }
5450}
5451
5452void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5453{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005454 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005455
5456 try
5457 {
5458 if (index >= gl::MAX_VERTEX_ATTRIBS)
5459 {
5460 return error(GL_INVALID_VALUE);
5461 }
5462
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005463 gl::Context *context = gl::getContext();
5464
5465 if (context)
5466 {
5467 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5468 context->setVertexAttrib(index, vals);
5469 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005470 }
5471 catch(std::bad_alloc&)
5472 {
5473 return error(GL_OUT_OF_MEMORY);
5474 }
5475}
5476
5477void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5478{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005479 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 +00005480
5481 try
5482 {
5483 if (index >= gl::MAX_VERTEX_ATTRIBS)
5484 {
5485 return error(GL_INVALID_VALUE);
5486 }
5487
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005488 gl::Context *context = gl::getContext();
5489
5490 if (context)
5491 {
5492 GLfloat vals[4] = { x, y, z, w };
5493 context->setVertexAttrib(index, vals);
5494 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005495 }
5496 catch(std::bad_alloc&)
5497 {
5498 return error(GL_OUT_OF_MEMORY);
5499 }
5500}
5501
5502void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5503{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005504 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005505
5506 try
5507 {
5508 if (index >= gl::MAX_VERTEX_ATTRIBS)
5509 {
5510 return error(GL_INVALID_VALUE);
5511 }
5512
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005513 gl::Context *context = gl::getContext();
5514
5515 if (context)
5516 {
5517 context->setVertexAttrib(index, values);
5518 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005519 }
5520 catch(std::bad_alloc&)
5521 {
5522 return error(GL_OUT_OF_MEMORY);
5523 }
5524}
5525
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005526void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005527{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005528 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005529 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005530 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005531
5532 try
5533 {
5534 if (index >= gl::MAX_VERTEX_ATTRIBS)
5535 {
5536 return error(GL_INVALID_VALUE);
5537 }
5538
5539 if (size < 1 || size > 4)
5540 {
5541 return error(GL_INVALID_VALUE);
5542 }
5543
5544 switch (type)
5545 {
5546 case GL_BYTE:
5547 case GL_UNSIGNED_BYTE:
5548 case GL_SHORT:
5549 case GL_UNSIGNED_SHORT:
5550 case GL_FIXED:
5551 case GL_FLOAT:
5552 break;
5553 default:
5554 return error(GL_INVALID_ENUM);
5555 }
5556
5557 if (stride < 0)
5558 {
5559 return error(GL_INVALID_VALUE);
5560 }
5561
5562 gl::Context *context = gl::getContext();
5563
5564 if (context)
5565 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005566 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005567 }
5568 }
5569 catch(std::bad_alloc&)
5570 {
5571 return error(GL_OUT_OF_MEMORY);
5572 }
5573}
5574
5575void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5576{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005577 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 +00005578
5579 try
5580 {
5581 if (width < 0 || height < 0)
5582 {
5583 return error(GL_INVALID_VALUE);
5584 }
5585
5586 gl::Context *context = gl::getContext();
5587
5588 if (context)
5589 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005590 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005591 }
5592 }
5593 catch(std::bad_alloc&)
5594 {
5595 return error(GL_OUT_OF_MEMORY);
5596 }
5597}
5598
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005599void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5600 GLbitfield mask, GLenum filter)
5601{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005602 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005603 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5604 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5605 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5606
5607 try
5608 {
5609 switch (filter)
5610 {
5611 case GL_NEAREST:
5612 break;
5613 default:
5614 return error(GL_INVALID_ENUM);
5615 }
5616
5617 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5618 {
5619 return error(GL_INVALID_VALUE);
5620 }
5621
5622 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5623 {
5624 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5625 return error(GL_INVALID_OPERATION);
5626 }
5627
5628 gl::Context *context = gl::getContext();
5629
5630 if (context)
5631 {
5632 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5633 {
5634 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5635 return error(GL_INVALID_OPERATION);
5636 }
5637
5638 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5639 }
5640 }
5641 catch(std::bad_alloc&)
5642 {
5643 return error(GL_OUT_OF_MEMORY);
5644 }
5645}
5646
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005647void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5648 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005649{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005650 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005651 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005652 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005653 target, level, internalformat, width, height, depth, border, format, type, pixels);
5654
5655 try
5656 {
5657 UNIMPLEMENTED(); // FIXME
5658 }
5659 catch(std::bad_alloc&)
5660 {
5661 return error(GL_OUT_OF_MEMORY);
5662 }
5663}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005664
5665__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5666{
5667 struct Extension
5668 {
5669 const char *name;
5670 __eglMustCastToProperFunctionPointerType address;
5671 };
5672
5673 static const Extension glExtensions[] =
5674 {
5675 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00005676 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00005677 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005678 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
5679 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
5680 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
5681 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
5682 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
5683 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
5684 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005685 };
5686
5687 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5688 {
5689 if (strcmp(procname, glExtensions[ext].name) == 0)
5690 {
5691 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5692 }
5693 }
5694
5695 return NULL;
5696}
5697
jbauman@chromium.orgae345802011-03-30 22:04:25 +00005698void __stdcall glBindTexImage(egl::Surface *surface)
5699{
5700 EVENT("(egl::Surface* surface = 0x%0.8p)",
5701 surface);
5702
5703 try
5704 {
5705 gl::Context *context = gl::getContext();
5706
5707 if (context)
5708 {
5709 gl::Texture2D *textureObject = context->getTexture2D();
5710
5711 if (textureObject)
5712 {
5713 textureObject->bindTexImage(surface);
5714 }
5715 }
5716 }
5717 catch(std::bad_alloc&)
5718 {
5719 return error(GL_OUT_OF_MEMORY);
5720 }
5721}
5722
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005723}