blob: 6c6e846bcec8d3457a0762e12098e6b23f456226 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// 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
31extern "C"
32{
33
34void __stdcall glActiveTexture(GLenum texture)
35{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +000036 EVENT("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000037
38 try
39 {
40 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
41 {
42 return error(GL_INVALID_ENUM);
43 }
44
45 gl::Context *context = gl::getContext();
46
47 if (context)
48 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +000049 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000050 }
51 }
52 catch(std::bad_alloc&)
53 {
54 return error(GL_OUT_OF_MEMORY);
55 }
56}
57
58void __stdcall glAttachShader(GLuint program, GLuint shader)
59{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +000060 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000061
62 try
63 {
64 gl::Context *context = gl::getContext();
65
66 if (context)
67 {
68 gl::Program *programObject = context->getProgram(program);
69 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000070
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000071 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000072 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000073 if (context->getShader(program))
74 {
75 return error(GL_INVALID_OPERATION);
76 }
77 else
78 {
79 return error(GL_INVALID_VALUE);
80 }
81 }
82
83 if (!shaderObject)
84 {
85 if (context->getProgram(shader))
86 {
87 return error(GL_INVALID_OPERATION);
88 }
89 else
90 {
91 return error(GL_INVALID_VALUE);
92 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000093 }
94
95 if (!programObject->attachShader(shaderObject))
96 {
97 return error(GL_INVALID_OPERATION);
98 }
99 }
100 }
101 catch(std::bad_alloc&)
102 {
103 return error(GL_OUT_OF_MEMORY);
104 }
105}
106
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000107void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000109 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000110
111 try
112 {
113 if (index >= gl::MAX_VERTEX_ATTRIBS)
114 {
115 return error(GL_INVALID_VALUE);
116 }
117
118 gl::Context *context = gl::getContext();
119
120 if (context)
121 {
122 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000123
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000124 if (!programObject)
125 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000126 if (context->getShader(program))
127 {
128 return error(GL_INVALID_OPERATION);
129 }
130 else
131 {
132 return error(GL_INVALID_VALUE);
133 }
134 }
135
136 if (strncmp(name, "gl_", 3) == 0)
137 {
138 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000139 }
140
141 programObject->bindAttributeLocation(index, name);
142 }
143 }
144 catch(std::bad_alloc&)
145 {
146 return error(GL_OUT_OF_MEMORY);
147 }
148}
149
150void __stdcall glBindBuffer(GLenum target, GLuint buffer)
151{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000152 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000153
154 try
155 {
156 gl::Context *context = gl::getContext();
157
158 if (context)
159 {
160 switch (target)
161 {
162 case GL_ARRAY_BUFFER:
163 context->bindArrayBuffer(buffer);
164 return;
165 case GL_ELEMENT_ARRAY_BUFFER:
166 context->bindElementArrayBuffer(buffer);
167 return;
168 default:
169 return error(GL_INVALID_ENUM);
170 }
171 }
172 }
173 catch(std::bad_alloc&)
174 {
175 return error(GL_OUT_OF_MEMORY);
176 }
177}
178
179void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
180{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000181 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000182
183 try
184 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000185 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000186 {
187 return error(GL_INVALID_ENUM);
188 }
189
190 gl::Context *context = gl::getContext();
191
192 if (context)
193 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000194 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
195 {
196 context->bindReadFramebuffer(framebuffer);
197 }
198
199 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
200 {
201 context->bindDrawFramebuffer(framebuffer);
202 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000203 }
204 }
205 catch(std::bad_alloc&)
206 {
207 return error(GL_OUT_OF_MEMORY);
208 }
209}
210
211void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
212{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000213 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000214
215 try
216 {
217 if (target != GL_RENDERBUFFER)
218 {
219 return error(GL_INVALID_ENUM);
220 }
221
222 gl::Context *context = gl::getContext();
223
224 if (context)
225 {
226 context->bindRenderbuffer(renderbuffer);
227 }
228 }
229 catch(std::bad_alloc&)
230 {
231 return error(GL_OUT_OF_MEMORY);
232 }
233}
234
235void __stdcall glBindTexture(GLenum target, GLuint texture)
236{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000237 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000238
239 try
240 {
241 gl::Context *context = gl::getContext();
242
243 if (context)
244 {
245 gl::Texture *textureObject = context->getTexture(texture);
246
247 if (textureObject && textureObject->getTarget() != target && texture != 0)
248 {
249 return error(GL_INVALID_OPERATION);
250 }
251
252 switch (target)
253 {
254 case GL_TEXTURE_2D:
255 context->bindTexture2D(texture);
256 return;
257 case GL_TEXTURE_CUBE_MAP:
258 context->bindTextureCubeMap(texture);
259 return;
260 default:
261 return error(GL_INVALID_ENUM);
262 }
263 }
264 }
265 catch(std::bad_alloc&)
266 {
267 return error(GL_OUT_OF_MEMORY);
268 }
269}
270
271void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
272{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000273 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000274 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000275
276 try
277 {
278 gl::Context* context = gl::getContext();
279
280 if (context)
281 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000282 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000283 }
284 }
285 catch(std::bad_alloc&)
286 {
287 return error(GL_OUT_OF_MEMORY);
288 }
289}
290
291void __stdcall glBlendEquation(GLenum mode)
292{
293 glBlendEquationSeparate(mode, mode);
294}
295
296void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
297{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000298 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000299
300 try
301 {
302 switch (modeRGB)
303 {
304 case GL_FUNC_ADD:
305 case GL_FUNC_SUBTRACT:
306 case GL_FUNC_REVERSE_SUBTRACT:
307 break;
308 default:
309 return error(GL_INVALID_ENUM);
310 }
311
312 switch (modeAlpha)
313 {
314 case GL_FUNC_ADD:
315 case GL_FUNC_SUBTRACT:
316 case GL_FUNC_REVERSE_SUBTRACT:
317 break;
318 default:
319 return error(GL_INVALID_ENUM);
320 }
321
322 gl::Context *context = gl::getContext();
323
324 if (context)
325 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000326 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000327 }
328 }
329 catch(std::bad_alloc&)
330 {
331 return error(GL_OUT_OF_MEMORY);
332 }
333}
334
335void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
336{
337 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
338}
339
340void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
341{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000342 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 +0000343 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000344
345 try
346 {
347 switch (srcRGB)
348 {
349 case GL_ZERO:
350 case GL_ONE:
351 case GL_SRC_COLOR:
352 case GL_ONE_MINUS_SRC_COLOR:
353 case GL_DST_COLOR:
354 case GL_ONE_MINUS_DST_COLOR:
355 case GL_SRC_ALPHA:
356 case GL_ONE_MINUS_SRC_ALPHA:
357 case GL_DST_ALPHA:
358 case GL_ONE_MINUS_DST_ALPHA:
359 case GL_CONSTANT_COLOR:
360 case GL_ONE_MINUS_CONSTANT_COLOR:
361 case GL_CONSTANT_ALPHA:
362 case GL_ONE_MINUS_CONSTANT_ALPHA:
363 case GL_SRC_ALPHA_SATURATE:
364 break;
365 default:
366 return error(GL_INVALID_ENUM);
367 }
368
369 switch (dstRGB)
370 {
371 case GL_ZERO:
372 case GL_ONE:
373 case GL_SRC_COLOR:
374 case GL_ONE_MINUS_SRC_COLOR:
375 case GL_DST_COLOR:
376 case GL_ONE_MINUS_DST_COLOR:
377 case GL_SRC_ALPHA:
378 case GL_ONE_MINUS_SRC_ALPHA:
379 case GL_DST_ALPHA:
380 case GL_ONE_MINUS_DST_ALPHA:
381 case GL_CONSTANT_COLOR:
382 case GL_ONE_MINUS_CONSTANT_COLOR:
383 case GL_CONSTANT_ALPHA:
384 case GL_ONE_MINUS_CONSTANT_ALPHA:
385 break;
386 default:
387 return error(GL_INVALID_ENUM);
388 }
389
390 switch (srcAlpha)
391 {
392 case GL_ZERO:
393 case GL_ONE:
394 case GL_SRC_COLOR:
395 case GL_ONE_MINUS_SRC_COLOR:
396 case GL_DST_COLOR:
397 case GL_ONE_MINUS_DST_COLOR:
398 case GL_SRC_ALPHA:
399 case GL_ONE_MINUS_SRC_ALPHA:
400 case GL_DST_ALPHA:
401 case GL_ONE_MINUS_DST_ALPHA:
402 case GL_CONSTANT_COLOR:
403 case GL_ONE_MINUS_CONSTANT_COLOR:
404 case GL_CONSTANT_ALPHA:
405 case GL_ONE_MINUS_CONSTANT_ALPHA:
406 case GL_SRC_ALPHA_SATURATE:
407 break;
408 default:
409 return error(GL_INVALID_ENUM);
410 }
411
412 switch (dstAlpha)
413 {
414 case GL_ZERO:
415 case GL_ONE:
416 case GL_SRC_COLOR:
417 case GL_ONE_MINUS_SRC_COLOR:
418 case GL_DST_COLOR:
419 case GL_ONE_MINUS_DST_COLOR:
420 case GL_SRC_ALPHA:
421 case GL_ONE_MINUS_SRC_ALPHA:
422 case GL_DST_ALPHA:
423 case GL_ONE_MINUS_DST_ALPHA:
424 case GL_CONSTANT_COLOR:
425 case GL_ONE_MINUS_CONSTANT_COLOR:
426 case GL_CONSTANT_ALPHA:
427 case GL_ONE_MINUS_CONSTANT_ALPHA:
428 break;
429 default:
430 return error(GL_INVALID_ENUM);
431 }
432
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000433 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
434 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
435
436 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
437 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
438
439 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000440 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000441 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
442 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000443 }
444
445 gl::Context *context = gl::getContext();
446
447 if (context)
448 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000449 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000450 }
451 }
452 catch(std::bad_alloc&)
453 {
454 return error(GL_OUT_OF_MEMORY);
455 }
456}
457
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000458void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000459{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000460 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 +0000461 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000462
463 try
464 {
465 if (size < 0)
466 {
467 return error(GL_INVALID_VALUE);
468 }
469
470 switch (usage)
471 {
472 case GL_STREAM_DRAW:
473 case GL_STATIC_DRAW:
474 case GL_DYNAMIC_DRAW:
475 break;
476 default:
477 return error(GL_INVALID_ENUM);
478 }
479
480 gl::Context *context = gl::getContext();
481
482 if (context)
483 {
484 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000485
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000486 switch (target)
487 {
488 case GL_ARRAY_BUFFER:
489 buffer = context->getArrayBuffer();
490 break;
491 case GL_ELEMENT_ARRAY_BUFFER:
492 buffer = context->getElementArrayBuffer();
493 break;
494 default:
495 return error(GL_INVALID_ENUM);
496 }
497
498 if (!buffer)
499 {
500 return error(GL_INVALID_OPERATION);
501 }
502
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000503 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000504 }
505 }
506 catch(std::bad_alloc&)
507 {
508 return error(GL_OUT_OF_MEMORY);
509 }
510}
511
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000512void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000513{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000514 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 +0000515 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000516
517 try
518 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000519 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000520 {
521 return error(GL_INVALID_VALUE);
522 }
523
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000524 if (data == NULL)
525 {
526 return;
527 }
528
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000529 gl::Context *context = gl::getContext();
530
531 if (context)
532 {
533 gl::Buffer *buffer;
534
535 switch (target)
536 {
537 case GL_ARRAY_BUFFER:
538 buffer = context->getArrayBuffer();
539 break;
540 case GL_ELEMENT_ARRAY_BUFFER:
541 buffer = context->getElementArrayBuffer();
542 break;
543 default:
544 return error(GL_INVALID_ENUM);
545 }
546
547 if (!buffer)
548 {
549 return error(GL_INVALID_OPERATION);
550 }
551
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000552 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000553 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000554 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000555 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000556
557 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000558 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000559 }
560 catch(std::bad_alloc&)
561 {
562 return error(GL_OUT_OF_MEMORY);
563 }
564}
565
566GLenum __stdcall glCheckFramebufferStatus(GLenum target)
567{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000568 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000569
570 try
571 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000572 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000573 {
574 return error(GL_INVALID_ENUM, 0);
575 }
576
577 gl::Context *context = gl::getContext();
578
579 if (context)
580 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000581 gl::Framebuffer *framebuffer = NULL;
582 if (target == GL_READ_FRAMEBUFFER_ANGLE)
583 {
584 framebuffer = context->getReadFramebuffer();
585 }
586 else
587 {
588 framebuffer = context->getDrawFramebuffer();
589 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000590
591 return framebuffer->completeness();
592 }
593 }
594 catch(std::bad_alloc&)
595 {
596 return error(GL_OUT_OF_MEMORY, 0);
597 }
598
599 return 0;
600}
601
602void __stdcall glClear(GLbitfield mask)
603{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000604 EVENT("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000605
606 try
607 {
608 gl::Context *context = gl::getContext();
609
610 if (context)
611 {
612 context->clear(mask);
613 }
614 }
615 catch(std::bad_alloc&)
616 {
617 return error(GL_OUT_OF_MEMORY);
618 }
619}
620
621void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
622{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000623 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000624 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000625
626 try
627 {
628 gl::Context *context = gl::getContext();
629
630 if (context)
631 {
632 context->setClearColor(red, green, blue, alpha);
633 }
634 }
635 catch(std::bad_alloc&)
636 {
637 return error(GL_OUT_OF_MEMORY);
638 }
639}
640
641void __stdcall glClearDepthf(GLclampf depth)
642{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000643 EVENT("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000644
645 try
646 {
647 gl::Context *context = gl::getContext();
648
649 if (context)
650 {
651 context->setClearDepth(depth);
652 }
653 }
654 catch(std::bad_alloc&)
655 {
656 return error(GL_OUT_OF_MEMORY);
657 }
658}
659
660void __stdcall glClearStencil(GLint s)
661{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000662 EVENT("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000663
664 try
665 {
666 gl::Context *context = gl::getContext();
667
668 if (context)
669 {
670 context->setClearStencil(s);
671 }
672 }
673 catch(std::bad_alloc&)
674 {
675 return error(GL_OUT_OF_MEMORY);
676 }
677}
678
679void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
680{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000681 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000682 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000683
684 try
685 {
686 gl::Context *context = gl::getContext();
687
688 if (context)
689 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000690 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000691 }
692 }
693 catch(std::bad_alloc&)
694 {
695 return error(GL_OUT_OF_MEMORY);
696 }
697}
698
699void __stdcall glCompileShader(GLuint shader)
700{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000701 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000702
703 try
704 {
705 gl::Context *context = gl::getContext();
706
707 if (context)
708 {
709 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000710
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000711 if (!shaderObject)
712 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000713 if (context->getProgram(shader))
714 {
715 return error(GL_INVALID_OPERATION);
716 }
717 else
718 {
719 return error(GL_INVALID_VALUE);
720 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000721 }
722
723 shaderObject->compile();
724 }
725 }
726 catch(std::bad_alloc&)
727 {
728 return error(GL_OUT_OF_MEMORY);
729 }
730}
731
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000732void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
733 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000734{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000735 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000736 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000737 target, level, internalformat, width, height, border, imageSize, data);
738
739 try
740 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000741 if (level < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000742 {
743 return error(GL_INVALID_VALUE);
744 }
745
daniel@transgaming.com41430492010-03-11 20:36:18 +0000746 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
747 {
748 return error(GL_INVALID_VALUE);
749 }
750
daniel@transgaming.com01868132010-08-24 19:21:17 +0000751 switch (internalformat)
752 {
753 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
754 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
755 break;
756 default:
757 return error(GL_INVALID_ENUM);
758 }
759
760 if (border != 0)
761 {
762 return error(GL_INVALID_VALUE);
763 }
764
765 gl::Context *context = gl::getContext();
766
767 if (context)
768 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000769 if (level > context->getMaximumTextureLevel())
770 {
771 return error(GL_INVALID_VALUE);
772 }
773
774 switch (target)
775 {
776 case GL_TEXTURE_2D:
777 if (width > (context->getMaximumTextureDimension() >> level) ||
778 height > (context->getMaximumTextureDimension() >> level))
779 {
780 return error(GL_INVALID_VALUE);
781 }
782 break;
783 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
784 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
785 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
786 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
787 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
788 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
789 if (width != height)
790 {
791 return error(GL_INVALID_VALUE);
792 }
793
794 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
795 height > (context->getMaximumCubeTextureDimension() >> level))
796 {
797 return error(GL_INVALID_VALUE);
798 }
799 break;
800 default:
801 return error(GL_INVALID_ENUM);
802 }
803
daniel@transgaming.com01868132010-08-24 19:21:17 +0000804 if (!context->supportsCompressedTextures())
805 {
806 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
807 }
808
809 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
810 {
811 return error(GL_INVALID_VALUE);
812 }
813
814 if (target == GL_TEXTURE_2D)
815 {
816 gl::Texture2D *texture = context->getTexture2D();
817
818 if (!texture)
819 {
820 return error(GL_INVALID_OPERATION);
821 }
822
823 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
824 }
825 else
826 {
827 gl::TextureCubeMap *texture = context->getTextureCubeMap();
828
829 if (!texture)
830 {
831 return error(GL_INVALID_OPERATION);
832 }
833
834 switch (target)
835 {
836 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
837 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
838 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
839 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
840 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
841 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
842 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
843 break;
844 default: UNREACHABLE();
845 }
846 }
847 }
848
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000849 }
850 catch(std::bad_alloc&)
851 {
852 return error(GL_OUT_OF_MEMORY);
853 }
854}
855
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000856void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
857 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000858{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000859 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000860 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000861 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000862 target, level, xoffset, yoffset, width, height, format, imageSize, data);
863
864 try
865 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000866 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000867 {
868 return error(GL_INVALID_ENUM);
869 }
870
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000871 if (level < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000872 {
873 return error(GL_INVALID_VALUE);
874 }
875
daniel@transgaming.com01868132010-08-24 19:21:17 +0000876 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 ||
877 (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000878 {
879 return error(GL_INVALID_VALUE);
880 }
881
daniel@transgaming.com01868132010-08-24 19:21:17 +0000882 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000883 {
daniel@transgaming.com01868132010-08-24 19:21:17 +0000884 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
885 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
886 break;
887 default:
888 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +0000889 }
890
daniel@transgaming.com01868132010-08-24 19:21:17 +0000891 if (width == 0 || height == 0 || data == NULL)
892 {
893 return;
894 }
895
896 gl::Context *context = gl::getContext();
897
898 if (context)
899 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000900 if (level > context->getMaximumTextureLevel())
901 {
902 return error(GL_INVALID_VALUE);
903 }
904
daniel@transgaming.com01868132010-08-24 19:21:17 +0000905 if (!context->supportsCompressedTextures())
906 {
907 return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
908 }
909
910 if (imageSize != gl::ComputeCompressedSize(width, height, format))
911 {
912 return error(GL_INVALID_VALUE);
913 }
914
915 if (xoffset % 4 != 0 || yoffset % 4 != 0)
916 {
917 return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
918 // does not exist unless DXT1 textures are supported.
919 }
920
921 if (target == GL_TEXTURE_2D)
922 {
923 gl::Texture2D *texture = context->getTexture2D();
924
925 if (!texture)
926 {
927 return error(GL_INVALID_OPERATION);
928 }
929
930 if (!texture->isCompressed())
931 {
932 return error(GL_INVALID_OPERATION);
933 }
934
935 if ((width % 4 != 0 && width != texture->getWidth()) ||
936 (height % 4 != 0 && height != texture->getHeight()))
937 {
938 return error(GL_INVALID_OPERATION);
939 }
940
941 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
942 }
943 else if (gl::IsCubemapTextureTarget(target))
944 {
945 gl::TextureCubeMap *texture = context->getTextureCubeMap();
946
947 if (!texture)
948 {
949 return error(GL_INVALID_OPERATION);
950 }
951
952 if (!texture->isCompressed())
953 {
954 return error(GL_INVALID_OPERATION);
955 }
956
957 if ((width % 4 != 0 && width != texture->getWidth()) ||
958 (height % 4 != 0 && height != texture->getHeight()))
959 {
960 return error(GL_INVALID_OPERATION);
961 }
962
963 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
964 }
965 else
966 {
967 UNREACHABLE();
968 }
969 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000970 }
971 catch(std::bad_alloc&)
972 {
973 return error(GL_OUT_OF_MEMORY);
974 }
975}
976
977void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
978{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000979 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000980 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000981 target, level, internalformat, x, y, width, height, border);
982
983 try
984 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000985 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000986 {
987 return error(GL_INVALID_VALUE);
988 }
989
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000990 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
991 {
992 return error(GL_INVALID_VALUE);
993 }
994
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000995 if (border != 0)
996 {
997 return error(GL_INVALID_VALUE);
998 }
999
1000 gl::Context *context = gl::getContext();
1001
1002 if (context)
1003 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001004 switch (target)
1005 {
1006 case GL_TEXTURE_2D:
1007 if (width > (context->getMaximumTextureDimension() >> level) ||
1008 height > (context->getMaximumTextureDimension() >> level))
1009 {
1010 return error(GL_INVALID_VALUE);
1011 }
1012 break;
1013 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1014 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1015 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1016 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1017 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1018 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1019 if (width != height)
1020 {
1021 return error(GL_INVALID_VALUE);
1022 }
1023
1024 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1025 height > (context->getMaximumCubeTextureDimension() >> level))
1026 {
1027 return error(GL_INVALID_VALUE);
1028 }
1029 break;
1030 default:
1031 return error(GL_INVALID_ENUM);
1032 }
1033
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001034 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001035
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001036 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1037 {
1038 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1039 }
1040
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001041 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1042 {
1043 return error(GL_INVALID_OPERATION);
1044 }
1045
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001046 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001047 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001048
1049 // [OpenGL ES 2.0.24] table 3.9
1050 switch (internalformat)
1051 {
1052 case GL_ALPHA:
1053 if (colorbufferFormat != GL_ALPHA &&
1054 colorbufferFormat != GL_RGBA &&
1055 colorbufferFormat != GL_RGBA4 &&
1056 colorbufferFormat != GL_RGB5_A1 &&
1057 colorbufferFormat != GL_RGBA8_OES)
1058 {
1059 return error(GL_INVALID_OPERATION);
1060 }
1061 break;
1062 case GL_LUMINANCE:
1063 case GL_RGB:
1064 if (colorbufferFormat != GL_RGB &&
1065 colorbufferFormat != GL_RGB565 &&
1066 colorbufferFormat != GL_RGB8_OES &&
1067 colorbufferFormat != GL_RGBA &&
1068 colorbufferFormat != GL_RGBA4 &&
1069 colorbufferFormat != GL_RGB5_A1 &&
1070 colorbufferFormat != GL_RGBA8_OES)
1071 {
1072 return error(GL_INVALID_OPERATION);
1073 }
1074 break;
1075 case GL_LUMINANCE_ALPHA:
1076 case GL_RGBA:
1077 if (colorbufferFormat != GL_RGBA &&
1078 colorbufferFormat != GL_RGBA4 &&
1079 colorbufferFormat != GL_RGB5_A1 &&
1080 colorbufferFormat != GL_RGBA8_OES)
1081 {
1082 return error(GL_INVALID_OPERATION);
1083 }
1084 break;
1085 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1086 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1087 if (context->supportsCompressedTextures())
1088 {
1089 return error(GL_INVALID_OPERATION);
1090 }
1091 else
1092 {
1093 return error(GL_INVALID_ENUM);
1094 }
1095 break;
1096 default:
1097 return error(GL_INVALID_ENUM);
1098 }
1099
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001100 if (target == GL_TEXTURE_2D)
1101 {
1102 gl::Texture2D *texture = context->getTexture2D();
1103
1104 if (!texture)
1105 {
1106 return error(GL_INVALID_OPERATION);
1107 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001108
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001109 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001110 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001111 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001112 {
1113 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1114
1115 if (!texture)
1116 {
1117 return error(GL_INVALID_OPERATION);
1118 }
1119
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001120 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001121 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001122 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001123 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001124 }
1125 catch(std::bad_alloc&)
1126 {
1127 return error(GL_OUT_OF_MEMORY);
1128 }
1129}
1130
1131void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1132{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001133 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001134 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001135 target, level, xoffset, yoffset, x, y, width, height);
1136
1137 try
1138 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001139 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001140 {
1141 return error(GL_INVALID_ENUM);
1142 }
1143
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001144 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001145 {
1146 return error(GL_INVALID_VALUE);
1147 }
1148
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001149 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1150 {
1151 return error(GL_INVALID_VALUE);
1152 }
1153
1154 if (width == 0 || height == 0)
1155 {
1156 return;
1157 }
1158
1159 gl::Context *context = gl::getContext();
1160
1161 if (context)
1162 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001163 if (level > context->getMaximumTextureLevel())
1164 {
1165 return error(GL_INVALID_VALUE);
1166 }
1167
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001168 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001169
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001170 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1171 {
1172 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1173 }
1174
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001175 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1176 {
1177 return error(GL_INVALID_OPERATION);
1178 }
1179
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001180 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001181 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001182 gl::Texture *texture = NULL;
1183
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001184 if (target == GL_TEXTURE_2D)
1185 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001186 texture = context->getTexture2D();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001187 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001188 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001189 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001190 texture = context->getTextureCubeMap();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001191 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001192 else UNREACHABLE();
1193
1194 if (!texture)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001195 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001196 return error(GL_INVALID_OPERATION);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001197 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001198
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001199 GLenum textureFormat = texture->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001200
1201 // [OpenGL ES 2.0.24] table 3.9
1202 switch (textureFormat)
1203 {
1204 case GL_ALPHA:
1205 if (colorbufferFormat != GL_ALPHA &&
1206 colorbufferFormat != GL_RGBA &&
1207 colorbufferFormat != GL_RGBA4 &&
1208 colorbufferFormat != GL_RGB5_A1 &&
1209 colorbufferFormat != GL_RGBA8_OES)
1210 {
1211 return error(GL_INVALID_OPERATION);
1212 }
1213 break;
1214 case GL_LUMINANCE:
1215 case GL_RGB:
1216 if (colorbufferFormat != GL_RGB &&
1217 colorbufferFormat != GL_RGB565 &&
1218 colorbufferFormat != GL_RGB8_OES &&
1219 colorbufferFormat != GL_RGBA &&
1220 colorbufferFormat != GL_RGBA4 &&
1221 colorbufferFormat != GL_RGB5_A1 &&
1222 colorbufferFormat != GL_RGBA8_OES)
1223 {
1224 return error(GL_INVALID_OPERATION);
1225 }
1226 break;
1227 case GL_LUMINANCE_ALPHA:
1228 case GL_RGBA:
1229 if (colorbufferFormat != GL_RGBA &&
1230 colorbufferFormat != GL_RGBA4 &&
1231 colorbufferFormat != GL_RGB5_A1 &&
1232 colorbufferFormat != GL_RGBA8_OES)
1233 {
1234 return error(GL_INVALID_OPERATION);
1235 }
1236 break;
1237 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1238 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1239 return error(GL_INVALID_OPERATION);
1240 default:
1241 return error(GL_INVALID_OPERATION);
1242 }
1243
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001244 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001245 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001246 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001247
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001248 catch(std::bad_alloc&)
1249 {
1250 return error(GL_OUT_OF_MEMORY);
1251 }
1252}
1253
1254GLuint __stdcall glCreateProgram(void)
1255{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001256 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001257
1258 try
1259 {
1260 gl::Context *context = gl::getContext();
1261
1262 if (context)
1263 {
1264 return context->createProgram();
1265 }
1266 }
1267 catch(std::bad_alloc&)
1268 {
1269 return error(GL_OUT_OF_MEMORY, 0);
1270 }
1271
1272 return 0;
1273}
1274
1275GLuint __stdcall glCreateShader(GLenum type)
1276{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001277 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001278
1279 try
1280 {
1281 gl::Context *context = gl::getContext();
1282
1283 if (context)
1284 {
1285 switch (type)
1286 {
1287 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001288 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001289 return context->createShader(type);
1290 default:
1291 return error(GL_INVALID_ENUM, 0);
1292 }
1293 }
1294 }
1295 catch(std::bad_alloc&)
1296 {
1297 return error(GL_OUT_OF_MEMORY, 0);
1298 }
1299
1300 return 0;
1301}
1302
1303void __stdcall glCullFace(GLenum mode)
1304{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001305 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001306
1307 try
1308 {
1309 switch (mode)
1310 {
1311 case GL_FRONT:
1312 case GL_BACK:
1313 case GL_FRONT_AND_BACK:
1314 {
1315 gl::Context *context = gl::getContext();
1316
1317 if (context)
1318 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001319 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001320 }
1321 }
1322 break;
1323 default:
1324 return error(GL_INVALID_ENUM);
1325 }
1326 }
1327 catch(std::bad_alloc&)
1328 {
1329 return error(GL_OUT_OF_MEMORY);
1330 }
1331}
1332
1333void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1334{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001335 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001336
1337 try
1338 {
1339 if (n < 0)
1340 {
1341 return error(GL_INVALID_VALUE);
1342 }
1343
1344 gl::Context *context = gl::getContext();
1345
1346 if (context)
1347 {
1348 for (int i = 0; i < n; i++)
1349 {
1350 context->deleteBuffer(buffers[i]);
1351 }
1352 }
1353 }
1354 catch(std::bad_alloc&)
1355 {
1356 return error(GL_OUT_OF_MEMORY);
1357 }
1358}
1359
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001360void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1361{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001362 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001363
1364 try
1365 {
1366 if (n < 0)
1367 {
1368 return error(GL_INVALID_VALUE);
1369 }
1370
1371 gl::Context *context = gl::getContext();
1372
1373 if (context)
1374 {
1375 for (int i = 0; i < n; i++)
1376 {
1377 context->deleteFence(fences[i]);
1378 }
1379 }
1380 }
1381 catch(std::bad_alloc&)
1382 {
1383 return error(GL_OUT_OF_MEMORY);
1384 }
1385}
1386
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001387void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1388{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001389 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001390
1391 try
1392 {
1393 if (n < 0)
1394 {
1395 return error(GL_INVALID_VALUE);
1396 }
1397
1398 gl::Context *context = gl::getContext();
1399
1400 if (context)
1401 {
1402 for (int i = 0; i < n; i++)
1403 {
1404 if (framebuffers[i] != 0)
1405 {
1406 context->deleteFramebuffer(framebuffers[i]);
1407 }
1408 }
1409 }
1410 }
1411 catch(std::bad_alloc&)
1412 {
1413 return error(GL_OUT_OF_MEMORY);
1414 }
1415}
1416
1417void __stdcall glDeleteProgram(GLuint program)
1418{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001419 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001420
1421 try
1422 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001423 if (program == 0)
1424 {
1425 return;
1426 }
1427
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001428 gl::Context *context = gl::getContext();
1429
1430 if (context)
1431 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001432 if (!context->getProgram(program))
1433 {
1434 if(context->getShader(program))
1435 {
1436 return error(GL_INVALID_OPERATION);
1437 }
1438 else
1439 {
1440 return error(GL_INVALID_VALUE);
1441 }
1442 }
1443
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001444 context->deleteProgram(program);
1445 }
1446 }
1447 catch(std::bad_alloc&)
1448 {
1449 return error(GL_OUT_OF_MEMORY);
1450 }
1451}
1452
1453void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1454{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001455 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001456
1457 try
1458 {
1459 if (n < 0)
1460 {
1461 return error(GL_INVALID_VALUE);
1462 }
1463
1464 gl::Context *context = gl::getContext();
1465
1466 if (context)
1467 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001468 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001469 {
1470 context->deleteRenderbuffer(renderbuffers[i]);
1471 }
1472 }
1473 }
1474 catch(std::bad_alloc&)
1475 {
1476 return error(GL_OUT_OF_MEMORY);
1477 }
1478}
1479
1480void __stdcall glDeleteShader(GLuint shader)
1481{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001482 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001483
1484 try
1485 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001486 if (shader == 0)
1487 {
1488 return;
1489 }
1490
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001491 gl::Context *context = gl::getContext();
1492
1493 if (context)
1494 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001495 if (!context->getShader(shader))
1496 {
1497 if(context->getProgram(shader))
1498 {
1499 return error(GL_INVALID_OPERATION);
1500 }
1501 else
1502 {
1503 return error(GL_INVALID_VALUE);
1504 }
1505 }
1506
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001507 context->deleteShader(shader);
1508 }
1509 }
1510 catch(std::bad_alloc&)
1511 {
1512 return error(GL_OUT_OF_MEMORY);
1513 }
1514}
1515
1516void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1517{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001518 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001519
1520 try
1521 {
1522 if (n < 0)
1523 {
1524 return error(GL_INVALID_VALUE);
1525 }
1526
1527 gl::Context *context = gl::getContext();
1528
1529 if (context)
1530 {
1531 for (int i = 0; i < n; i++)
1532 {
1533 if (textures[i] != 0)
1534 {
1535 context->deleteTexture(textures[i]);
1536 }
1537 }
1538 }
1539 }
1540 catch(std::bad_alloc&)
1541 {
1542 return error(GL_OUT_OF_MEMORY);
1543 }
1544}
1545
1546void __stdcall glDepthFunc(GLenum func)
1547{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001548 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001549
1550 try
1551 {
1552 switch (func)
1553 {
1554 case GL_NEVER:
1555 case GL_ALWAYS:
1556 case GL_LESS:
1557 case GL_LEQUAL:
1558 case GL_EQUAL:
1559 case GL_GREATER:
1560 case GL_GEQUAL:
1561 case GL_NOTEQUAL:
1562 break;
1563 default:
1564 return error(GL_INVALID_ENUM);
1565 }
1566
1567 gl::Context *context = gl::getContext();
1568
1569 if (context)
1570 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001571 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001572 }
1573 }
1574 catch(std::bad_alloc&)
1575 {
1576 return error(GL_OUT_OF_MEMORY);
1577 }
1578}
1579
1580void __stdcall glDepthMask(GLboolean flag)
1581{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001582 EVENT("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001583
1584 try
1585 {
1586 gl::Context *context = gl::getContext();
1587
1588 if (context)
1589 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001590 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001591 }
1592 }
1593 catch(std::bad_alloc&)
1594 {
1595 return error(GL_OUT_OF_MEMORY);
1596 }
1597}
1598
1599void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1600{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001601 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001602
1603 try
1604 {
1605 gl::Context *context = gl::getContext();
1606
1607 if (context)
1608 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001609 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001610 }
1611 }
1612 catch(std::bad_alloc&)
1613 {
1614 return error(GL_OUT_OF_MEMORY);
1615 }
1616}
1617
1618void __stdcall glDetachShader(GLuint program, GLuint shader)
1619{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001620 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001621
1622 try
1623 {
1624 gl::Context *context = gl::getContext();
1625
1626 if (context)
1627 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001628
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001629 gl::Program *programObject = context->getProgram(program);
1630 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001631
1632 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001633 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001634 gl::Shader *shaderByProgramHandle;
1635 shaderByProgramHandle = context->getShader(program);
1636 if (!shaderByProgramHandle)
1637 {
1638 return error(GL_INVALID_VALUE);
1639 }
1640 else
1641 {
1642 return error(GL_INVALID_OPERATION);
1643 }
1644 }
1645
1646 if (!shaderObject)
1647 {
1648 gl::Program *programByShaderHandle = context->getProgram(shader);
1649 if (!programByShaderHandle)
1650 {
1651 return error(GL_INVALID_VALUE);
1652 }
1653 else
1654 {
1655 return error(GL_INVALID_OPERATION);
1656 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001657 }
1658
1659 if (!programObject->detachShader(shaderObject))
1660 {
1661 return error(GL_INVALID_OPERATION);
1662 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001663 }
1664 }
1665 catch(std::bad_alloc&)
1666 {
1667 return error(GL_OUT_OF_MEMORY);
1668 }
1669}
1670
1671void __stdcall glDisable(GLenum cap)
1672{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001673 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001674
1675 try
1676 {
1677 gl::Context *context = gl::getContext();
1678
1679 if (context)
1680 {
1681 switch (cap)
1682 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001683 case GL_CULL_FACE: context->setCullFace(false); break;
1684 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1685 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1686 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1687 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1688 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1689 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1690 case GL_BLEND: context->setBlend(false); break;
1691 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001692 default:
1693 return error(GL_INVALID_ENUM);
1694 }
1695 }
1696 }
1697 catch(std::bad_alloc&)
1698 {
1699 return error(GL_OUT_OF_MEMORY);
1700 }
1701}
1702
1703void __stdcall glDisableVertexAttribArray(GLuint index)
1704{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001705 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001706
1707 try
1708 {
1709 if (index >= gl::MAX_VERTEX_ATTRIBS)
1710 {
1711 return error(GL_INVALID_VALUE);
1712 }
1713
1714 gl::Context *context = gl::getContext();
1715
1716 if (context)
1717 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001718 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001719 }
1720 }
1721 catch(std::bad_alloc&)
1722 {
1723 return error(GL_OUT_OF_MEMORY);
1724 }
1725}
1726
1727void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1728{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001729 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001730
1731 try
1732 {
1733 if (count < 0 || first < 0)
1734 {
1735 return error(GL_INVALID_VALUE);
1736 }
1737
1738 gl::Context *context = gl::getContext();
1739
1740 if (context)
1741 {
1742 context->drawArrays(mode, first, count);
1743 }
1744 }
1745 catch(std::bad_alloc&)
1746 {
1747 return error(GL_OUT_OF_MEMORY);
1748 }
1749}
1750
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001751void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001752{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001753 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 +00001754 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001755
1756 try
1757 {
1758 if (count < 0)
1759 {
1760 return error(GL_INVALID_VALUE);
1761 }
1762
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001763 gl::Context *context = gl::getContext();
1764
1765 if (context)
1766 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001767 switch (type)
1768 {
1769 case GL_UNSIGNED_BYTE:
1770 case GL_UNSIGNED_SHORT:
1771 break;
1772 case GL_UNSIGNED_INT:
1773 if (!context->supports32bitIndices())
1774 {
1775 return error(GL_INVALID_ENUM);
1776 }
1777 break;
1778 default:
1779 return error(GL_INVALID_ENUM);
1780 }
1781
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001782 context->drawElements(mode, count, type, indices);
1783 }
1784 }
1785 catch(std::bad_alloc&)
1786 {
1787 return error(GL_OUT_OF_MEMORY);
1788 }
1789}
1790
1791void __stdcall glEnable(GLenum cap)
1792{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001793 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001794
1795 try
1796 {
1797 gl::Context *context = gl::getContext();
1798
1799 if (context)
1800 {
1801 switch (cap)
1802 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001803 case GL_CULL_FACE: context->setCullFace(true); break;
1804 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1805 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1806 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1807 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1808 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1809 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1810 case GL_BLEND: context->setBlend(true); break;
1811 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001812 default:
1813 return error(GL_INVALID_ENUM);
1814 }
1815 }
1816 }
1817 catch(std::bad_alloc&)
1818 {
1819 return error(GL_OUT_OF_MEMORY);
1820 }
1821}
1822
1823void __stdcall glEnableVertexAttribArray(GLuint index)
1824{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001825 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001826
1827 try
1828 {
1829 if (index >= gl::MAX_VERTEX_ATTRIBS)
1830 {
1831 return error(GL_INVALID_VALUE);
1832 }
1833
1834 gl::Context *context = gl::getContext();
1835
1836 if (context)
1837 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001838 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001839 }
1840 }
1841 catch(std::bad_alloc&)
1842 {
1843 return error(GL_OUT_OF_MEMORY);
1844 }
1845}
1846
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001847void __stdcall glFinishFenceNV(GLuint fence)
1848{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001849 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001850
1851 try
1852 {
1853 gl::Context *context = gl::getContext();
1854
1855 if (context)
1856 {
1857 gl::Fence* fenceObject = context->getFence(fence);
1858
1859 if (fenceObject == NULL)
1860 {
1861 return error(GL_INVALID_OPERATION);
1862 }
1863
1864 fenceObject->finishFence();
1865 }
1866 }
1867 catch(std::bad_alloc&)
1868 {
1869 return error(GL_OUT_OF_MEMORY);
1870 }
1871}
1872
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001873void __stdcall glFinish(void)
1874{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001875 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001876
1877 try
1878 {
1879 gl::Context *context = gl::getContext();
1880
1881 if (context)
1882 {
1883 context->finish();
1884 }
1885 }
1886 catch(std::bad_alloc&)
1887 {
1888 return error(GL_OUT_OF_MEMORY);
1889 }
1890}
1891
1892void __stdcall glFlush(void)
1893{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001894 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001895
1896 try
1897 {
1898 gl::Context *context = gl::getContext();
1899
1900 if (context)
1901 {
1902 context->flush();
1903 }
1904 }
1905 catch(std::bad_alloc&)
1906 {
1907 return error(GL_OUT_OF_MEMORY);
1908 }
1909}
1910
1911void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1912{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001913 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001914 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001915
1916 try
1917 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001918 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1919 || renderbuffertarget != GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001920 {
1921 return error(GL_INVALID_ENUM);
1922 }
1923
1924 gl::Context *context = gl::getContext();
1925
1926 if (context)
1927 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001928 gl::Framebuffer *framebuffer = NULL;
1929 GLuint framebufferHandle = 0;
1930 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1931 {
1932 framebuffer = context->getReadFramebuffer();
1933 framebufferHandle = context->getReadFramebufferHandle();
1934 }
1935 else
1936 {
1937 framebuffer = context->getDrawFramebuffer();
1938 framebufferHandle = context->getDrawFramebufferHandle();
1939 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001940
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001941 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001942 {
1943 return error(GL_INVALID_OPERATION);
1944 }
1945
1946 switch (attachment)
1947 {
1948 case GL_COLOR_ATTACHMENT0:
1949 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1950 break;
1951 case GL_DEPTH_ATTACHMENT:
1952 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1953 break;
1954 case GL_STENCIL_ATTACHMENT:
1955 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1956 break;
1957 default:
1958 return error(GL_INVALID_ENUM);
1959 }
1960 }
1961 }
1962 catch(std::bad_alloc&)
1963 {
1964 return error(GL_OUT_OF_MEMORY);
1965 }
1966}
1967
1968void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1969{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001970 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001971 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001972
1973 try
1974 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001975 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001976 {
1977 return error(GL_INVALID_ENUM);
1978 }
1979
1980 switch (attachment)
1981 {
1982 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001983 case GL_DEPTH_ATTACHMENT:
1984 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001985 break;
1986 default:
1987 return error(GL_INVALID_ENUM);
1988 }
1989
1990 gl::Context *context = gl::getContext();
1991
1992 if (context)
1993 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001994 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001995 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001996 textarget = GL_NONE;
1997 }
1998 else
1999 {
2000 gl::Texture *tex = context->getTexture(texture);
2001
2002 if (tex == NULL)
2003 {
2004 return error(GL_INVALID_OPERATION);
2005 }
2006
daniel@transgaming.com01868132010-08-24 19:21:17 +00002007 if (tex->isCompressed())
2008 {
2009 return error(GL_INVALID_OPERATION);
2010 }
2011
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002012 switch (textarget)
2013 {
2014 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002015 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002016 {
2017 return error(GL_INVALID_OPERATION);
2018 }
2019 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002020
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002021 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002022 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002023 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002024 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002025 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002026 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002027 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2028 {
2029 return error(GL_INVALID_OPERATION);
2030 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002031 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002032
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002033 default:
2034 return error(GL_INVALID_ENUM);
2035 }
2036
2037 if (level != 0)
2038 {
2039 return error(GL_INVALID_VALUE);
2040 }
2041 }
2042
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002043 gl::Framebuffer *framebuffer = NULL;
2044 GLuint framebufferHandle = 0;
2045 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2046 {
2047 framebuffer = context->getReadFramebuffer();
2048 framebufferHandle = context->getReadFramebufferHandle();
2049 }
2050 else
2051 {
2052 framebuffer = context->getDrawFramebuffer();
2053 framebufferHandle = context->getDrawFramebufferHandle();
2054 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002055
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002056 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002057 {
2058 return error(GL_INVALID_OPERATION);
2059 }
2060
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002061 switch (attachment)
2062 {
2063 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2064 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2065 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2066 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002067 }
2068 }
2069 catch(std::bad_alloc&)
2070 {
2071 return error(GL_OUT_OF_MEMORY);
2072 }
2073}
2074
2075void __stdcall glFrontFace(GLenum mode)
2076{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002077 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002078
2079 try
2080 {
2081 switch (mode)
2082 {
2083 case GL_CW:
2084 case GL_CCW:
2085 {
2086 gl::Context *context = gl::getContext();
2087
2088 if (context)
2089 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002090 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002091 }
2092 }
2093 break;
2094 default:
2095 return error(GL_INVALID_ENUM);
2096 }
2097 }
2098 catch(std::bad_alloc&)
2099 {
2100 return error(GL_OUT_OF_MEMORY);
2101 }
2102}
2103
2104void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2105{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002106 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002107
2108 try
2109 {
2110 if (n < 0)
2111 {
2112 return error(GL_INVALID_VALUE);
2113 }
2114
2115 gl::Context *context = gl::getContext();
2116
2117 if (context)
2118 {
2119 for (int i = 0; i < n; i++)
2120 {
2121 buffers[i] = context->createBuffer();
2122 }
2123 }
2124 }
2125 catch(std::bad_alloc&)
2126 {
2127 return error(GL_OUT_OF_MEMORY);
2128 }
2129}
2130
2131void __stdcall glGenerateMipmap(GLenum target)
2132{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002133 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002134
2135 try
2136 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002137 gl::Context *context = gl::getContext();
2138
2139 if (context)
2140 {
2141 gl::Texture *texture;
2142
2143 switch (target)
2144 {
2145 case GL_TEXTURE_2D:
2146 texture = context->getTexture2D();
2147 break;
2148
2149 case GL_TEXTURE_CUBE_MAP:
2150 texture = context->getTextureCubeMap();
2151 break;
2152
2153 default:
2154 return error(GL_INVALID_ENUM);
2155 }
2156
daniel@transgaming.com01868132010-08-24 19:21:17 +00002157 if (texture->isCompressed())
2158 {
2159 return error(GL_INVALID_OPERATION);
2160 }
2161
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002162 texture->generateMipmaps();
2163 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002164 }
2165 catch(std::bad_alloc&)
2166 {
2167 return error(GL_OUT_OF_MEMORY);
2168 }
2169}
2170
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002171void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2172{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002173 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002174
2175 try
2176 {
2177 if (n < 0)
2178 {
2179 return error(GL_INVALID_VALUE);
2180 }
2181
2182 gl::Context *context = gl::getContext();
2183
2184 if (context)
2185 {
2186 for (int i = 0; i < n; i++)
2187 {
2188 fences[i] = context->createFence();
2189 }
2190 }
2191 }
2192 catch(std::bad_alloc&)
2193 {
2194 return error(GL_OUT_OF_MEMORY);
2195 }
2196}
2197
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002198void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2199{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002200 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002201
2202 try
2203 {
2204 if (n < 0)
2205 {
2206 return error(GL_INVALID_VALUE);
2207 }
2208
2209 gl::Context *context = gl::getContext();
2210
2211 if (context)
2212 {
2213 for (int i = 0; i < n; i++)
2214 {
2215 framebuffers[i] = context->createFramebuffer();
2216 }
2217 }
2218 }
2219 catch(std::bad_alloc&)
2220 {
2221 return error(GL_OUT_OF_MEMORY);
2222 }
2223}
2224
2225void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2226{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002227 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002228
2229 try
2230 {
2231 if (n < 0)
2232 {
2233 return error(GL_INVALID_VALUE);
2234 }
2235
2236 gl::Context *context = gl::getContext();
2237
2238 if (context)
2239 {
2240 for (int i = 0; i < n; i++)
2241 {
2242 renderbuffers[i] = context->createRenderbuffer();
2243 }
2244 }
2245 }
2246 catch(std::bad_alloc&)
2247 {
2248 return error(GL_OUT_OF_MEMORY);
2249 }
2250}
2251
2252void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2253{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002254 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002255
2256 try
2257 {
2258 if (n < 0)
2259 {
2260 return error(GL_INVALID_VALUE);
2261 }
2262
2263 gl::Context *context = gl::getContext();
2264
2265 if (context)
2266 {
2267 for (int i = 0; i < n; i++)
2268 {
2269 textures[i] = context->createTexture();
2270 }
2271 }
2272 }
2273 catch(std::bad_alloc&)
2274 {
2275 return error(GL_OUT_OF_MEMORY);
2276 }
2277}
2278
daniel@transgaming.com85423182010-04-22 13:35:27 +00002279void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002280{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002281 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002282 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002283 program, index, bufsize, length, size, type, name);
2284
2285 try
2286 {
2287 if (bufsize < 0)
2288 {
2289 return error(GL_INVALID_VALUE);
2290 }
2291
daniel@transgaming.com85423182010-04-22 13:35:27 +00002292 gl::Context *context = gl::getContext();
2293
2294 if (context)
2295 {
2296 gl::Program *programObject = context->getProgram(program);
2297
2298 if (!programObject)
2299 {
2300 if (context->getShader(program))
2301 {
2302 return error(GL_INVALID_OPERATION);
2303 }
2304 else
2305 {
2306 return error(GL_INVALID_VALUE);
2307 }
2308 }
2309
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002310 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002311 {
2312 return error(GL_INVALID_VALUE);
2313 }
2314
2315 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2316 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002317 }
2318 catch(std::bad_alloc&)
2319 {
2320 return error(GL_OUT_OF_MEMORY);
2321 }
2322}
2323
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002324void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002325{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002326 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002327 "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 +00002328 program, index, bufsize, length, size, type, name);
2329
2330 try
2331 {
2332 if (bufsize < 0)
2333 {
2334 return error(GL_INVALID_VALUE);
2335 }
2336
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002337 gl::Context *context = gl::getContext();
2338
2339 if (context)
2340 {
2341 gl::Program *programObject = context->getProgram(program);
2342
2343 if (!programObject)
2344 {
2345 if (context->getShader(program))
2346 {
2347 return error(GL_INVALID_OPERATION);
2348 }
2349 else
2350 {
2351 return error(GL_INVALID_VALUE);
2352 }
2353 }
2354
2355 if (index >= (GLuint)programObject->getActiveUniformCount())
2356 {
2357 return error(GL_INVALID_VALUE);
2358 }
2359
2360 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2361 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002362 }
2363 catch(std::bad_alloc&)
2364 {
2365 return error(GL_OUT_OF_MEMORY);
2366 }
2367}
2368
2369void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2370{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002371 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 +00002372 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002373
2374 try
2375 {
2376 if (maxcount < 0)
2377 {
2378 return error(GL_INVALID_VALUE);
2379 }
2380
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002381 gl::Context *context = gl::getContext();
2382
2383 if (context)
2384 {
2385 gl::Program *programObject = context->getProgram(program);
2386
2387 if (!programObject)
2388 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002389 if (context->getShader(program))
2390 {
2391 return error(GL_INVALID_OPERATION);
2392 }
2393 else
2394 {
2395 return error(GL_INVALID_VALUE);
2396 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002397 }
2398
2399 return programObject->getAttachedShaders(maxcount, count, shaders);
2400 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002401 }
2402 catch(std::bad_alloc&)
2403 {
2404 return error(GL_OUT_OF_MEMORY);
2405 }
2406}
2407
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002408int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002409{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002410 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002411
2412 try
2413 {
2414 gl::Context *context = gl::getContext();
2415
2416 if (context)
2417 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002418
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002419 gl::Program *programObject = context->getProgram(program);
2420
2421 if (!programObject)
2422 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002423 if (context->getShader(program))
2424 {
2425 return error(GL_INVALID_OPERATION, -1);
2426 }
2427 else
2428 {
2429 return error(GL_INVALID_VALUE, -1);
2430 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002431 }
2432
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002433 if (!programObject->isLinked())
2434 {
2435 return error(GL_INVALID_OPERATION, -1);
2436 }
2437
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002438 return programObject->getAttributeLocation(name);
2439 }
2440 }
2441 catch(std::bad_alloc&)
2442 {
2443 return error(GL_OUT_OF_MEMORY, -1);
2444 }
2445
2446 return -1;
2447}
2448
2449void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2450{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002451 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002452
2453 try
2454 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002455 gl::Context *context = gl::getContext();
2456
2457 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002458 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002459 if (!(context->getBooleanv(pname, params)))
2460 {
2461 GLenum nativeType;
2462 unsigned int numParams = 0;
2463 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2464 return error(GL_INVALID_ENUM);
2465
2466 if (numParams == 0)
2467 return; // it is known that the pname is valid, but there are no parameters to return
2468
2469 if (nativeType == GL_FLOAT)
2470 {
2471 GLfloat *floatParams = NULL;
2472 floatParams = new GLfloat[numParams];
2473
2474 context->getFloatv(pname, floatParams);
2475
2476 for (unsigned int i = 0; i < numParams; ++i)
2477 {
2478 if (floatParams[i] == 0.0f)
2479 params[i] = GL_FALSE;
2480 else
2481 params[i] = GL_TRUE;
2482 }
2483
2484 delete [] floatParams;
2485 }
2486 else if (nativeType == GL_INT)
2487 {
2488 GLint *intParams = NULL;
2489 intParams = new GLint[numParams];
2490
2491 context->getIntegerv(pname, intParams);
2492
2493 for (unsigned int i = 0; i < numParams; ++i)
2494 {
2495 if (intParams[i] == 0)
2496 params[i] = GL_FALSE;
2497 else
2498 params[i] = GL_TRUE;
2499 }
2500
2501 delete [] intParams;
2502 }
2503 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002504 }
2505 }
2506 catch(std::bad_alloc&)
2507 {
2508 return error(GL_OUT_OF_MEMORY);
2509 }
2510}
2511
2512void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2513{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002514 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 +00002515
2516 try
2517 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002518 gl::Context *context = gl::getContext();
2519
2520 if (context)
2521 {
2522 gl::Buffer *buffer;
2523
2524 switch (target)
2525 {
2526 case GL_ARRAY_BUFFER:
2527 buffer = context->getArrayBuffer();
2528 break;
2529 case GL_ELEMENT_ARRAY_BUFFER:
2530 buffer = context->getElementArrayBuffer();
2531 break;
2532 default: return error(GL_INVALID_ENUM);
2533 }
2534
2535 if (!buffer)
2536 {
2537 // A null buffer means that "0" is bound to the requested buffer target
2538 return error(GL_INVALID_OPERATION);
2539 }
2540
2541 switch (pname)
2542 {
2543 case GL_BUFFER_USAGE:
2544 *params = buffer->usage();
2545 break;
2546 case GL_BUFFER_SIZE:
2547 *params = buffer->size();
2548 break;
2549 default: return error(GL_INVALID_ENUM);
2550 }
2551 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002552 }
2553 catch(std::bad_alloc&)
2554 {
2555 return error(GL_OUT_OF_MEMORY);
2556 }
2557}
2558
2559GLenum __stdcall glGetError(void)
2560{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002561 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002562
2563 gl::Context *context = gl::getContext();
2564
2565 if (context)
2566 {
2567 return context->getError();
2568 }
2569
2570 return GL_NO_ERROR;
2571}
2572
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002573void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2574{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002575 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002576
2577 try
2578 {
2579
2580 gl::Context *context = gl::getContext();
2581
2582 if (context)
2583 {
2584 gl::Fence *fenceObject = context->getFence(fence);
2585
2586 if (fenceObject == NULL)
2587 {
2588 return error(GL_INVALID_OPERATION);
2589 }
2590
2591 fenceObject->getFenceiv(pname, params);
2592 }
2593 }
2594 catch(std::bad_alloc&)
2595 {
2596 return error(GL_OUT_OF_MEMORY);
2597 }
2598}
2599
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002600void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2601{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002602 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002603
2604 try
2605 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002606 gl::Context *context = gl::getContext();
2607
2608 if (context)
2609 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002610 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002611 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002612 GLenum nativeType;
2613 unsigned int numParams = 0;
2614 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2615 return error(GL_INVALID_ENUM);
2616
2617 if (numParams == 0)
2618 return; // it is known that the pname is valid, but that there are no parameters to return.
2619
2620 if (nativeType == GL_BOOL)
2621 {
2622 GLboolean *boolParams = NULL;
2623 boolParams = new GLboolean[numParams];
2624
2625 context->getBooleanv(pname, boolParams);
2626
2627 for (unsigned int i = 0; i < numParams; ++i)
2628 {
2629 if (boolParams[i] == GL_FALSE)
2630 params[i] = 0.0f;
2631 else
2632 params[i] = 1.0f;
2633 }
2634
2635 delete [] boolParams;
2636 }
2637 else if (nativeType == GL_INT)
2638 {
2639 GLint *intParams = NULL;
2640 intParams = new GLint[numParams];
2641
2642 context->getIntegerv(pname, intParams);
2643
2644 for (unsigned int i = 0; i < numParams; ++i)
2645 {
2646 params[i] = (GLfloat)intParams[i];
2647 }
2648
2649 delete [] intParams;
2650 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002651 }
2652 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002653 }
2654 catch(std::bad_alloc&)
2655 {
2656 return error(GL_OUT_OF_MEMORY);
2657 }
2658}
2659
2660void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2661{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002662 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 +00002663 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002664
2665 try
2666 {
2667 gl::Context *context = gl::getContext();
2668
2669 if (context)
2670 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002671 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002672 {
2673 return error(GL_INVALID_ENUM);
2674 }
2675
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002676 gl::Framebuffer *framebuffer = NULL;
2677 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2678 {
2679 if(context->getReadFramebufferHandle() == 0)
2680 {
2681 return error(GL_INVALID_OPERATION);
2682 }
2683
2684 framebuffer = context->getReadFramebuffer();
2685 }
2686 else
2687 {
2688 if (context->getDrawFramebufferHandle() == 0)
2689 {
2690 return error(GL_INVALID_OPERATION);
2691 }
2692
2693 framebuffer = context->getDrawFramebuffer();
2694 }
2695
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002696 GLenum attachmentType;
2697 GLuint attachmentHandle;
2698 switch (attachment)
2699 {
2700 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002701 attachmentType = framebuffer->getColorbufferType();
2702 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002703 break;
2704 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002705 attachmentType = framebuffer->getDepthbufferType();
2706 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002707 break;
2708 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002709 attachmentType = framebuffer->getStencilbufferType();
2710 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002711 break;
2712 default: return error(GL_INVALID_ENUM);
2713 }
2714
2715 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002716 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002717 {
2718 attachmentObjectType = attachmentType;
2719 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002720 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002721 {
2722 attachmentObjectType = GL_TEXTURE;
2723 }
2724 else UNREACHABLE();
2725
2726 switch (pname)
2727 {
2728 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2729 *params = attachmentObjectType;
2730 break;
2731 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2732 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2733 {
2734 *params = attachmentHandle;
2735 }
2736 else
2737 {
2738 return error(GL_INVALID_ENUM);
2739 }
2740 break;
2741 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2742 if (attachmentObjectType == GL_TEXTURE)
2743 {
2744 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2745 }
2746 else
2747 {
2748 return error(GL_INVALID_ENUM);
2749 }
2750 break;
2751 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2752 if (attachmentObjectType == GL_TEXTURE)
2753 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002754 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002755 {
2756 *params = attachmentType;
2757 }
2758 else
2759 {
2760 *params = 0;
2761 }
2762 }
2763 else
2764 {
2765 return error(GL_INVALID_ENUM);
2766 }
2767 break;
2768 default:
2769 return error(GL_INVALID_ENUM);
2770 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002771 }
2772 }
2773 catch(std::bad_alloc&)
2774 {
2775 return error(GL_OUT_OF_MEMORY);
2776 }
2777}
2778
2779void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2780{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002781 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002782
2783 try
2784 {
2785 gl::Context *context = gl::getContext();
2786
2787 if (context)
2788 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002789 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002790 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002791 GLenum nativeType;
2792 unsigned int numParams = 0;
2793 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2794 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002795
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002796 if (numParams == 0)
2797 return; // it is known that pname is valid, but there are no parameters to return
2798
2799 if (nativeType == GL_BOOL)
2800 {
2801 GLboolean *boolParams = NULL;
2802 boolParams = new GLboolean[numParams];
2803
2804 context->getBooleanv(pname, boolParams);
2805
2806 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002807 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002808 if (boolParams[i] == GL_FALSE)
2809 params[i] = 0;
2810 else
2811 params[i] = 1;
2812 }
2813
2814 delete [] boolParams;
2815 }
2816 else if (nativeType == GL_FLOAT)
2817 {
2818 GLfloat *floatParams = NULL;
2819 floatParams = new GLfloat[numParams];
2820
2821 context->getFloatv(pname, floatParams);
2822
2823 for (unsigned int i = 0; i < numParams; ++i)
2824 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002825 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 +00002826 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002827 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002828 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002829 else
2830 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 +00002831 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002832
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002833 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002834 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002835 }
2836 }
2837 }
2838 catch(std::bad_alloc&)
2839 {
2840 return error(GL_OUT_OF_MEMORY);
2841 }
2842}
2843
2844void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2845{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002846 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002847
2848 try
2849 {
2850 gl::Context *context = gl::getContext();
2851
2852 if (context)
2853 {
2854 gl::Program *programObject = context->getProgram(program);
2855
2856 if (!programObject)
2857 {
2858 return error(GL_INVALID_VALUE);
2859 }
2860
2861 switch (pname)
2862 {
2863 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002864 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002865 return;
2866 case GL_LINK_STATUS:
2867 *params = programObject->isLinked();
2868 return;
2869 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002870 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002871 return;
2872 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002873 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002874 return;
2875 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002876 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002877 return;
2878 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002879 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002880 return;
2881 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002882 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002883 return;
2884 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002885 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002886 return;
2887 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002888 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002889 return;
2890 default:
2891 return error(GL_INVALID_ENUM);
2892 }
2893 }
2894 }
2895 catch(std::bad_alloc&)
2896 {
2897 return error(GL_OUT_OF_MEMORY);
2898 }
2899}
2900
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002901void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002902{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002903 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 +00002904 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002905
2906 try
2907 {
2908 if (bufsize < 0)
2909 {
2910 return error(GL_INVALID_VALUE);
2911 }
2912
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002913 gl::Context *context = gl::getContext();
2914
2915 if (context)
2916 {
2917 gl::Program *programObject = context->getProgram(program);
2918
2919 if (!programObject)
2920 {
2921 return error(GL_INVALID_VALUE);
2922 }
2923
2924 programObject->getInfoLog(bufsize, length, infolog);
2925 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002926 }
2927 catch(std::bad_alloc&)
2928 {
2929 return error(GL_OUT_OF_MEMORY);
2930 }
2931}
2932
2933void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2934{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002935 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 +00002936
2937 try
2938 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002939 gl::Context *context = gl::getContext();
2940
2941 if (context)
2942 {
2943 if (target != GL_RENDERBUFFER)
2944 {
2945 return error(GL_INVALID_ENUM);
2946 }
2947
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002948 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002949 {
2950 return error(GL_INVALID_OPERATION);
2951 }
2952
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002953 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002954
2955 switch (pname)
2956 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00002957 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
2958 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
2959 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
2960 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
2961 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
2962 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
2963 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
2964 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
2965 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00002966 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00002967 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00002968 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00002969 *params = renderbuffer->getSamples();
2970 }
2971 else
2972 {
2973 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00002974 }
2975 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002976 default:
2977 return error(GL_INVALID_ENUM);
2978 }
2979 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002980 }
2981 catch(std::bad_alloc&)
2982 {
2983 return error(GL_OUT_OF_MEMORY);
2984 }
2985}
2986
2987void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2988{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002989 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002990
2991 try
2992 {
2993 gl::Context *context = gl::getContext();
2994
2995 if (context)
2996 {
2997 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002998
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002999 if (!shaderObject)
3000 {
3001 return error(GL_INVALID_VALUE);
3002 }
3003
3004 switch (pname)
3005 {
3006 case GL_SHADER_TYPE:
3007 *params = shaderObject->getType();
3008 return;
3009 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003010 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003011 return;
3012 case GL_COMPILE_STATUS:
3013 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3014 return;
3015 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003016 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003017 return;
3018 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003019 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003020 return;
3021 default:
3022 return error(GL_INVALID_ENUM);
3023 }
3024 }
3025 }
3026 catch(std::bad_alloc&)
3027 {
3028 return error(GL_OUT_OF_MEMORY);
3029 }
3030}
3031
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003032void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003033{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003034 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 +00003035 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003036
3037 try
3038 {
3039 if (bufsize < 0)
3040 {
3041 return error(GL_INVALID_VALUE);
3042 }
3043
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003044 gl::Context *context = gl::getContext();
3045
3046 if (context)
3047 {
3048 gl::Shader *shaderObject = context->getShader(shader);
3049
3050 if (!shaderObject)
3051 {
3052 return error(GL_INVALID_VALUE);
3053 }
3054
3055 shaderObject->getInfoLog(bufsize, length, infolog);
3056 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003057 }
3058 catch(std::bad_alloc&)
3059 {
3060 return error(GL_OUT_OF_MEMORY);
3061 }
3062}
3063
3064void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3065{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003066 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 +00003067 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003068
3069 try
3070 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003071 switch (shadertype)
3072 {
3073 case GL_VERTEX_SHADER:
3074 case GL_FRAGMENT_SHADER:
3075 break;
3076 default:
3077 return error(GL_INVALID_ENUM);
3078 }
3079
3080 switch (precisiontype)
3081 {
3082 case GL_LOW_FLOAT:
3083 case GL_MEDIUM_FLOAT:
3084 case GL_HIGH_FLOAT:
3085 // Assume IEEE 754 precision
3086 range[0] = 127;
3087 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003088 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003089 break;
3090 case GL_LOW_INT:
3091 case GL_MEDIUM_INT:
3092 case GL_HIGH_INT:
3093 // Some (most) hardware only supports single-precision floating-point numbers,
3094 // which can accurately represent integers up to +/-16777216
3095 range[0] = 24;
3096 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003097 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003098 break;
3099 default:
3100 return error(GL_INVALID_ENUM);
3101 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003102 }
3103 catch(std::bad_alloc&)
3104 {
3105 return error(GL_OUT_OF_MEMORY);
3106 }
3107}
3108
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003109void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003110{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003111 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 +00003112 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003113
3114 try
3115 {
3116 if (bufsize < 0)
3117 {
3118 return error(GL_INVALID_VALUE);
3119 }
3120
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003121 gl::Context *context = gl::getContext();
3122
3123 if (context)
3124 {
3125 gl::Shader *shaderObject = context->getShader(shader);
3126
3127 if (!shaderObject)
3128 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003129 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003130 }
3131
3132 shaderObject->getSource(bufsize, length, source);
3133 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003134 }
3135 catch(std::bad_alloc&)
3136 {
3137 return error(GL_OUT_OF_MEMORY);
3138 }
3139}
3140
3141const GLubyte* __stdcall glGetString(GLenum name)
3142{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003143 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003144
3145 try
3146 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003147 gl::Context *context = gl::getContext();
3148
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003149 switch (name)
3150 {
3151 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003152 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003153 case GL_RENDERER:
3154 return (GLubyte*)"ANGLE";
3155 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003156 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003157 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003158 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003159 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003160 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003161 default:
3162 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3163 }
3164 }
3165 catch(std::bad_alloc&)
3166 {
3167 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3168 }
3169
3170 return NULL;
3171}
3172
3173void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3174{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003175 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 +00003176
3177 try
3178 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003179 gl::Context *context = gl::getContext();
3180
3181 if (context)
3182 {
3183 gl::Texture *texture;
3184
3185 switch (target)
3186 {
3187 case GL_TEXTURE_2D:
3188 texture = context->getTexture2D();
3189 break;
3190 case GL_TEXTURE_CUBE_MAP:
3191 texture = context->getTextureCubeMap();
3192 break;
3193 default:
3194 return error(GL_INVALID_ENUM);
3195 }
3196
3197 switch (pname)
3198 {
3199 case GL_TEXTURE_MAG_FILTER:
3200 *params = (GLfloat)texture->getMagFilter();
3201 break;
3202 case GL_TEXTURE_MIN_FILTER:
3203 *params = (GLfloat)texture->getMinFilter();
3204 break;
3205 case GL_TEXTURE_WRAP_S:
3206 *params = (GLfloat)texture->getWrapS();
3207 break;
3208 case GL_TEXTURE_WRAP_T:
3209 *params = (GLfloat)texture->getWrapT();
3210 break;
3211 default:
3212 return error(GL_INVALID_ENUM);
3213 }
3214 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003215 }
3216 catch(std::bad_alloc&)
3217 {
3218 return error(GL_OUT_OF_MEMORY);
3219 }
3220}
3221
3222void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3223{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003224 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 +00003225
3226 try
3227 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003228 gl::Context *context = gl::getContext();
3229
3230 if (context)
3231 {
3232 gl::Texture *texture;
3233
3234 switch (target)
3235 {
3236 case GL_TEXTURE_2D:
3237 texture = context->getTexture2D();
3238 break;
3239 case GL_TEXTURE_CUBE_MAP:
3240 texture = context->getTextureCubeMap();
3241 break;
3242 default:
3243 return error(GL_INVALID_ENUM);
3244 }
3245
3246 switch (pname)
3247 {
3248 case GL_TEXTURE_MAG_FILTER:
3249 *params = texture->getMagFilter();
3250 break;
3251 case GL_TEXTURE_MIN_FILTER:
3252 *params = texture->getMinFilter();
3253 break;
3254 case GL_TEXTURE_WRAP_S:
3255 *params = texture->getWrapS();
3256 break;
3257 case GL_TEXTURE_WRAP_T:
3258 *params = texture->getWrapT();
3259 break;
3260 default:
3261 return error(GL_INVALID_ENUM);
3262 }
3263 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003264 }
3265 catch(std::bad_alloc&)
3266 {
3267 return error(GL_OUT_OF_MEMORY);
3268 }
3269}
3270
3271void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3272{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003273 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003274
3275 try
3276 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003277 gl::Context *context = gl::getContext();
3278
3279 if (context)
3280 {
3281 if (program == 0)
3282 {
3283 return error(GL_INVALID_VALUE);
3284 }
3285
3286 gl::Program *programObject = context->getProgram(program);
3287
3288 if (!programObject || !programObject->isLinked())
3289 {
3290 return error(GL_INVALID_OPERATION);
3291 }
3292
3293 if (!programObject->getUniformfv(location, params))
3294 {
3295 return error(GL_INVALID_OPERATION);
3296 }
3297 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003298 }
3299 catch(std::bad_alloc&)
3300 {
3301 return error(GL_OUT_OF_MEMORY);
3302 }
3303}
3304
3305void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3306{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003307 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003308
3309 try
3310 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003311 gl::Context *context = gl::getContext();
3312
3313 if (context)
3314 {
3315 if (program == 0)
3316 {
3317 return error(GL_INVALID_VALUE);
3318 }
3319
3320 gl::Program *programObject = context->getProgram(program);
3321
3322 if (!programObject || !programObject->isLinked())
3323 {
3324 return error(GL_INVALID_OPERATION);
3325 }
3326
3327 if (!programObject)
3328 {
3329 return error(GL_INVALID_OPERATION);
3330 }
3331
3332 if (!programObject->getUniformiv(location, params))
3333 {
3334 return error(GL_INVALID_OPERATION);
3335 }
3336 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003337 }
3338 catch(std::bad_alloc&)
3339 {
3340 return error(GL_OUT_OF_MEMORY);
3341 }
3342}
3343
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003344int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003345{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003346 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003347
3348 try
3349 {
3350 gl::Context *context = gl::getContext();
3351
3352 if (strstr(name, "gl_") == name)
3353 {
3354 return -1;
3355 }
3356
3357 if (context)
3358 {
3359 gl::Program *programObject = context->getProgram(program);
3360
3361 if (!programObject)
3362 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003363 if (context->getShader(program))
3364 {
3365 return error(GL_INVALID_OPERATION, -1);
3366 }
3367 else
3368 {
3369 return error(GL_INVALID_VALUE, -1);
3370 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003371 }
3372
3373 if (!programObject->isLinked())
3374 {
3375 return error(GL_INVALID_OPERATION, -1);
3376 }
3377
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00003378 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003379 }
3380 }
3381 catch(std::bad_alloc&)
3382 {
3383 return error(GL_OUT_OF_MEMORY, -1);
3384 }
3385
3386 return -1;
3387}
3388
3389void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3390{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003391 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003392
3393 try
3394 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003395 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003396
daniel@transgaming.come0078962010-04-15 20:45:08 +00003397 if (context)
3398 {
3399 if (index >= gl::MAX_VERTEX_ATTRIBS)
3400 {
3401 return error(GL_INVALID_VALUE);
3402 }
3403
daniel@transgaming.com83921382011-01-08 05:46:00 +00003404 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003405
daniel@transgaming.come0078962010-04-15 20:45:08 +00003406 switch (pname)
3407 {
3408 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003409 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003410 break;
3411 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003412 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003413 break;
3414 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003415 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003416 break;
3417 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003418 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003419 break;
3420 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003421 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003422 break;
3423 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003424 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003425 break;
3426 case GL_CURRENT_VERTEX_ATTRIB:
3427 for (int i = 0; i < 4; ++i)
3428 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003429 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003430 }
3431 break;
3432 default: return error(GL_INVALID_ENUM);
3433 }
3434 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003435 }
3436 catch(std::bad_alloc&)
3437 {
3438 return error(GL_OUT_OF_MEMORY);
3439 }
3440}
3441
3442void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3443{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003444 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003445
3446 try
3447 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003448 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003449
daniel@transgaming.come0078962010-04-15 20:45:08 +00003450 if (context)
3451 {
3452 if (index >= gl::MAX_VERTEX_ATTRIBS)
3453 {
3454 return error(GL_INVALID_VALUE);
3455 }
3456
daniel@transgaming.com83921382011-01-08 05:46:00 +00003457 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003458
daniel@transgaming.come0078962010-04-15 20:45:08 +00003459 switch (pname)
3460 {
3461 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003462 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003463 break;
3464 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003465 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003466 break;
3467 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003468 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003469 break;
3470 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003471 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003472 break;
3473 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003474 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003475 break;
3476 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003477 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003478 break;
3479 case GL_CURRENT_VERTEX_ATTRIB:
3480 for (int i = 0; i < 4; ++i)
3481 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003482 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003483 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3484 }
3485 break;
3486 default: return error(GL_INVALID_ENUM);
3487 }
3488 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003489 }
3490 catch(std::bad_alloc&)
3491 {
3492 return error(GL_OUT_OF_MEMORY);
3493 }
3494}
3495
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003496void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003497{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003498 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003499
3500 try
3501 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003502 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003503
daniel@transgaming.come0078962010-04-15 20:45:08 +00003504 if (context)
3505 {
3506 if (index >= gl::MAX_VERTEX_ATTRIBS)
3507 {
3508 return error(GL_INVALID_VALUE);
3509 }
3510
3511 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3512 {
3513 return error(GL_INVALID_ENUM);
3514 }
3515
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003516 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003517 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003518 }
3519 catch(std::bad_alloc&)
3520 {
3521 return error(GL_OUT_OF_MEMORY);
3522 }
3523}
3524
3525void __stdcall glHint(GLenum target, GLenum mode)
3526{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003527 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003528
3529 try
3530 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003531 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003532 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003533 case GL_FASTEST:
3534 case GL_NICEST:
3535 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003536 break;
3537 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003538 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003539 }
3540
3541 gl::Context *context = gl::getContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003542 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003543 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003544 case GL_GENERATE_MIPMAP_HINT:
3545 if (context) context->setGenerateMipmapHint(mode);
3546 break;
3547 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3548 if (context) context->setFragmentShaderDerivativeHint(mode);
3549 break;
3550 default:
3551 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003552 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003553 }
3554 catch(std::bad_alloc&)
3555 {
3556 return error(GL_OUT_OF_MEMORY);
3557 }
3558}
3559
3560GLboolean __stdcall glIsBuffer(GLuint buffer)
3561{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003562 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003563
3564 try
3565 {
3566 gl::Context *context = gl::getContext();
3567
3568 if (context && buffer)
3569 {
3570 gl::Buffer *bufferObject = context->getBuffer(buffer);
3571
3572 if (bufferObject)
3573 {
3574 return GL_TRUE;
3575 }
3576 }
3577 }
3578 catch(std::bad_alloc&)
3579 {
3580 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3581 }
3582
3583 return GL_FALSE;
3584}
3585
3586GLboolean __stdcall glIsEnabled(GLenum cap)
3587{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003588 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003589
3590 try
3591 {
3592 gl::Context *context = gl::getContext();
3593
3594 if (context)
3595 {
3596 switch (cap)
3597 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003598 case GL_CULL_FACE: return context->isCullFaceEnabled();
3599 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3600 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3601 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3602 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3603 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3604 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3605 case GL_BLEND: return context->isBlendEnabled();
3606 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003607 default:
3608 return error(GL_INVALID_ENUM, false);
3609 }
3610 }
3611 }
3612 catch(std::bad_alloc&)
3613 {
3614 return error(GL_OUT_OF_MEMORY, false);
3615 }
3616
3617 return false;
3618}
3619
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003620GLboolean __stdcall glIsFenceNV(GLuint fence)
3621{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003622 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003623
3624 try
3625 {
3626 gl::Context *context = gl::getContext();
3627
3628 if (context)
3629 {
3630 gl::Fence *fenceObject = context->getFence(fence);
3631
3632 if (fenceObject == NULL)
3633 {
3634 return GL_FALSE;
3635 }
3636
3637 return fenceObject->isFence();
3638 }
3639 }
3640 catch(std::bad_alloc&)
3641 {
3642 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3643 }
3644
3645 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003646}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003647
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003648GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3649{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003650 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003651
3652 try
3653 {
3654 gl::Context *context = gl::getContext();
3655
3656 if (context && framebuffer)
3657 {
3658 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3659
3660 if (framebufferObject)
3661 {
3662 return GL_TRUE;
3663 }
3664 }
3665 }
3666 catch(std::bad_alloc&)
3667 {
3668 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3669 }
3670
3671 return GL_FALSE;
3672}
3673
3674GLboolean __stdcall glIsProgram(GLuint program)
3675{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003676 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003677
3678 try
3679 {
3680 gl::Context *context = gl::getContext();
3681
3682 if (context && program)
3683 {
3684 gl::Program *programObject = context->getProgram(program);
3685
3686 if (programObject)
3687 {
3688 return GL_TRUE;
3689 }
3690 }
3691 }
3692 catch(std::bad_alloc&)
3693 {
3694 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3695 }
3696
3697 return GL_FALSE;
3698}
3699
3700GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3701{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003702 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003703
3704 try
3705 {
3706 gl::Context *context = gl::getContext();
3707
3708 if (context && renderbuffer)
3709 {
3710 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3711
3712 if (renderbufferObject)
3713 {
3714 return GL_TRUE;
3715 }
3716 }
3717 }
3718 catch(std::bad_alloc&)
3719 {
3720 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3721 }
3722
3723 return GL_FALSE;
3724}
3725
3726GLboolean __stdcall glIsShader(GLuint shader)
3727{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003728 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003729
3730 try
3731 {
3732 gl::Context *context = gl::getContext();
3733
3734 if (context && shader)
3735 {
3736 gl::Shader *shaderObject = context->getShader(shader);
3737
3738 if (shaderObject)
3739 {
3740 return GL_TRUE;
3741 }
3742 }
3743 }
3744 catch(std::bad_alloc&)
3745 {
3746 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3747 }
3748
3749 return GL_FALSE;
3750}
3751
3752GLboolean __stdcall glIsTexture(GLuint texture)
3753{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003754 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003755
3756 try
3757 {
3758 gl::Context *context = gl::getContext();
3759
3760 if (context && texture)
3761 {
3762 gl::Texture *textureObject = context->getTexture(texture);
3763
3764 if (textureObject)
3765 {
3766 return GL_TRUE;
3767 }
3768 }
3769 }
3770 catch(std::bad_alloc&)
3771 {
3772 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3773 }
3774
3775 return GL_FALSE;
3776}
3777
3778void __stdcall glLineWidth(GLfloat width)
3779{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003780 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003781
3782 try
3783 {
3784 if (width <= 0.0f)
3785 {
3786 return error(GL_INVALID_VALUE);
3787 }
3788
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003789 gl::Context *context = gl::getContext();
3790
3791 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003792 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003793 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003794 }
3795 }
3796 catch(std::bad_alloc&)
3797 {
3798 return error(GL_OUT_OF_MEMORY);
3799 }
3800}
3801
3802void __stdcall glLinkProgram(GLuint program)
3803{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003804 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003805
3806 try
3807 {
3808 gl::Context *context = gl::getContext();
3809
3810 if (context)
3811 {
3812 gl::Program *programObject = context->getProgram(program);
3813
3814 if (!programObject)
3815 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003816 if (context->getShader(program))
3817 {
3818 return error(GL_INVALID_OPERATION);
3819 }
3820 else
3821 {
3822 return error(GL_INVALID_VALUE);
3823 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003824 }
3825
3826 programObject->link();
3827 }
3828 }
3829 catch(std::bad_alloc&)
3830 {
3831 return error(GL_OUT_OF_MEMORY);
3832 }
3833}
3834
3835void __stdcall glPixelStorei(GLenum pname, GLint param)
3836{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003837 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003838
3839 try
3840 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003841 gl::Context *context = gl::getContext();
3842
3843 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003844 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003845 switch (pname)
3846 {
3847 case GL_UNPACK_ALIGNMENT:
3848 if (param != 1 && param != 2 && param != 4 && param != 8)
3849 {
3850 return error(GL_INVALID_VALUE);
3851 }
3852
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003853 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003854 break;
3855
3856 case GL_PACK_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->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003863 break;
3864
3865 default:
3866 return error(GL_INVALID_ENUM);
3867 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003868 }
3869 }
3870 catch(std::bad_alloc&)
3871 {
3872 return error(GL_OUT_OF_MEMORY);
3873 }
3874}
3875
3876void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3877{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003878 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003879
3880 try
3881 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003882 gl::Context *context = gl::getContext();
3883
3884 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003885 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003886 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003887 }
3888 }
3889 catch(std::bad_alloc&)
3890 {
3891 return error(GL_OUT_OF_MEMORY);
3892 }
3893}
3894
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003895void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003896{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003897 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003898 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003899 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003900
3901 try
3902 {
3903 if (width < 0 || height < 0)
3904 {
3905 return error(GL_INVALID_VALUE);
3906 }
3907
3908 switch (format)
3909 {
3910 case GL_RGBA:
3911 switch (type)
3912 {
3913 case GL_UNSIGNED_BYTE:
3914 break;
3915 default:
3916 return error(GL_INVALID_OPERATION);
3917 }
3918 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003919 case GL_BGRA_EXT:
3920 switch (type)
3921 {
3922 case GL_UNSIGNED_BYTE:
3923 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3924 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3925 break;
3926 default:
3927 return error(GL_INVALID_OPERATION);
3928 }
3929 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003930 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3931 switch (type)
3932 {
3933 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3934 break;
3935 default:
3936 return error(GL_INVALID_OPERATION);
3937 }
3938 break;
3939 default:
3940 return error(GL_INVALID_OPERATION);
3941 }
3942
3943 gl::Context *context = gl::getContext();
3944
3945 if (context)
3946 {
3947 context->readPixels(x, y, width, height, format, type, pixels);
3948 }
3949 }
3950 catch(std::bad_alloc&)
3951 {
3952 return error(GL_OUT_OF_MEMORY);
3953 }
3954}
3955
3956void __stdcall glReleaseShaderCompiler(void)
3957{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003958 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003959
3960 try
3961 {
3962 gl::Shader::releaseCompiler();
3963 }
3964 catch(std::bad_alloc&)
3965 {
3966 return error(GL_OUT_OF_MEMORY);
3967 }
3968}
3969
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003970void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003971{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003972 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 +00003973 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003974
3975 try
3976 {
3977 switch (target)
3978 {
3979 case GL_RENDERBUFFER:
3980 break;
3981 default:
3982 return error(GL_INVALID_ENUM);
3983 }
3984
daniel@transgaming.comedc19182010-10-15 17:57:55 +00003985 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003986 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003987 return error(GL_INVALID_ENUM);
3988 }
3989
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00003990 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003991 {
3992 return error(GL_INVALID_VALUE);
3993 }
3994
3995 gl::Context *context = gl::getContext();
3996
3997 if (context)
3998 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00003999 if (width > context->getMaximumRenderbufferDimension() ||
4000 height > context->getMaximumRenderbufferDimension() ||
4001 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004002 {
4003 return error(GL_INVALID_VALUE);
4004 }
4005
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004006 GLuint handle = context->getRenderbufferHandle();
4007 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004008 {
4009 return error(GL_INVALID_OPERATION);
4010 }
4011
4012 switch (internalformat)
4013 {
4014 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004015 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004016 break;
4017 case GL_RGBA4:
4018 case GL_RGB5_A1:
4019 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004020 case GL_RGB8_OES:
4021 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004022 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004023 break;
4024 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004025 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004026 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004027 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004028 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004029 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004030 default:
4031 return error(GL_INVALID_ENUM);
4032 }
4033 }
4034 }
4035 catch(std::bad_alloc&)
4036 {
4037 return error(GL_OUT_OF_MEMORY);
4038 }
4039}
4040
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004041void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4042{
4043 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4044}
4045
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004046void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4047{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004048 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004049
4050 try
4051 {
4052 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004053
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004054 if (context)
4055 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004056 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004057 }
4058 }
4059 catch(std::bad_alloc&)
4060 {
4061 return error(GL_OUT_OF_MEMORY);
4062 }
4063}
4064
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004065void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4066{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004067 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004068
4069 try
4070 {
4071 if (condition != GL_ALL_COMPLETED_NV)
4072 {
4073 return error(GL_INVALID_ENUM);
4074 }
4075
4076 gl::Context *context = gl::getContext();
4077
4078 if (context)
4079 {
4080 gl::Fence *fenceObject = context->getFence(fence);
4081
4082 if (fenceObject == NULL)
4083 {
4084 return error(GL_INVALID_OPERATION);
4085 }
4086
4087 fenceObject->setFence(condition);
4088 }
4089 }
4090 catch(std::bad_alloc&)
4091 {
4092 return error(GL_OUT_OF_MEMORY);
4093 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004094}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004095
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004096void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4097{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004098 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 +00004099
4100 try
4101 {
4102 if (width < 0 || height < 0)
4103 {
4104 return error(GL_INVALID_VALUE);
4105 }
4106
4107 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004108
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004109 if (context)
4110 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004111 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004112 }
4113 }
4114 catch(std::bad_alloc&)
4115 {
4116 return error(GL_OUT_OF_MEMORY);
4117 }
4118}
4119
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004120void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004121{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004122 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004123 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004124 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004125
4126 try
4127 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004128 // No binary shader formats are supported.
4129 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004130 }
4131 catch(std::bad_alloc&)
4132 {
4133 return error(GL_OUT_OF_MEMORY);
4134 }
4135}
4136
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004137void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004138{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004139 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 +00004140 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004141
4142 try
4143 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004144 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004145 {
4146 return error(GL_INVALID_VALUE);
4147 }
4148
4149 gl::Context *context = gl::getContext();
4150
4151 if (context)
4152 {
4153 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004154
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004155 if (!shaderObject)
4156 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004157 if (context->getProgram(shader))
4158 {
4159 return error(GL_INVALID_OPERATION);
4160 }
4161 else
4162 {
4163 return error(GL_INVALID_VALUE);
4164 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004165 }
4166
4167 shaderObject->setSource(count, string, length);
4168 }
4169 }
4170 catch(std::bad_alloc&)
4171 {
4172 return error(GL_OUT_OF_MEMORY);
4173 }
4174}
4175
4176void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4177{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004178 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004179}
4180
4181void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4182{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004183 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 +00004184
4185 try
4186 {
4187 switch (face)
4188 {
4189 case GL_FRONT:
4190 case GL_BACK:
4191 case GL_FRONT_AND_BACK:
4192 break;
4193 default:
4194 return error(GL_INVALID_ENUM);
4195 }
4196
4197 switch (func)
4198 {
4199 case GL_NEVER:
4200 case GL_ALWAYS:
4201 case GL_LESS:
4202 case GL_LEQUAL:
4203 case GL_EQUAL:
4204 case GL_GEQUAL:
4205 case GL_GREATER:
4206 case GL_NOTEQUAL:
4207 break;
4208 default:
4209 return error(GL_INVALID_ENUM);
4210 }
4211
4212 gl::Context *context = gl::getContext();
4213
4214 if (context)
4215 {
4216 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4217 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004218 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004219 }
4220
4221 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4222 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004223 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004224 }
4225 }
4226 }
4227 catch(std::bad_alloc&)
4228 {
4229 return error(GL_OUT_OF_MEMORY);
4230 }
4231}
4232
4233void __stdcall glStencilMask(GLuint mask)
4234{
4235 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4236}
4237
4238void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4239{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004240 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004241
4242 try
4243 {
4244 switch (face)
4245 {
4246 case GL_FRONT:
4247 case GL_BACK:
4248 case GL_FRONT_AND_BACK:
4249 break;
4250 default:
4251 return error(GL_INVALID_ENUM);
4252 }
4253
4254 gl::Context *context = gl::getContext();
4255
4256 if (context)
4257 {
4258 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4259 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004260 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004261 }
4262
4263 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4264 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004265 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004266 }
4267 }
4268 }
4269 catch(std::bad_alloc&)
4270 {
4271 return error(GL_OUT_OF_MEMORY);
4272 }
4273}
4274
4275void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4276{
4277 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4278}
4279
4280void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4281{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004282 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 +00004283 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004284
4285 try
4286 {
4287 switch (face)
4288 {
4289 case GL_FRONT:
4290 case GL_BACK:
4291 case GL_FRONT_AND_BACK:
4292 break;
4293 default:
4294 return error(GL_INVALID_ENUM);
4295 }
4296
4297 switch (fail)
4298 {
4299 case GL_ZERO:
4300 case GL_KEEP:
4301 case GL_REPLACE:
4302 case GL_INCR:
4303 case GL_DECR:
4304 case GL_INVERT:
4305 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004306 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004307 break;
4308 default:
4309 return error(GL_INVALID_ENUM);
4310 }
4311
4312 switch (zfail)
4313 {
4314 case GL_ZERO:
4315 case GL_KEEP:
4316 case GL_REPLACE:
4317 case GL_INCR:
4318 case GL_DECR:
4319 case GL_INVERT:
4320 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004321 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004322 break;
4323 default:
4324 return error(GL_INVALID_ENUM);
4325 }
4326
4327 switch (zpass)
4328 {
4329 case GL_ZERO:
4330 case GL_KEEP:
4331 case GL_REPLACE:
4332 case GL_INCR:
4333 case GL_DECR:
4334 case GL_INVERT:
4335 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004336 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004337 break;
4338 default:
4339 return error(GL_INVALID_ENUM);
4340 }
4341
4342 gl::Context *context = gl::getContext();
4343
4344 if (context)
4345 {
4346 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4347 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004348 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004349 }
4350
4351 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4352 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004353 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004354 }
4355 }
4356 }
4357 catch(std::bad_alloc&)
4358 {
4359 return error(GL_OUT_OF_MEMORY);
4360 }
4361}
4362
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004363GLboolean __stdcall glTestFenceNV(GLuint fence)
4364{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004365 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004366
4367 try
4368 {
4369 gl::Context *context = gl::getContext();
4370
4371 if (context)
4372 {
4373 gl::Fence *fenceObject = context->getFence(fence);
4374
4375 if (fenceObject == NULL)
4376 {
4377 return error(GL_INVALID_OPERATION, GL_TRUE);
4378 }
4379
4380 return fenceObject->testFence();
4381 }
4382 }
4383 catch(std::bad_alloc&)
4384 {
4385 error(GL_OUT_OF_MEMORY);
4386 }
4387
4388 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004389}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004390
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004391void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4392 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004393{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004394 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 +00004395 "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 +00004396 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004397
4398 try
4399 {
4400 if (level < 0 || width < 0 || height < 0)
4401 {
4402 return error(GL_INVALID_VALUE);
4403 }
4404
4405 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
4406 {
4407 return error(GL_INVALID_VALUE);
4408 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004409
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004410 if (internalformat != format)
4411 {
4412 return error(GL_INVALID_OPERATION);
4413 }
4414
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004415 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004416 {
4417 case GL_ALPHA:
4418 case GL_LUMINANCE:
4419 case GL_LUMINANCE_ALPHA:
4420 switch (type)
4421 {
4422 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004423 case GL_FLOAT:
4424 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004425 break;
4426 default:
4427 return error(GL_INVALID_ENUM);
4428 }
4429 break;
4430 case GL_RGB:
4431 switch (type)
4432 {
4433 case GL_UNSIGNED_BYTE:
4434 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004435 case GL_FLOAT:
4436 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004437 break;
4438 default:
4439 return error(GL_INVALID_ENUM);
4440 }
4441 break;
4442 case GL_RGBA:
4443 switch (type)
4444 {
4445 case GL_UNSIGNED_BYTE:
4446 case GL_UNSIGNED_SHORT_4_4_4_4:
4447 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004448 case GL_FLOAT:
4449 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004450 break;
4451 default:
4452 return error(GL_INVALID_ENUM);
4453 }
4454 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004455 case GL_BGRA_EXT:
4456 switch (type)
4457 {
4458 case GL_UNSIGNED_BYTE:
4459 break;
4460 default:
4461 return error(GL_INVALID_ENUM);
4462 }
4463 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004464 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4465 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4466 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004467 default:
4468 return error(GL_INVALID_VALUE);
4469 }
4470
4471 if (border != 0)
4472 {
4473 return error(GL_INVALID_VALUE);
4474 }
4475
4476 gl::Context *context = gl::getContext();
4477
4478 if (context)
4479 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004480 switch (target)
4481 {
4482 case GL_TEXTURE_2D:
4483 if (width > (context->getMaximumTextureDimension() >> level) ||
4484 height > (context->getMaximumTextureDimension() >> level))
4485 {
4486 return error(GL_INVALID_VALUE);
4487 }
4488 break;
4489 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4490 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4491 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4492 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4493 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4494 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4495 if (width != height)
4496 {
4497 return error(GL_INVALID_VALUE);
4498 }
4499
4500 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4501 height > (context->getMaximumCubeTextureDimension() >> level))
4502 {
4503 return error(GL_INVALID_VALUE);
4504 }
4505 break;
4506 default:
4507 return error(GL_INVALID_ENUM);
4508 }
4509
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004510 if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4511 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
daniel@transgaming.com01868132010-08-24 19:21:17 +00004512 {
4513 if (context->supportsCompressedTextures())
4514 {
4515 return error(GL_INVALID_OPERATION);
4516 }
4517 else
4518 {
4519 return error(GL_INVALID_ENUM);
4520 }
4521 }
4522
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004523 if (type == GL_FLOAT)
4524 {
4525 if (!context->supportsFloatTextures())
4526 {
4527 return error(GL_INVALID_ENUM);
4528 }
4529 }
4530 else if (type == GL_HALF_FLOAT_OES)
4531 {
4532 if (!context->supportsHalfFloatTextures())
4533 {
4534 return error(GL_INVALID_ENUM);
4535 }
4536 }
4537
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004538 if (target == GL_TEXTURE_2D)
4539 {
4540 gl::Texture2D *texture = context->getTexture2D();
4541
4542 if (!texture)
4543 {
4544 return error(GL_INVALID_OPERATION);
4545 }
4546
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004547 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004548 }
4549 else
4550 {
4551 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4552
4553 if (!texture)
4554 {
4555 return error(GL_INVALID_OPERATION);
4556 }
4557
4558 switch (target)
4559 {
4560 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004561 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004562 break;
4563 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004564 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004565 break;
4566 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004567 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004568 break;
4569 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004570 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004571 break;
4572 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004573 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004574 break;
4575 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004576 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004577 break;
4578 default: UNREACHABLE();
4579 }
4580 }
4581 }
4582 }
4583 catch(std::bad_alloc&)
4584 {
4585 return error(GL_OUT_OF_MEMORY);
4586 }
4587}
4588
4589void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4590{
4591 glTexParameteri(target, pname, (GLint)param);
4592}
4593
4594void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4595{
4596 glTexParameteri(target, pname, (GLint)*params);
4597}
4598
4599void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4600{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004601 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004602
4603 try
4604 {
4605 gl::Context *context = gl::getContext();
4606
4607 if (context)
4608 {
4609 gl::Texture *texture;
4610
4611 switch (target)
4612 {
4613 case GL_TEXTURE_2D:
4614 texture = context->getTexture2D();
4615 break;
4616 case GL_TEXTURE_CUBE_MAP:
4617 texture = context->getTextureCubeMap();
4618 break;
4619 default:
4620 return error(GL_INVALID_ENUM);
4621 }
4622
4623 switch (pname)
4624 {
4625 case GL_TEXTURE_WRAP_S:
4626 if (!texture->setWrapS((GLenum)param))
4627 {
4628 return error(GL_INVALID_ENUM);
4629 }
4630 break;
4631 case GL_TEXTURE_WRAP_T:
4632 if (!texture->setWrapT((GLenum)param))
4633 {
4634 return error(GL_INVALID_ENUM);
4635 }
4636 break;
4637 case GL_TEXTURE_MIN_FILTER:
4638 if (!texture->setMinFilter((GLenum)param))
4639 {
4640 return error(GL_INVALID_ENUM);
4641 }
4642 break;
4643 case GL_TEXTURE_MAG_FILTER:
4644 if (!texture->setMagFilter((GLenum)param))
4645 {
4646 return error(GL_INVALID_ENUM);
4647 }
4648 break;
4649 default:
4650 return error(GL_INVALID_ENUM);
4651 }
4652 }
4653 }
4654 catch(std::bad_alloc&)
4655 {
4656 return error(GL_OUT_OF_MEMORY);
4657 }
4658}
4659
4660void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4661{
4662 glTexParameteri(target, pname, *params);
4663}
4664
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004665void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4666 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004667{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004668 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004669 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004670 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004671 target, level, xoffset, yoffset, width, height, format, type, pixels);
4672
4673 try
4674 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004675 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004676 {
4677 return error(GL_INVALID_ENUM);
4678 }
4679
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004680 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004681 {
4682 return error(GL_INVALID_VALUE);
4683 }
4684
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004685 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4686 {
4687 return error(GL_INVALID_VALUE);
4688 }
4689
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004690 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004691 {
4692 return error(GL_INVALID_ENUM);
4693 }
4694
4695 if (width == 0 || height == 0 || pixels == NULL)
4696 {
4697 return;
4698 }
4699
4700 gl::Context *context = gl::getContext();
4701
4702 if (context)
4703 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004704 if (level > context->getMaximumTextureLevel())
4705 {
4706 return error(GL_INVALID_VALUE);
4707 }
4708
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004709 if (format == GL_FLOAT)
4710 {
4711 if (!context->supportsFloatTextures())
4712 {
4713 return error(GL_INVALID_ENUM);
4714 }
4715 }
4716 else if (format == GL_HALF_FLOAT_OES)
4717 {
4718 if (!context->supportsHalfFloatTextures())
4719 {
4720 return error(GL_INVALID_ENUM);
4721 }
4722 }
4723
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004724 if (target == GL_TEXTURE_2D)
4725 {
4726 gl::Texture2D *texture = context->getTexture2D();
4727
4728 if (!texture)
4729 {
4730 return error(GL_INVALID_OPERATION);
4731 }
4732
daniel@transgaming.com01868132010-08-24 19:21:17 +00004733 if (texture->isCompressed())
4734 {
4735 return error(GL_INVALID_OPERATION);
4736 }
4737
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00004738 if (format != texture->getInternalFormat())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004739 {
4740 return error(GL_INVALID_OPERATION);
4741 }
4742
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004743 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004744 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004745 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004746 {
4747 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4748
4749 if (!texture)
4750 {
4751 return error(GL_INVALID_OPERATION);
4752 }
4753
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004754 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004755 }
4756 else
4757 {
4758 UNREACHABLE();
4759 }
4760 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004761 }
4762 catch(std::bad_alloc&)
4763 {
4764 return error(GL_OUT_OF_MEMORY);
4765 }
4766}
4767
4768void __stdcall glUniform1f(GLint location, GLfloat x)
4769{
4770 glUniform1fv(location, 1, &x);
4771}
4772
4773void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4774{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004775 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004776
4777 try
4778 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004779 if (count < 0)
4780 {
4781 return error(GL_INVALID_VALUE);
4782 }
4783
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004784 if (location == -1)
4785 {
4786 return;
4787 }
4788
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004789 gl::Context *context = gl::getContext();
4790
4791 if (context)
4792 {
4793 gl::Program *program = context->getCurrentProgram();
4794
4795 if (!program)
4796 {
4797 return error(GL_INVALID_OPERATION);
4798 }
4799
4800 if (!program->setUniform1fv(location, count, v))
4801 {
4802 return error(GL_INVALID_OPERATION);
4803 }
4804 }
4805 }
4806 catch(std::bad_alloc&)
4807 {
4808 return error(GL_OUT_OF_MEMORY);
4809 }
4810}
4811
4812void __stdcall glUniform1i(GLint location, GLint x)
4813{
4814 glUniform1iv(location, 1, &x);
4815}
4816
4817void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4818{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004819 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004820
4821 try
4822 {
4823 if (count < 0)
4824 {
4825 return error(GL_INVALID_VALUE);
4826 }
4827
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004828 if (location == -1)
4829 {
4830 return;
4831 }
4832
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004833 gl::Context *context = gl::getContext();
4834
4835 if (context)
4836 {
4837 gl::Program *program = context->getCurrentProgram();
4838
4839 if (!program)
4840 {
4841 return error(GL_INVALID_OPERATION);
4842 }
4843
4844 if (!program->setUniform1iv(location, count, v))
4845 {
4846 return error(GL_INVALID_OPERATION);
4847 }
4848 }
4849 }
4850 catch(std::bad_alloc&)
4851 {
4852 return error(GL_OUT_OF_MEMORY);
4853 }
4854}
4855
4856void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4857{
4858 GLfloat xy[2] = {x, y};
4859
4860 glUniform2fv(location, 1, (GLfloat*)&xy);
4861}
4862
4863void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4864{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004865 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004866
4867 try
4868 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004869 if (count < 0)
4870 {
4871 return error(GL_INVALID_VALUE);
4872 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004873
4874 if (location == -1)
4875 {
4876 return;
4877 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004878
4879 gl::Context *context = gl::getContext();
4880
4881 if (context)
4882 {
4883 gl::Program *program = context->getCurrentProgram();
4884
4885 if (!program)
4886 {
4887 return error(GL_INVALID_OPERATION);
4888 }
4889
4890 if (!program->setUniform2fv(location, count, v))
4891 {
4892 return error(GL_INVALID_OPERATION);
4893 }
4894 }
4895 }
4896 catch(std::bad_alloc&)
4897 {
4898 return error(GL_OUT_OF_MEMORY);
4899 }
4900}
4901
4902void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4903{
4904 GLint xy[4] = {x, y};
4905
4906 glUniform2iv(location, 1, (GLint*)&xy);
4907}
4908
4909void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4910{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004911 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004912
4913 try
4914 {
4915 if (count < 0)
4916 {
4917 return error(GL_INVALID_VALUE);
4918 }
4919
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004920 if (location == -1)
4921 {
4922 return;
4923 }
4924
4925 gl::Context *context = gl::getContext();
4926
4927 if (context)
4928 {
4929 gl::Program *program = context->getCurrentProgram();
4930
4931 if (!program)
4932 {
4933 return error(GL_INVALID_OPERATION);
4934 }
4935
4936 if (!program->setUniform2iv(location, count, v))
4937 {
4938 return error(GL_INVALID_OPERATION);
4939 }
4940 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004941 }
4942 catch(std::bad_alloc&)
4943 {
4944 return error(GL_OUT_OF_MEMORY);
4945 }
4946}
4947
4948void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4949{
4950 GLfloat xyz[3] = {x, y, z};
4951
4952 glUniform3fv(location, 1, (GLfloat*)&xyz);
4953}
4954
4955void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4956{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004957 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004958
4959 try
4960 {
4961 if (count < 0)
4962 {
4963 return error(GL_INVALID_VALUE);
4964 }
4965
4966 if (location == -1)
4967 {
4968 return;
4969 }
4970
4971 gl::Context *context = gl::getContext();
4972
4973 if (context)
4974 {
4975 gl::Program *program = context->getCurrentProgram();
4976
4977 if (!program)
4978 {
4979 return error(GL_INVALID_OPERATION);
4980 }
4981
4982 if (!program->setUniform3fv(location, count, v))
4983 {
4984 return error(GL_INVALID_OPERATION);
4985 }
4986 }
4987 }
4988 catch(std::bad_alloc&)
4989 {
4990 return error(GL_OUT_OF_MEMORY);
4991 }
4992}
4993
4994void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4995{
4996 GLint xyz[3] = {x, y, z};
4997
4998 glUniform3iv(location, 1, (GLint*)&xyz);
4999}
5000
5001void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5002{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005003 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005004
5005 try
5006 {
5007 if (count < 0)
5008 {
5009 return error(GL_INVALID_VALUE);
5010 }
5011
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005012 if (location == -1)
5013 {
5014 return;
5015 }
5016
5017 gl::Context *context = gl::getContext();
5018
5019 if (context)
5020 {
5021 gl::Program *program = context->getCurrentProgram();
5022
5023 if (!program)
5024 {
5025 return error(GL_INVALID_OPERATION);
5026 }
5027
5028 if (!program->setUniform3iv(location, count, v))
5029 {
5030 return error(GL_INVALID_OPERATION);
5031 }
5032 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005033 }
5034 catch(std::bad_alloc&)
5035 {
5036 return error(GL_OUT_OF_MEMORY);
5037 }
5038}
5039
5040void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5041{
5042 GLfloat xyzw[4] = {x, y, z, w};
5043
5044 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5045}
5046
5047void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5048{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005049 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005050
5051 try
5052 {
5053 if (count < 0)
5054 {
5055 return error(GL_INVALID_VALUE);
5056 }
5057
5058 if (location == -1)
5059 {
5060 return;
5061 }
5062
5063 gl::Context *context = gl::getContext();
5064
5065 if (context)
5066 {
5067 gl::Program *program = context->getCurrentProgram();
5068
5069 if (!program)
5070 {
5071 return error(GL_INVALID_OPERATION);
5072 }
5073
5074 if (!program->setUniform4fv(location, count, v))
5075 {
5076 return error(GL_INVALID_OPERATION);
5077 }
5078 }
5079 }
5080 catch(std::bad_alloc&)
5081 {
5082 return error(GL_OUT_OF_MEMORY);
5083 }
5084}
5085
5086void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5087{
5088 GLint xyzw[4] = {x, y, z, w};
5089
5090 glUniform4iv(location, 1, (GLint*)&xyzw);
5091}
5092
5093void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5094{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005095 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005096
5097 try
5098 {
5099 if (count < 0)
5100 {
5101 return error(GL_INVALID_VALUE);
5102 }
5103
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005104 if (location == -1)
5105 {
5106 return;
5107 }
5108
5109 gl::Context *context = gl::getContext();
5110
5111 if (context)
5112 {
5113 gl::Program *program = context->getCurrentProgram();
5114
5115 if (!program)
5116 {
5117 return error(GL_INVALID_OPERATION);
5118 }
5119
5120 if (!program->setUniform4iv(location, count, v))
5121 {
5122 return error(GL_INVALID_OPERATION);
5123 }
5124 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005125 }
5126 catch(std::bad_alloc&)
5127 {
5128 return error(GL_OUT_OF_MEMORY);
5129 }
5130}
5131
5132void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5133{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005134 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005135 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005136
5137 try
5138 {
5139 if (count < 0 || transpose != GL_FALSE)
5140 {
5141 return error(GL_INVALID_VALUE);
5142 }
5143
5144 if (location == -1)
5145 {
5146 return;
5147 }
5148
5149 gl::Context *context = gl::getContext();
5150
5151 if (context)
5152 {
5153 gl::Program *program = context->getCurrentProgram();
5154
5155 if (!program)
5156 {
5157 return error(GL_INVALID_OPERATION);
5158 }
5159
5160 if (!program->setUniformMatrix2fv(location, count, value))
5161 {
5162 return error(GL_INVALID_OPERATION);
5163 }
5164 }
5165 }
5166 catch(std::bad_alloc&)
5167 {
5168 return error(GL_OUT_OF_MEMORY);
5169 }
5170}
5171
5172void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5173{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005174 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005175 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005176
5177 try
5178 {
5179 if (count < 0 || transpose != GL_FALSE)
5180 {
5181 return error(GL_INVALID_VALUE);
5182 }
5183
5184 if (location == -1)
5185 {
5186 return;
5187 }
5188
5189 gl::Context *context = gl::getContext();
5190
5191 if (context)
5192 {
5193 gl::Program *program = context->getCurrentProgram();
5194
5195 if (!program)
5196 {
5197 return error(GL_INVALID_OPERATION);
5198 }
5199
5200 if (!program->setUniformMatrix3fv(location, count, value))
5201 {
5202 return error(GL_INVALID_OPERATION);
5203 }
5204 }
5205 }
5206 catch(std::bad_alloc&)
5207 {
5208 return error(GL_OUT_OF_MEMORY);
5209 }
5210}
5211
5212void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5213{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005214 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005215 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005216
5217 try
5218 {
5219 if (count < 0 || transpose != GL_FALSE)
5220 {
5221 return error(GL_INVALID_VALUE);
5222 }
5223
5224 if (location == -1)
5225 {
5226 return;
5227 }
5228
5229 gl::Context *context = gl::getContext();
5230
5231 if (context)
5232 {
5233 gl::Program *program = context->getCurrentProgram();
5234
5235 if (!program)
5236 {
5237 return error(GL_INVALID_OPERATION);
5238 }
5239
5240 if (!program->setUniformMatrix4fv(location, count, value))
5241 {
5242 return error(GL_INVALID_OPERATION);
5243 }
5244 }
5245 }
5246 catch(std::bad_alloc&)
5247 {
5248 return error(GL_OUT_OF_MEMORY);
5249 }
5250}
5251
5252void __stdcall glUseProgram(GLuint program)
5253{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005254 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005255
5256 try
5257 {
5258 gl::Context *context = gl::getContext();
5259
5260 if (context)
5261 {
5262 gl::Program *programObject = context->getProgram(program);
5263
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005264 if (!programObject && program != 0)
5265 {
5266 if (context->getShader(program))
5267 {
5268 return error(GL_INVALID_OPERATION);
5269 }
5270 else
5271 {
5272 return error(GL_INVALID_VALUE);
5273 }
5274 }
5275
5276 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005277 {
5278 return error(GL_INVALID_OPERATION);
5279 }
5280
5281 context->useProgram(program);
5282 }
5283 }
5284 catch(std::bad_alloc&)
5285 {
5286 return error(GL_OUT_OF_MEMORY);
5287 }
5288}
5289
5290void __stdcall glValidateProgram(GLuint program)
5291{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005292 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005293
5294 try
5295 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005296 gl::Context *context = gl::getContext();
5297
5298 if (context)
5299 {
5300 gl::Program *programObject = context->getProgram(program);
5301
5302 if (!programObject)
5303 {
5304 if (context->getShader(program))
5305 {
5306 return error(GL_INVALID_OPERATION);
5307 }
5308 else
5309 {
5310 return error(GL_INVALID_VALUE);
5311 }
5312 }
5313
5314 programObject->validate();
5315 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005316 }
5317 catch(std::bad_alloc&)
5318 {
5319 return error(GL_OUT_OF_MEMORY);
5320 }
5321}
5322
5323void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5324{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005325 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005326
5327 try
5328 {
5329 if (index >= gl::MAX_VERTEX_ATTRIBS)
5330 {
5331 return error(GL_INVALID_VALUE);
5332 }
5333
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005334 gl::Context *context = gl::getContext();
5335
5336 if (context)
5337 {
5338 GLfloat vals[4] = { x, 0, 0, 1 };
5339 context->setVertexAttrib(index, vals);
5340 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005341 }
5342 catch(std::bad_alloc&)
5343 {
5344 return error(GL_OUT_OF_MEMORY);
5345 }
5346}
5347
5348void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5349{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005350 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005351
5352 try
5353 {
5354 if (index >= gl::MAX_VERTEX_ATTRIBS)
5355 {
5356 return error(GL_INVALID_VALUE);
5357 }
5358
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005359 gl::Context *context = gl::getContext();
5360
5361 if (context)
5362 {
5363 GLfloat vals[4] = { values[0], 0, 0, 1 };
5364 context->setVertexAttrib(index, vals);
5365 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005366 }
5367 catch(std::bad_alloc&)
5368 {
5369 return error(GL_OUT_OF_MEMORY);
5370 }
5371}
5372
5373void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5374{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005375 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005376
5377 try
5378 {
5379 if (index >= gl::MAX_VERTEX_ATTRIBS)
5380 {
5381 return error(GL_INVALID_VALUE);
5382 }
5383
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005384 gl::Context *context = gl::getContext();
5385
5386 if (context)
5387 {
5388 GLfloat vals[4] = { x, y, 0, 1 };
5389 context->setVertexAttrib(index, vals);
5390 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005391 }
5392 catch(std::bad_alloc&)
5393 {
5394 return error(GL_OUT_OF_MEMORY);
5395 }
5396}
5397
5398void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5399{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005400 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005401
5402 try
5403 {
5404 if (index >= gl::MAX_VERTEX_ATTRIBS)
5405 {
5406 return error(GL_INVALID_VALUE);
5407 }
5408
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005409 gl::Context *context = gl::getContext();
5410
5411 if (context)
5412 {
5413 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5414 context->setVertexAttrib(index, vals);
5415 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005416 }
5417 catch(std::bad_alloc&)
5418 {
5419 return error(GL_OUT_OF_MEMORY);
5420 }
5421}
5422
5423void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5424{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005425 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 +00005426
5427 try
5428 {
5429 if (index >= gl::MAX_VERTEX_ATTRIBS)
5430 {
5431 return error(GL_INVALID_VALUE);
5432 }
5433
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005434 gl::Context *context = gl::getContext();
5435
5436 if (context)
5437 {
5438 GLfloat vals[4] = { x, y, z, 1 };
5439 context->setVertexAttrib(index, vals);
5440 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005441 }
5442 catch(std::bad_alloc&)
5443 {
5444 return error(GL_OUT_OF_MEMORY);
5445 }
5446}
5447
5448void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5449{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005450 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005451
5452 try
5453 {
5454 if (index >= gl::MAX_VERTEX_ATTRIBS)
5455 {
5456 return error(GL_INVALID_VALUE);
5457 }
5458
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005459 gl::Context *context = gl::getContext();
5460
5461 if (context)
5462 {
5463 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5464 context->setVertexAttrib(index, vals);
5465 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005466 }
5467 catch(std::bad_alloc&)
5468 {
5469 return error(GL_OUT_OF_MEMORY);
5470 }
5471}
5472
5473void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5474{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005475 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 +00005476
5477 try
5478 {
5479 if (index >= gl::MAX_VERTEX_ATTRIBS)
5480 {
5481 return error(GL_INVALID_VALUE);
5482 }
5483
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005484 gl::Context *context = gl::getContext();
5485
5486 if (context)
5487 {
5488 GLfloat vals[4] = { x, y, z, w };
5489 context->setVertexAttrib(index, vals);
5490 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005491 }
5492 catch(std::bad_alloc&)
5493 {
5494 return error(GL_OUT_OF_MEMORY);
5495 }
5496}
5497
5498void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5499{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005500 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005501
5502 try
5503 {
5504 if (index >= gl::MAX_VERTEX_ATTRIBS)
5505 {
5506 return error(GL_INVALID_VALUE);
5507 }
5508
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005509 gl::Context *context = gl::getContext();
5510
5511 if (context)
5512 {
5513 context->setVertexAttrib(index, values);
5514 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005515 }
5516 catch(std::bad_alloc&)
5517 {
5518 return error(GL_OUT_OF_MEMORY);
5519 }
5520}
5521
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005522void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005523{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005524 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005525 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005526 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005527
5528 try
5529 {
5530 if (index >= gl::MAX_VERTEX_ATTRIBS)
5531 {
5532 return error(GL_INVALID_VALUE);
5533 }
5534
5535 if (size < 1 || size > 4)
5536 {
5537 return error(GL_INVALID_VALUE);
5538 }
5539
5540 switch (type)
5541 {
5542 case GL_BYTE:
5543 case GL_UNSIGNED_BYTE:
5544 case GL_SHORT:
5545 case GL_UNSIGNED_SHORT:
5546 case GL_FIXED:
5547 case GL_FLOAT:
5548 break;
5549 default:
5550 return error(GL_INVALID_ENUM);
5551 }
5552
5553 if (stride < 0)
5554 {
5555 return error(GL_INVALID_VALUE);
5556 }
5557
5558 gl::Context *context = gl::getContext();
5559
5560 if (context)
5561 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005562 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005563 }
5564 }
5565 catch(std::bad_alloc&)
5566 {
5567 return error(GL_OUT_OF_MEMORY);
5568 }
5569}
5570
5571void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5572{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005573 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 +00005574
5575 try
5576 {
5577 if (width < 0 || height < 0)
5578 {
5579 return error(GL_INVALID_VALUE);
5580 }
5581
5582 gl::Context *context = gl::getContext();
5583
5584 if (context)
5585 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005586 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005587 }
5588 }
5589 catch(std::bad_alloc&)
5590 {
5591 return error(GL_OUT_OF_MEMORY);
5592 }
5593}
5594
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005595void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5596 GLbitfield mask, GLenum filter)
5597{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005598 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005599 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5600 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5601 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5602
5603 try
5604 {
5605 switch (filter)
5606 {
5607 case GL_NEAREST:
5608 break;
5609 default:
5610 return error(GL_INVALID_ENUM);
5611 }
5612
5613 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5614 {
5615 return error(GL_INVALID_VALUE);
5616 }
5617
5618 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5619 {
5620 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5621 return error(GL_INVALID_OPERATION);
5622 }
5623
5624 gl::Context *context = gl::getContext();
5625
5626 if (context)
5627 {
5628 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5629 {
5630 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5631 return error(GL_INVALID_OPERATION);
5632 }
5633
5634 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5635 }
5636 }
5637 catch(std::bad_alloc&)
5638 {
5639 return error(GL_OUT_OF_MEMORY);
5640 }
5641}
5642
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005643void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5644 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005645{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005646 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005647 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005648 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005649 target, level, internalformat, width, height, depth, border, format, type, pixels);
5650
5651 try
5652 {
5653 UNIMPLEMENTED(); // FIXME
5654 }
5655 catch(std::bad_alloc&)
5656 {
5657 return error(GL_OUT_OF_MEMORY);
5658 }
5659}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005660
5661__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5662{
5663 struct Extension
5664 {
5665 const char *name;
5666 __eglMustCastToProperFunctionPointerType address;
5667 };
5668
5669 static const Extension glExtensions[] =
5670 {
5671 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00005672 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00005673 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005674 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
5675 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
5676 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
5677 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
5678 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
5679 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
5680 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005681 };
5682
5683 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5684 {
5685 if (strcmp(procname, glExtensions[ext].name) == 0)
5686 {
5687 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5688 }
5689 }
5690
5691 return NULL;
5692}
5693
jbauman@chromium.orgae345802011-03-30 22:04:25 +00005694void __stdcall glBindTexImage(egl::Surface *surface)
5695{
5696 EVENT("(egl::Surface* surface = 0x%0.8p)",
5697 surface);
5698
5699 try
5700 {
5701 gl::Context *context = gl::getContext();
5702
5703 if (context)
5704 {
5705 gl::Texture2D *textureObject = context->getTexture2D();
5706
5707 if (textureObject)
5708 {
5709 textureObject->bindTexImage(surface);
5710 }
5711 }
5712 }
5713 catch(std::bad_alloc&)
5714 {
5715 return error(GL_OUT_OF_MEMORY);
5716 }
5717}
5718
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005719}