blob: bed9211bbfbd92bf3d826996572d2a7dc76928f1 [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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000036 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000060 TRACE("(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{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000109 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000152 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000181 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000213 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000237 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000273 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
274 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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000298 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000342 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
343 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{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000460 TRACE("(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{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000514 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000568 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000604 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000623 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
624 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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000643 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000662 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000681 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
682 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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000701 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000735 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000859 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
860 "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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000979 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
980 "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.com3f85fbb2010-10-15 17:58:05 +00001047 GLenum colorbufferFormat = source->getFormat();
1048
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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001133 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1134 "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.com3f85fbb2010-10-15 17:58:05 +00001181 GLenum colorbufferFormat = source->getFormat();
1182 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
1199 GLenum textureFormat = texture->getFormat();
1200
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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001256 TRACE("()");
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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001277 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001305 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001335 TRACE("(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{
1362 TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
1363
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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001389 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001419 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001455 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001482 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001518 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001548 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001582 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001601 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001620 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001673 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001705 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001729 TRACE("(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{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001753 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001793 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001825 TRACE("(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{
1849 TRACE("(GLuint fence = %d)", fence);
1850
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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001875 TRACE("()");
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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001894 TRACE("()");
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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001913 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1914 "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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001970 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1971 "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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002077 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002106 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002133 TRACE("(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{
2173 TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
2174
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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002200 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002227 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002254 TRACE("(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{
daniel@transgaming.com85423182010-04-22 13:35:27 +00002281 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2282 "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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002326 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002371 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2372 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{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002410 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002451 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002514 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002561 TRACE("()");
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{
2575 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
2576
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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002602 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002662 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2663 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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002781 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002846 TRACE("(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{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002903 TRACE("(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{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002935 TRACE("(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 {
2957 case GL_RENDERBUFFER_WIDTH:
2958 *params = renderbuffer->getWidth();
2959 break;
2960 case GL_RENDERBUFFER_HEIGHT:
2961 *params = renderbuffer->getHeight();
2962 break;
2963 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2964 *params = renderbuffer->getFormat();
2965 break;
2966 case GL_RENDERBUFFER_RED_SIZE:
2967 if (renderbuffer->isColorbuffer())
2968 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002969 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002970 }
2971 else
2972 {
2973 *params = 0;
2974 }
2975 break;
2976 case GL_RENDERBUFFER_GREEN_SIZE:
2977 if (renderbuffer->isColorbuffer())
2978 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002979 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002980 }
2981 else
2982 {
2983 *params = 0;
2984 }
2985 break;
2986 case GL_RENDERBUFFER_BLUE_SIZE:
2987 if (renderbuffer->isColorbuffer())
2988 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002989 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002990 }
2991 else
2992 {
2993 *params = 0;
2994 }
2995 break;
2996 case GL_RENDERBUFFER_ALPHA_SIZE:
2997 if (renderbuffer->isColorbuffer())
2998 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002999 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003000 }
3001 else
3002 {
3003 *params = 0;
3004 }
3005 break;
3006 case GL_RENDERBUFFER_DEPTH_SIZE:
3007 if (renderbuffer->isDepthbuffer())
3008 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003009 *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003010 }
3011 else
3012 {
3013 *params = 0;
3014 }
3015 break;
3016 case GL_RENDERBUFFER_STENCIL_SIZE:
3017 if (renderbuffer->isStencilbuffer())
3018 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003019 *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003020 }
3021 else
3022 {
3023 *params = 0;
3024 }
3025 break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003026 case GL_RENDERBUFFER_SAMPLES_ANGLE:
3027 {
3028 if (context->getMaxSupportedSamples() != 0)
3029 {
3030 *params = renderbuffer->getStorage()->getSamples();
3031 }
3032 else
3033 {
3034 return error(GL_INVALID_ENUM);
3035 }
3036 }
3037 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003038 default:
3039 return error(GL_INVALID_ENUM);
3040 }
3041 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003042 }
3043 catch(std::bad_alloc&)
3044 {
3045 return error(GL_OUT_OF_MEMORY);
3046 }
3047}
3048
3049void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3050{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003051 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003052
3053 try
3054 {
3055 gl::Context *context = gl::getContext();
3056
3057 if (context)
3058 {
3059 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003060
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003061 if (!shaderObject)
3062 {
3063 return error(GL_INVALID_VALUE);
3064 }
3065
3066 switch (pname)
3067 {
3068 case GL_SHADER_TYPE:
3069 *params = shaderObject->getType();
3070 return;
3071 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003072 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003073 return;
3074 case GL_COMPILE_STATUS:
3075 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3076 return;
3077 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003078 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003079 return;
3080 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003081 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003082 return;
3083 default:
3084 return error(GL_INVALID_ENUM);
3085 }
3086 }
3087 }
3088 catch(std::bad_alloc&)
3089 {
3090 return error(GL_OUT_OF_MEMORY);
3091 }
3092}
3093
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003094void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003095{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003096 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003097 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003098
3099 try
3100 {
3101 if (bufsize < 0)
3102 {
3103 return error(GL_INVALID_VALUE);
3104 }
3105
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003106 gl::Context *context = gl::getContext();
3107
3108 if (context)
3109 {
3110 gl::Shader *shaderObject = context->getShader(shader);
3111
3112 if (!shaderObject)
3113 {
3114 return error(GL_INVALID_VALUE);
3115 }
3116
3117 shaderObject->getInfoLog(bufsize, length, infolog);
3118 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003119 }
3120 catch(std::bad_alloc&)
3121 {
3122 return error(GL_OUT_OF_MEMORY);
3123 }
3124}
3125
3126void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3127{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003128 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
3129 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003130
3131 try
3132 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003133 switch (shadertype)
3134 {
3135 case GL_VERTEX_SHADER:
3136 case GL_FRAGMENT_SHADER:
3137 break;
3138 default:
3139 return error(GL_INVALID_ENUM);
3140 }
3141
3142 switch (precisiontype)
3143 {
3144 case GL_LOW_FLOAT:
3145 case GL_MEDIUM_FLOAT:
3146 case GL_HIGH_FLOAT:
3147 // Assume IEEE 754 precision
3148 range[0] = 127;
3149 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003150 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003151 break;
3152 case GL_LOW_INT:
3153 case GL_MEDIUM_INT:
3154 case GL_HIGH_INT:
3155 // Some (most) hardware only supports single-precision floating-point numbers,
3156 // which can accurately represent integers up to +/-16777216
3157 range[0] = 24;
3158 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003159 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003160 break;
3161 default:
3162 return error(GL_INVALID_ENUM);
3163 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003164 }
3165 catch(std::bad_alloc&)
3166 {
3167 return error(GL_OUT_OF_MEMORY);
3168 }
3169}
3170
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003171void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003172{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003173 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003174 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003175
3176 try
3177 {
3178 if (bufsize < 0)
3179 {
3180 return error(GL_INVALID_VALUE);
3181 }
3182
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003183 gl::Context *context = gl::getContext();
3184
3185 if (context)
3186 {
3187 gl::Shader *shaderObject = context->getShader(shader);
3188
3189 if (!shaderObject)
3190 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003191 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003192 }
3193
3194 shaderObject->getSource(bufsize, length, source);
3195 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003196 }
3197 catch(std::bad_alloc&)
3198 {
3199 return error(GL_OUT_OF_MEMORY);
3200 }
3201}
3202
3203const GLubyte* __stdcall glGetString(GLenum name)
3204{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003205 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003206
3207 try
3208 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003209 gl::Context *context = gl::getContext();
3210
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003211 switch (name)
3212 {
3213 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003214 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003215 case GL_RENDERER:
3216 return (GLubyte*)"ANGLE";
3217 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003218 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003219 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003220 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003221 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003222 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003223 default:
3224 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3225 }
3226 }
3227 catch(std::bad_alloc&)
3228 {
3229 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3230 }
3231
3232 return NULL;
3233}
3234
3235void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3236{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003237 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003238
3239 try
3240 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003241 gl::Context *context = gl::getContext();
3242
3243 if (context)
3244 {
3245 gl::Texture *texture;
3246
3247 switch (target)
3248 {
3249 case GL_TEXTURE_2D:
3250 texture = context->getTexture2D();
3251 break;
3252 case GL_TEXTURE_CUBE_MAP:
3253 texture = context->getTextureCubeMap();
3254 break;
3255 default:
3256 return error(GL_INVALID_ENUM);
3257 }
3258
3259 switch (pname)
3260 {
3261 case GL_TEXTURE_MAG_FILTER:
3262 *params = (GLfloat)texture->getMagFilter();
3263 break;
3264 case GL_TEXTURE_MIN_FILTER:
3265 *params = (GLfloat)texture->getMinFilter();
3266 break;
3267 case GL_TEXTURE_WRAP_S:
3268 *params = (GLfloat)texture->getWrapS();
3269 break;
3270 case GL_TEXTURE_WRAP_T:
3271 *params = (GLfloat)texture->getWrapT();
3272 break;
3273 default:
3274 return error(GL_INVALID_ENUM);
3275 }
3276 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003277 }
3278 catch(std::bad_alloc&)
3279 {
3280 return error(GL_OUT_OF_MEMORY);
3281 }
3282}
3283
3284void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3285{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003286 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003287
3288 try
3289 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003290 gl::Context *context = gl::getContext();
3291
3292 if (context)
3293 {
3294 gl::Texture *texture;
3295
3296 switch (target)
3297 {
3298 case GL_TEXTURE_2D:
3299 texture = context->getTexture2D();
3300 break;
3301 case GL_TEXTURE_CUBE_MAP:
3302 texture = context->getTextureCubeMap();
3303 break;
3304 default:
3305 return error(GL_INVALID_ENUM);
3306 }
3307
3308 switch (pname)
3309 {
3310 case GL_TEXTURE_MAG_FILTER:
3311 *params = texture->getMagFilter();
3312 break;
3313 case GL_TEXTURE_MIN_FILTER:
3314 *params = texture->getMinFilter();
3315 break;
3316 case GL_TEXTURE_WRAP_S:
3317 *params = texture->getWrapS();
3318 break;
3319 case GL_TEXTURE_WRAP_T:
3320 *params = texture->getWrapT();
3321 break;
3322 default:
3323 return error(GL_INVALID_ENUM);
3324 }
3325 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003326 }
3327 catch(std::bad_alloc&)
3328 {
3329 return error(GL_OUT_OF_MEMORY);
3330 }
3331}
3332
3333void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3334{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003335 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003336
3337 try
3338 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003339 gl::Context *context = gl::getContext();
3340
3341 if (context)
3342 {
3343 if (program == 0)
3344 {
3345 return error(GL_INVALID_VALUE);
3346 }
3347
3348 gl::Program *programObject = context->getProgram(program);
3349
3350 if (!programObject || !programObject->isLinked())
3351 {
3352 return error(GL_INVALID_OPERATION);
3353 }
3354
3355 if (!programObject->getUniformfv(location, params))
3356 {
3357 return error(GL_INVALID_OPERATION);
3358 }
3359 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003360 }
3361 catch(std::bad_alloc&)
3362 {
3363 return error(GL_OUT_OF_MEMORY);
3364 }
3365}
3366
3367void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3368{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003369 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003370
3371 try
3372 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003373 gl::Context *context = gl::getContext();
3374
3375 if (context)
3376 {
3377 if (program == 0)
3378 {
3379 return error(GL_INVALID_VALUE);
3380 }
3381
3382 gl::Program *programObject = context->getProgram(program);
3383
3384 if (!programObject || !programObject->isLinked())
3385 {
3386 return error(GL_INVALID_OPERATION);
3387 }
3388
3389 if (!programObject)
3390 {
3391 return error(GL_INVALID_OPERATION);
3392 }
3393
3394 if (!programObject->getUniformiv(location, params))
3395 {
3396 return error(GL_INVALID_OPERATION);
3397 }
3398 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003399 }
3400 catch(std::bad_alloc&)
3401 {
3402 return error(GL_OUT_OF_MEMORY);
3403 }
3404}
3405
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003406int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003407{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003408 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003409
3410 try
3411 {
3412 gl::Context *context = gl::getContext();
3413
3414 if (strstr(name, "gl_") == name)
3415 {
3416 return -1;
3417 }
3418
3419 if (context)
3420 {
3421 gl::Program *programObject = context->getProgram(program);
3422
3423 if (!programObject)
3424 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003425 if (context->getShader(program))
3426 {
3427 return error(GL_INVALID_OPERATION, -1);
3428 }
3429 else
3430 {
3431 return error(GL_INVALID_VALUE, -1);
3432 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003433 }
3434
3435 if (!programObject->isLinked())
3436 {
3437 return error(GL_INVALID_OPERATION, -1);
3438 }
3439
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00003440 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003441 }
3442 }
3443 catch(std::bad_alloc&)
3444 {
3445 return error(GL_OUT_OF_MEMORY, -1);
3446 }
3447
3448 return -1;
3449}
3450
3451void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3452{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003453 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003454
3455 try
3456 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003457 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003458
daniel@transgaming.come0078962010-04-15 20:45:08 +00003459 if (context)
3460 {
3461 if (index >= gl::MAX_VERTEX_ATTRIBS)
3462 {
3463 return error(GL_INVALID_VALUE);
3464 }
3465
daniel@transgaming.com83921382011-01-08 05:46:00 +00003466 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003467
daniel@transgaming.come0078962010-04-15 20:45:08 +00003468 switch (pname)
3469 {
3470 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003471 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003472 break;
3473 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003474 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003475 break;
3476 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003477 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003478 break;
3479 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003480 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003481 break;
3482 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003483 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003484 break;
3485 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003486 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003487 break;
3488 case GL_CURRENT_VERTEX_ATTRIB:
3489 for (int i = 0; i < 4; ++i)
3490 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003491 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003492 }
3493 break;
3494 default: return error(GL_INVALID_ENUM);
3495 }
3496 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003497 }
3498 catch(std::bad_alloc&)
3499 {
3500 return error(GL_OUT_OF_MEMORY);
3501 }
3502}
3503
3504void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3505{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003506 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003507
3508 try
3509 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003510 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003511
daniel@transgaming.come0078962010-04-15 20:45:08 +00003512 if (context)
3513 {
3514 if (index >= gl::MAX_VERTEX_ATTRIBS)
3515 {
3516 return error(GL_INVALID_VALUE);
3517 }
3518
daniel@transgaming.com83921382011-01-08 05:46:00 +00003519 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003520
daniel@transgaming.come0078962010-04-15 20:45:08 +00003521 switch (pname)
3522 {
3523 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003524 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003525 break;
3526 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003527 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003528 break;
3529 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003530 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003531 break;
3532 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003533 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003534 break;
3535 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003536 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003537 break;
3538 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003539 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003540 break;
3541 case GL_CURRENT_VERTEX_ATTRIB:
3542 for (int i = 0; i < 4; ++i)
3543 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003544 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003545 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3546 }
3547 break;
3548 default: return error(GL_INVALID_ENUM);
3549 }
3550 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003551 }
3552 catch(std::bad_alloc&)
3553 {
3554 return error(GL_OUT_OF_MEMORY);
3555 }
3556}
3557
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003558void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003559{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003560 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003561
3562 try
3563 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003564 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003565
daniel@transgaming.come0078962010-04-15 20:45:08 +00003566 if (context)
3567 {
3568 if (index >= gl::MAX_VERTEX_ATTRIBS)
3569 {
3570 return error(GL_INVALID_VALUE);
3571 }
3572
3573 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3574 {
3575 return error(GL_INVALID_ENUM);
3576 }
3577
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003578 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003579 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003580 }
3581 catch(std::bad_alloc&)
3582 {
3583 return error(GL_OUT_OF_MEMORY);
3584 }
3585}
3586
3587void __stdcall glHint(GLenum target, GLenum mode)
3588{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003589 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003590
3591 try
3592 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003593 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003594 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003595 case GL_FASTEST:
3596 case GL_NICEST:
3597 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003598 break;
3599 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003600 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003601 }
3602
3603 gl::Context *context = gl::getContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003604 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003605 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003606 case GL_GENERATE_MIPMAP_HINT:
3607 if (context) context->setGenerateMipmapHint(mode);
3608 break;
3609 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3610 if (context) context->setFragmentShaderDerivativeHint(mode);
3611 break;
3612 default:
3613 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003614 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003615 }
3616 catch(std::bad_alloc&)
3617 {
3618 return error(GL_OUT_OF_MEMORY);
3619 }
3620}
3621
3622GLboolean __stdcall glIsBuffer(GLuint buffer)
3623{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003624 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003625
3626 try
3627 {
3628 gl::Context *context = gl::getContext();
3629
3630 if (context && buffer)
3631 {
3632 gl::Buffer *bufferObject = context->getBuffer(buffer);
3633
3634 if (bufferObject)
3635 {
3636 return GL_TRUE;
3637 }
3638 }
3639 }
3640 catch(std::bad_alloc&)
3641 {
3642 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3643 }
3644
3645 return GL_FALSE;
3646}
3647
3648GLboolean __stdcall glIsEnabled(GLenum cap)
3649{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003650 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003651
3652 try
3653 {
3654 gl::Context *context = gl::getContext();
3655
3656 if (context)
3657 {
3658 switch (cap)
3659 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003660 case GL_CULL_FACE: return context->isCullFaceEnabled();
3661 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3662 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3663 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3664 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3665 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3666 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3667 case GL_BLEND: return context->isBlendEnabled();
3668 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003669 default:
3670 return error(GL_INVALID_ENUM, false);
3671 }
3672 }
3673 }
3674 catch(std::bad_alloc&)
3675 {
3676 return error(GL_OUT_OF_MEMORY, false);
3677 }
3678
3679 return false;
3680}
3681
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003682GLboolean __stdcall glIsFenceNV(GLuint fence)
3683{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003684 TRACE("(GLuint fence = %d)", fence);
3685
3686 try
3687 {
3688 gl::Context *context = gl::getContext();
3689
3690 if (context)
3691 {
3692 gl::Fence *fenceObject = context->getFence(fence);
3693
3694 if (fenceObject == NULL)
3695 {
3696 return GL_FALSE;
3697 }
3698
3699 return fenceObject->isFence();
3700 }
3701 }
3702 catch(std::bad_alloc&)
3703 {
3704 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3705 }
3706
3707 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003708}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003709
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003710GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3711{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003712 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003713
3714 try
3715 {
3716 gl::Context *context = gl::getContext();
3717
3718 if (context && framebuffer)
3719 {
3720 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3721
3722 if (framebufferObject)
3723 {
3724 return GL_TRUE;
3725 }
3726 }
3727 }
3728 catch(std::bad_alloc&)
3729 {
3730 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3731 }
3732
3733 return GL_FALSE;
3734}
3735
3736GLboolean __stdcall glIsProgram(GLuint program)
3737{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003738 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003739
3740 try
3741 {
3742 gl::Context *context = gl::getContext();
3743
3744 if (context && program)
3745 {
3746 gl::Program *programObject = context->getProgram(program);
3747
3748 if (programObject)
3749 {
3750 return GL_TRUE;
3751 }
3752 }
3753 }
3754 catch(std::bad_alloc&)
3755 {
3756 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3757 }
3758
3759 return GL_FALSE;
3760}
3761
3762GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3763{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003764 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003765
3766 try
3767 {
3768 gl::Context *context = gl::getContext();
3769
3770 if (context && renderbuffer)
3771 {
3772 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3773
3774 if (renderbufferObject)
3775 {
3776 return GL_TRUE;
3777 }
3778 }
3779 }
3780 catch(std::bad_alloc&)
3781 {
3782 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3783 }
3784
3785 return GL_FALSE;
3786}
3787
3788GLboolean __stdcall glIsShader(GLuint shader)
3789{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003790 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003791
3792 try
3793 {
3794 gl::Context *context = gl::getContext();
3795
3796 if (context && shader)
3797 {
3798 gl::Shader *shaderObject = context->getShader(shader);
3799
3800 if (shaderObject)
3801 {
3802 return GL_TRUE;
3803 }
3804 }
3805 }
3806 catch(std::bad_alloc&)
3807 {
3808 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3809 }
3810
3811 return GL_FALSE;
3812}
3813
3814GLboolean __stdcall glIsTexture(GLuint texture)
3815{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003816 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003817
3818 try
3819 {
3820 gl::Context *context = gl::getContext();
3821
3822 if (context && texture)
3823 {
3824 gl::Texture *textureObject = context->getTexture(texture);
3825
3826 if (textureObject)
3827 {
3828 return GL_TRUE;
3829 }
3830 }
3831 }
3832 catch(std::bad_alloc&)
3833 {
3834 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3835 }
3836
3837 return GL_FALSE;
3838}
3839
3840void __stdcall glLineWidth(GLfloat width)
3841{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003842 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003843
3844 try
3845 {
3846 if (width <= 0.0f)
3847 {
3848 return error(GL_INVALID_VALUE);
3849 }
3850
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003851 gl::Context *context = gl::getContext();
3852
3853 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003854 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003855 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003856 }
3857 }
3858 catch(std::bad_alloc&)
3859 {
3860 return error(GL_OUT_OF_MEMORY);
3861 }
3862}
3863
3864void __stdcall glLinkProgram(GLuint program)
3865{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003866 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003867
3868 try
3869 {
3870 gl::Context *context = gl::getContext();
3871
3872 if (context)
3873 {
3874 gl::Program *programObject = context->getProgram(program);
3875
3876 if (!programObject)
3877 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003878 if (context->getShader(program))
3879 {
3880 return error(GL_INVALID_OPERATION);
3881 }
3882 else
3883 {
3884 return error(GL_INVALID_VALUE);
3885 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003886 }
3887
3888 programObject->link();
3889 }
3890 }
3891 catch(std::bad_alloc&)
3892 {
3893 return error(GL_OUT_OF_MEMORY);
3894 }
3895}
3896
3897void __stdcall glPixelStorei(GLenum pname, GLint param)
3898{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003899 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003900
3901 try
3902 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003903 gl::Context *context = gl::getContext();
3904
3905 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003906 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003907 switch (pname)
3908 {
3909 case GL_UNPACK_ALIGNMENT:
3910 if (param != 1 && param != 2 && param != 4 && param != 8)
3911 {
3912 return error(GL_INVALID_VALUE);
3913 }
3914
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003915 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003916 break;
3917
3918 case GL_PACK_ALIGNMENT:
3919 if (param != 1 && param != 2 && param != 4 && param != 8)
3920 {
3921 return error(GL_INVALID_VALUE);
3922 }
3923
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003924 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003925 break;
3926
3927 default:
3928 return error(GL_INVALID_ENUM);
3929 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003930 }
3931 }
3932 catch(std::bad_alloc&)
3933 {
3934 return error(GL_OUT_OF_MEMORY);
3935 }
3936}
3937
3938void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3939{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003940 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003941
3942 try
3943 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003944 gl::Context *context = gl::getContext();
3945
3946 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003947 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003948 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003949 }
3950 }
3951 catch(std::bad_alloc&)
3952 {
3953 return error(GL_OUT_OF_MEMORY);
3954 }
3955}
3956
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003957void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003958{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003959 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003960 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003961 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003962
3963 try
3964 {
3965 if (width < 0 || height < 0)
3966 {
3967 return error(GL_INVALID_VALUE);
3968 }
3969
3970 switch (format)
3971 {
3972 case GL_RGBA:
3973 switch (type)
3974 {
3975 case GL_UNSIGNED_BYTE:
3976 break;
3977 default:
3978 return error(GL_INVALID_OPERATION);
3979 }
3980 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003981 case GL_BGRA_EXT:
3982 switch (type)
3983 {
3984 case GL_UNSIGNED_BYTE:
3985 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3986 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3987 break;
3988 default:
3989 return error(GL_INVALID_OPERATION);
3990 }
3991 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003992 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3993 switch (type)
3994 {
3995 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3996 break;
3997 default:
3998 return error(GL_INVALID_OPERATION);
3999 }
4000 break;
4001 default:
4002 return error(GL_INVALID_OPERATION);
4003 }
4004
4005 gl::Context *context = gl::getContext();
4006
4007 if (context)
4008 {
4009 context->readPixels(x, y, width, height, format, type, pixels);
4010 }
4011 }
4012 catch(std::bad_alloc&)
4013 {
4014 return error(GL_OUT_OF_MEMORY);
4015 }
4016}
4017
4018void __stdcall glReleaseShaderCompiler(void)
4019{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004020 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004021
4022 try
4023 {
4024 gl::Shader::releaseCompiler();
4025 }
4026 catch(std::bad_alloc&)
4027 {
4028 return error(GL_OUT_OF_MEMORY);
4029 }
4030}
4031
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004032void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004033{
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004034 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4035 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004036
4037 try
4038 {
4039 switch (target)
4040 {
4041 case GL_RENDERBUFFER:
4042 break;
4043 default:
4044 return error(GL_INVALID_ENUM);
4045 }
4046
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004047 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004048 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004049 return error(GL_INVALID_ENUM);
4050 }
4051
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004052 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004053 {
4054 return error(GL_INVALID_VALUE);
4055 }
4056
4057 gl::Context *context = gl::getContext();
4058
4059 if (context)
4060 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004061 if (width > context->getMaximumRenderbufferDimension() ||
4062 height > context->getMaximumRenderbufferDimension() ||
4063 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004064 {
4065 return error(GL_INVALID_VALUE);
4066 }
4067
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004068 GLuint handle = context->getRenderbufferHandle();
4069 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004070 {
4071 return error(GL_INVALID_OPERATION);
4072 }
4073
4074 switch (internalformat)
4075 {
4076 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004077 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004078 break;
4079 case GL_RGBA4:
4080 case GL_RGB5_A1:
4081 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004082 case GL_RGB8_OES:
4083 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004084 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004085 break;
4086 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004087 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004088 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004089 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004090 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004091 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004092 default:
4093 return error(GL_INVALID_ENUM);
4094 }
4095 }
4096 }
4097 catch(std::bad_alloc&)
4098 {
4099 return error(GL_OUT_OF_MEMORY);
4100 }
4101}
4102
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004103void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4104{
4105 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4106}
4107
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004108void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4109{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004110 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004111
4112 try
4113 {
4114 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004115
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004116 if (context)
4117 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004118 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004119 }
4120 }
4121 catch(std::bad_alloc&)
4122 {
4123 return error(GL_OUT_OF_MEMORY);
4124 }
4125}
4126
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004127void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4128{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004129 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
4130
4131 try
4132 {
4133 if (condition != GL_ALL_COMPLETED_NV)
4134 {
4135 return error(GL_INVALID_ENUM);
4136 }
4137
4138 gl::Context *context = gl::getContext();
4139
4140 if (context)
4141 {
4142 gl::Fence *fenceObject = context->getFence(fence);
4143
4144 if (fenceObject == NULL)
4145 {
4146 return error(GL_INVALID_OPERATION);
4147 }
4148
4149 fenceObject->setFence(condition);
4150 }
4151 }
4152 catch(std::bad_alloc&)
4153 {
4154 return error(GL_OUT_OF_MEMORY);
4155 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004156}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004157
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004158void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4159{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004160 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004161
4162 try
4163 {
4164 if (width < 0 || height < 0)
4165 {
4166 return error(GL_INVALID_VALUE);
4167 }
4168
4169 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004170
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004171 if (context)
4172 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004173 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004174 }
4175 }
4176 catch(std::bad_alloc&)
4177 {
4178 return error(GL_OUT_OF_MEMORY);
4179 }
4180}
4181
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004182void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004183{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004184 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004185 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004186 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004187
4188 try
4189 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004190 // No binary shader formats are supported.
4191 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004192 }
4193 catch(std::bad_alloc&)
4194 {
4195 return error(GL_OUT_OF_MEMORY);
4196 }
4197}
4198
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004199void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004200{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004201 TRACE("(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 +00004202 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004203
4204 try
4205 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004206 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004207 {
4208 return error(GL_INVALID_VALUE);
4209 }
4210
4211 gl::Context *context = gl::getContext();
4212
4213 if (context)
4214 {
4215 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004216
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004217 if (!shaderObject)
4218 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004219 if (context->getProgram(shader))
4220 {
4221 return error(GL_INVALID_OPERATION);
4222 }
4223 else
4224 {
4225 return error(GL_INVALID_VALUE);
4226 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004227 }
4228
4229 shaderObject->setSource(count, string, length);
4230 }
4231 }
4232 catch(std::bad_alloc&)
4233 {
4234 return error(GL_OUT_OF_MEMORY);
4235 }
4236}
4237
4238void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4239{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004240 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004241}
4242
4243void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4244{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004245 TRACE("(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 +00004246
4247 try
4248 {
4249 switch (face)
4250 {
4251 case GL_FRONT:
4252 case GL_BACK:
4253 case GL_FRONT_AND_BACK:
4254 break;
4255 default:
4256 return error(GL_INVALID_ENUM);
4257 }
4258
4259 switch (func)
4260 {
4261 case GL_NEVER:
4262 case GL_ALWAYS:
4263 case GL_LESS:
4264 case GL_LEQUAL:
4265 case GL_EQUAL:
4266 case GL_GEQUAL:
4267 case GL_GREATER:
4268 case GL_NOTEQUAL:
4269 break;
4270 default:
4271 return error(GL_INVALID_ENUM);
4272 }
4273
4274 gl::Context *context = gl::getContext();
4275
4276 if (context)
4277 {
4278 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4279 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004280 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004281 }
4282
4283 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4284 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004285 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004286 }
4287 }
4288 }
4289 catch(std::bad_alloc&)
4290 {
4291 return error(GL_OUT_OF_MEMORY);
4292 }
4293}
4294
4295void __stdcall glStencilMask(GLuint mask)
4296{
4297 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4298}
4299
4300void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4301{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004302 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004303
4304 try
4305 {
4306 switch (face)
4307 {
4308 case GL_FRONT:
4309 case GL_BACK:
4310 case GL_FRONT_AND_BACK:
4311 break;
4312 default:
4313 return error(GL_INVALID_ENUM);
4314 }
4315
4316 gl::Context *context = gl::getContext();
4317
4318 if (context)
4319 {
4320 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4321 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004322 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004323 }
4324
4325 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4326 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004327 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004328 }
4329 }
4330 }
4331 catch(std::bad_alloc&)
4332 {
4333 return error(GL_OUT_OF_MEMORY);
4334 }
4335}
4336
4337void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4338{
4339 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4340}
4341
4342void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4343{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004344 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4345 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004346
4347 try
4348 {
4349 switch (face)
4350 {
4351 case GL_FRONT:
4352 case GL_BACK:
4353 case GL_FRONT_AND_BACK:
4354 break;
4355 default:
4356 return error(GL_INVALID_ENUM);
4357 }
4358
4359 switch (fail)
4360 {
4361 case GL_ZERO:
4362 case GL_KEEP:
4363 case GL_REPLACE:
4364 case GL_INCR:
4365 case GL_DECR:
4366 case GL_INVERT:
4367 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004368 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004369 break;
4370 default:
4371 return error(GL_INVALID_ENUM);
4372 }
4373
4374 switch (zfail)
4375 {
4376 case GL_ZERO:
4377 case GL_KEEP:
4378 case GL_REPLACE:
4379 case GL_INCR:
4380 case GL_DECR:
4381 case GL_INVERT:
4382 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004383 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004384 break;
4385 default:
4386 return error(GL_INVALID_ENUM);
4387 }
4388
4389 switch (zpass)
4390 {
4391 case GL_ZERO:
4392 case GL_KEEP:
4393 case GL_REPLACE:
4394 case GL_INCR:
4395 case GL_DECR:
4396 case GL_INVERT:
4397 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004398 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004399 break;
4400 default:
4401 return error(GL_INVALID_ENUM);
4402 }
4403
4404 gl::Context *context = gl::getContext();
4405
4406 if (context)
4407 {
4408 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4409 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004410 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004411 }
4412
4413 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4414 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004415 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004416 }
4417 }
4418 }
4419 catch(std::bad_alloc&)
4420 {
4421 return error(GL_OUT_OF_MEMORY);
4422 }
4423}
4424
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004425GLboolean __stdcall glTestFenceNV(GLuint fence)
4426{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004427 TRACE("(GLuint fence = %d)", fence);
4428
4429 try
4430 {
4431 gl::Context *context = gl::getContext();
4432
4433 if (context)
4434 {
4435 gl::Fence *fenceObject = context->getFence(fence);
4436
4437 if (fenceObject == NULL)
4438 {
4439 return error(GL_INVALID_OPERATION, GL_TRUE);
4440 }
4441
4442 return fenceObject->testFence();
4443 }
4444 }
4445 catch(std::bad_alloc&)
4446 {
4447 error(GL_OUT_OF_MEMORY);
4448 }
4449
4450 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004451}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004452
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004453void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4454 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004455{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004456 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004457 "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 +00004458 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004459
4460 try
4461 {
4462 if (level < 0 || width < 0 || height < 0)
4463 {
4464 return error(GL_INVALID_VALUE);
4465 }
4466
4467 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
4468 {
4469 return error(GL_INVALID_VALUE);
4470 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004471
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004472 if (internalformat != format)
4473 {
4474 return error(GL_INVALID_OPERATION);
4475 }
4476
4477 switch (internalformat)
4478 {
4479 case GL_ALPHA:
4480 case GL_LUMINANCE:
4481 case GL_LUMINANCE_ALPHA:
4482 switch (type)
4483 {
4484 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004485 case GL_FLOAT:
4486 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004487 break;
4488 default:
4489 return error(GL_INVALID_ENUM);
4490 }
4491 break;
4492 case GL_RGB:
4493 switch (type)
4494 {
4495 case GL_UNSIGNED_BYTE:
4496 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004497 case GL_FLOAT:
4498 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004499 break;
4500 default:
4501 return error(GL_INVALID_ENUM);
4502 }
4503 break;
4504 case GL_RGBA:
4505 switch (type)
4506 {
4507 case GL_UNSIGNED_BYTE:
4508 case GL_UNSIGNED_SHORT_4_4_4_4:
4509 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004510 case GL_FLOAT:
4511 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004512 break;
4513 default:
4514 return error(GL_INVALID_ENUM);
4515 }
4516 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004517 case GL_BGRA_EXT:
4518 switch (type)
4519 {
4520 case GL_UNSIGNED_BYTE:
4521 break;
4522 default:
4523 return error(GL_INVALID_ENUM);
4524 }
4525 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004526 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4527 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4528 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004529 default:
4530 return error(GL_INVALID_VALUE);
4531 }
4532
4533 if (border != 0)
4534 {
4535 return error(GL_INVALID_VALUE);
4536 }
4537
4538 gl::Context *context = gl::getContext();
4539
4540 if (context)
4541 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004542 switch (target)
4543 {
4544 case GL_TEXTURE_2D:
4545 if (width > (context->getMaximumTextureDimension() >> level) ||
4546 height > (context->getMaximumTextureDimension() >> level))
4547 {
4548 return error(GL_INVALID_VALUE);
4549 }
4550 break;
4551 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4552 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4553 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4554 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4555 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4556 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4557 if (width != height)
4558 {
4559 return error(GL_INVALID_VALUE);
4560 }
4561
4562 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4563 height > (context->getMaximumCubeTextureDimension() >> level))
4564 {
4565 return error(GL_INVALID_VALUE);
4566 }
4567 break;
4568 default:
4569 return error(GL_INVALID_ENUM);
4570 }
4571
daniel@transgaming.com01868132010-08-24 19:21:17 +00004572 if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4573 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
4574 {
4575 if (context->supportsCompressedTextures())
4576 {
4577 return error(GL_INVALID_OPERATION);
4578 }
4579 else
4580 {
4581 return error(GL_INVALID_ENUM);
4582 }
4583 }
4584
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004585 if (type == GL_FLOAT)
4586 {
4587 if (!context->supportsFloatTextures())
4588 {
4589 return error(GL_INVALID_ENUM);
4590 }
4591 }
4592 else if (type == GL_HALF_FLOAT_OES)
4593 {
4594 if (!context->supportsHalfFloatTextures())
4595 {
4596 return error(GL_INVALID_ENUM);
4597 }
4598 }
4599
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004600 if (target == GL_TEXTURE_2D)
4601 {
4602 gl::Texture2D *texture = context->getTexture2D();
4603
4604 if (!texture)
4605 {
4606 return error(GL_INVALID_OPERATION);
4607 }
4608
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004609 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004610 }
4611 else
4612 {
4613 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4614
4615 if (!texture)
4616 {
4617 return error(GL_INVALID_OPERATION);
4618 }
4619
4620 switch (target)
4621 {
4622 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004623 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004624 break;
4625 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004626 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004627 break;
4628 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004629 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004630 break;
4631 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004632 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004633 break;
4634 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004635 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004636 break;
4637 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004638 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004639 break;
4640 default: UNREACHABLE();
4641 }
4642 }
4643 }
4644 }
4645 catch(std::bad_alloc&)
4646 {
4647 return error(GL_OUT_OF_MEMORY);
4648 }
4649}
4650
4651void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4652{
4653 glTexParameteri(target, pname, (GLint)param);
4654}
4655
4656void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4657{
4658 glTexParameteri(target, pname, (GLint)*params);
4659}
4660
4661void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4662{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004663 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004664
4665 try
4666 {
4667 gl::Context *context = gl::getContext();
4668
4669 if (context)
4670 {
4671 gl::Texture *texture;
4672
4673 switch (target)
4674 {
4675 case GL_TEXTURE_2D:
4676 texture = context->getTexture2D();
4677 break;
4678 case GL_TEXTURE_CUBE_MAP:
4679 texture = context->getTextureCubeMap();
4680 break;
4681 default:
4682 return error(GL_INVALID_ENUM);
4683 }
4684
4685 switch (pname)
4686 {
4687 case GL_TEXTURE_WRAP_S:
4688 if (!texture->setWrapS((GLenum)param))
4689 {
4690 return error(GL_INVALID_ENUM);
4691 }
4692 break;
4693 case GL_TEXTURE_WRAP_T:
4694 if (!texture->setWrapT((GLenum)param))
4695 {
4696 return error(GL_INVALID_ENUM);
4697 }
4698 break;
4699 case GL_TEXTURE_MIN_FILTER:
4700 if (!texture->setMinFilter((GLenum)param))
4701 {
4702 return error(GL_INVALID_ENUM);
4703 }
4704 break;
4705 case GL_TEXTURE_MAG_FILTER:
4706 if (!texture->setMagFilter((GLenum)param))
4707 {
4708 return error(GL_INVALID_ENUM);
4709 }
4710 break;
4711 default:
4712 return error(GL_INVALID_ENUM);
4713 }
4714 }
4715 }
4716 catch(std::bad_alloc&)
4717 {
4718 return error(GL_OUT_OF_MEMORY);
4719 }
4720}
4721
4722void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4723{
4724 glTexParameteri(target, pname, *params);
4725}
4726
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004727void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4728 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004729{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004730 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4731 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004732 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004733 target, level, xoffset, yoffset, width, height, format, type, pixels);
4734
4735 try
4736 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004737 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004738 {
4739 return error(GL_INVALID_ENUM);
4740 }
4741
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004742 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004743 {
4744 return error(GL_INVALID_VALUE);
4745 }
4746
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004747 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4748 {
4749 return error(GL_INVALID_VALUE);
4750 }
4751
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004752 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004753 {
4754 return error(GL_INVALID_ENUM);
4755 }
4756
4757 if (width == 0 || height == 0 || pixels == NULL)
4758 {
4759 return;
4760 }
4761
4762 gl::Context *context = gl::getContext();
4763
4764 if (context)
4765 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004766 if (level > context->getMaximumTextureLevel())
4767 {
4768 return error(GL_INVALID_VALUE);
4769 }
4770
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004771 if (format == GL_FLOAT)
4772 {
4773 if (!context->supportsFloatTextures())
4774 {
4775 return error(GL_INVALID_ENUM);
4776 }
4777 }
4778 else if (format == GL_HALF_FLOAT_OES)
4779 {
4780 if (!context->supportsHalfFloatTextures())
4781 {
4782 return error(GL_INVALID_ENUM);
4783 }
4784 }
4785
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004786 if (target == GL_TEXTURE_2D)
4787 {
4788 gl::Texture2D *texture = context->getTexture2D();
4789
4790 if (!texture)
4791 {
4792 return error(GL_INVALID_OPERATION);
4793 }
4794
daniel@transgaming.com01868132010-08-24 19:21:17 +00004795 if (texture->isCompressed())
4796 {
4797 return error(GL_INVALID_OPERATION);
4798 }
4799
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004800 if (format != texture->getFormat())
4801 {
4802 return error(GL_INVALID_OPERATION);
4803 }
4804
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004805 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004806 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004807 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004808 {
4809 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4810
4811 if (!texture)
4812 {
4813 return error(GL_INVALID_OPERATION);
4814 }
4815
daniel@transgaming.com01868132010-08-24 19:21:17 +00004816 if (texture->isCompressed())
4817 {
4818 return error(GL_INVALID_OPERATION);
4819 }
4820
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004821 if (format != texture->getFormat())
4822 {
4823 return error(GL_INVALID_OPERATION);
4824 }
4825
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004826 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004827 }
4828 else
4829 {
4830 UNREACHABLE();
4831 }
4832 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004833 }
4834 catch(std::bad_alloc&)
4835 {
4836 return error(GL_OUT_OF_MEMORY);
4837 }
4838}
4839
4840void __stdcall glUniform1f(GLint location, GLfloat x)
4841{
4842 glUniform1fv(location, 1, &x);
4843}
4844
4845void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4846{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004847 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004848
4849 try
4850 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004851 if (count < 0)
4852 {
4853 return error(GL_INVALID_VALUE);
4854 }
4855
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004856 if (location == -1)
4857 {
4858 return;
4859 }
4860
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004861 gl::Context *context = gl::getContext();
4862
4863 if (context)
4864 {
4865 gl::Program *program = context->getCurrentProgram();
4866
4867 if (!program)
4868 {
4869 return error(GL_INVALID_OPERATION);
4870 }
4871
4872 if (!program->setUniform1fv(location, count, v))
4873 {
4874 return error(GL_INVALID_OPERATION);
4875 }
4876 }
4877 }
4878 catch(std::bad_alloc&)
4879 {
4880 return error(GL_OUT_OF_MEMORY);
4881 }
4882}
4883
4884void __stdcall glUniform1i(GLint location, GLint x)
4885{
4886 glUniform1iv(location, 1, &x);
4887}
4888
4889void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4890{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004891 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004892
4893 try
4894 {
4895 if (count < 0)
4896 {
4897 return error(GL_INVALID_VALUE);
4898 }
4899
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004900 if (location == -1)
4901 {
4902 return;
4903 }
4904
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004905 gl::Context *context = gl::getContext();
4906
4907 if (context)
4908 {
4909 gl::Program *program = context->getCurrentProgram();
4910
4911 if (!program)
4912 {
4913 return error(GL_INVALID_OPERATION);
4914 }
4915
4916 if (!program->setUniform1iv(location, count, v))
4917 {
4918 return error(GL_INVALID_OPERATION);
4919 }
4920 }
4921 }
4922 catch(std::bad_alloc&)
4923 {
4924 return error(GL_OUT_OF_MEMORY);
4925 }
4926}
4927
4928void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4929{
4930 GLfloat xy[2] = {x, y};
4931
4932 glUniform2fv(location, 1, (GLfloat*)&xy);
4933}
4934
4935void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4936{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004937 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004938
4939 try
4940 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004941 if (count < 0)
4942 {
4943 return error(GL_INVALID_VALUE);
4944 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004945
4946 if (location == -1)
4947 {
4948 return;
4949 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004950
4951 gl::Context *context = gl::getContext();
4952
4953 if (context)
4954 {
4955 gl::Program *program = context->getCurrentProgram();
4956
4957 if (!program)
4958 {
4959 return error(GL_INVALID_OPERATION);
4960 }
4961
4962 if (!program->setUniform2fv(location, count, v))
4963 {
4964 return error(GL_INVALID_OPERATION);
4965 }
4966 }
4967 }
4968 catch(std::bad_alloc&)
4969 {
4970 return error(GL_OUT_OF_MEMORY);
4971 }
4972}
4973
4974void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4975{
4976 GLint xy[4] = {x, y};
4977
4978 glUniform2iv(location, 1, (GLint*)&xy);
4979}
4980
4981void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4982{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004983 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004984
4985 try
4986 {
4987 if (count < 0)
4988 {
4989 return error(GL_INVALID_VALUE);
4990 }
4991
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004992 if (location == -1)
4993 {
4994 return;
4995 }
4996
4997 gl::Context *context = gl::getContext();
4998
4999 if (context)
5000 {
5001 gl::Program *program = context->getCurrentProgram();
5002
5003 if (!program)
5004 {
5005 return error(GL_INVALID_OPERATION);
5006 }
5007
5008 if (!program->setUniform2iv(location, count, v))
5009 {
5010 return error(GL_INVALID_OPERATION);
5011 }
5012 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005013 }
5014 catch(std::bad_alloc&)
5015 {
5016 return error(GL_OUT_OF_MEMORY);
5017 }
5018}
5019
5020void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5021{
5022 GLfloat xyz[3] = {x, y, z};
5023
5024 glUniform3fv(location, 1, (GLfloat*)&xyz);
5025}
5026
5027void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5028{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005029 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005030
5031 try
5032 {
5033 if (count < 0)
5034 {
5035 return error(GL_INVALID_VALUE);
5036 }
5037
5038 if (location == -1)
5039 {
5040 return;
5041 }
5042
5043 gl::Context *context = gl::getContext();
5044
5045 if (context)
5046 {
5047 gl::Program *program = context->getCurrentProgram();
5048
5049 if (!program)
5050 {
5051 return error(GL_INVALID_OPERATION);
5052 }
5053
5054 if (!program->setUniform3fv(location, count, v))
5055 {
5056 return error(GL_INVALID_OPERATION);
5057 }
5058 }
5059 }
5060 catch(std::bad_alloc&)
5061 {
5062 return error(GL_OUT_OF_MEMORY);
5063 }
5064}
5065
5066void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5067{
5068 GLint xyz[3] = {x, y, z};
5069
5070 glUniform3iv(location, 1, (GLint*)&xyz);
5071}
5072
5073void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5074{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005075 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005076
5077 try
5078 {
5079 if (count < 0)
5080 {
5081 return error(GL_INVALID_VALUE);
5082 }
5083
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005084 if (location == -1)
5085 {
5086 return;
5087 }
5088
5089 gl::Context *context = gl::getContext();
5090
5091 if (context)
5092 {
5093 gl::Program *program = context->getCurrentProgram();
5094
5095 if (!program)
5096 {
5097 return error(GL_INVALID_OPERATION);
5098 }
5099
5100 if (!program->setUniform3iv(location, count, v))
5101 {
5102 return error(GL_INVALID_OPERATION);
5103 }
5104 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005105 }
5106 catch(std::bad_alloc&)
5107 {
5108 return error(GL_OUT_OF_MEMORY);
5109 }
5110}
5111
5112void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5113{
5114 GLfloat xyzw[4] = {x, y, z, w};
5115
5116 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5117}
5118
5119void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5120{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005121 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005122
5123 try
5124 {
5125 if (count < 0)
5126 {
5127 return error(GL_INVALID_VALUE);
5128 }
5129
5130 if (location == -1)
5131 {
5132 return;
5133 }
5134
5135 gl::Context *context = gl::getContext();
5136
5137 if (context)
5138 {
5139 gl::Program *program = context->getCurrentProgram();
5140
5141 if (!program)
5142 {
5143 return error(GL_INVALID_OPERATION);
5144 }
5145
5146 if (!program->setUniform4fv(location, count, v))
5147 {
5148 return error(GL_INVALID_OPERATION);
5149 }
5150 }
5151 }
5152 catch(std::bad_alloc&)
5153 {
5154 return error(GL_OUT_OF_MEMORY);
5155 }
5156}
5157
5158void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5159{
5160 GLint xyzw[4] = {x, y, z, w};
5161
5162 glUniform4iv(location, 1, (GLint*)&xyzw);
5163}
5164
5165void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5166{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005167 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005168
5169 try
5170 {
5171 if (count < 0)
5172 {
5173 return error(GL_INVALID_VALUE);
5174 }
5175
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005176 if (location == -1)
5177 {
5178 return;
5179 }
5180
5181 gl::Context *context = gl::getContext();
5182
5183 if (context)
5184 {
5185 gl::Program *program = context->getCurrentProgram();
5186
5187 if (!program)
5188 {
5189 return error(GL_INVALID_OPERATION);
5190 }
5191
5192 if (!program->setUniform4iv(location, count, v))
5193 {
5194 return error(GL_INVALID_OPERATION);
5195 }
5196 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005197 }
5198 catch(std::bad_alloc&)
5199 {
5200 return error(GL_OUT_OF_MEMORY);
5201 }
5202}
5203
5204void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5205{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005206 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5207 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005208
5209 try
5210 {
5211 if (count < 0 || transpose != GL_FALSE)
5212 {
5213 return error(GL_INVALID_VALUE);
5214 }
5215
5216 if (location == -1)
5217 {
5218 return;
5219 }
5220
5221 gl::Context *context = gl::getContext();
5222
5223 if (context)
5224 {
5225 gl::Program *program = context->getCurrentProgram();
5226
5227 if (!program)
5228 {
5229 return error(GL_INVALID_OPERATION);
5230 }
5231
5232 if (!program->setUniformMatrix2fv(location, count, value))
5233 {
5234 return error(GL_INVALID_OPERATION);
5235 }
5236 }
5237 }
5238 catch(std::bad_alloc&)
5239 {
5240 return error(GL_OUT_OF_MEMORY);
5241 }
5242}
5243
5244void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5245{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005246 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5247 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005248
5249 try
5250 {
5251 if (count < 0 || transpose != GL_FALSE)
5252 {
5253 return error(GL_INVALID_VALUE);
5254 }
5255
5256 if (location == -1)
5257 {
5258 return;
5259 }
5260
5261 gl::Context *context = gl::getContext();
5262
5263 if (context)
5264 {
5265 gl::Program *program = context->getCurrentProgram();
5266
5267 if (!program)
5268 {
5269 return error(GL_INVALID_OPERATION);
5270 }
5271
5272 if (!program->setUniformMatrix3fv(location, count, value))
5273 {
5274 return error(GL_INVALID_OPERATION);
5275 }
5276 }
5277 }
5278 catch(std::bad_alloc&)
5279 {
5280 return error(GL_OUT_OF_MEMORY);
5281 }
5282}
5283
5284void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5285{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005286 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5287 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005288
5289 try
5290 {
5291 if (count < 0 || transpose != GL_FALSE)
5292 {
5293 return error(GL_INVALID_VALUE);
5294 }
5295
5296 if (location == -1)
5297 {
5298 return;
5299 }
5300
5301 gl::Context *context = gl::getContext();
5302
5303 if (context)
5304 {
5305 gl::Program *program = context->getCurrentProgram();
5306
5307 if (!program)
5308 {
5309 return error(GL_INVALID_OPERATION);
5310 }
5311
5312 if (!program->setUniformMatrix4fv(location, count, value))
5313 {
5314 return error(GL_INVALID_OPERATION);
5315 }
5316 }
5317 }
5318 catch(std::bad_alloc&)
5319 {
5320 return error(GL_OUT_OF_MEMORY);
5321 }
5322}
5323
5324void __stdcall glUseProgram(GLuint program)
5325{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005326 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005327
5328 try
5329 {
5330 gl::Context *context = gl::getContext();
5331
5332 if (context)
5333 {
5334 gl::Program *programObject = context->getProgram(program);
5335
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005336 if (!programObject && program != 0)
5337 {
5338 if (context->getShader(program))
5339 {
5340 return error(GL_INVALID_OPERATION);
5341 }
5342 else
5343 {
5344 return error(GL_INVALID_VALUE);
5345 }
5346 }
5347
5348 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005349 {
5350 return error(GL_INVALID_OPERATION);
5351 }
5352
5353 context->useProgram(program);
5354 }
5355 }
5356 catch(std::bad_alloc&)
5357 {
5358 return error(GL_OUT_OF_MEMORY);
5359 }
5360}
5361
5362void __stdcall glValidateProgram(GLuint program)
5363{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005364 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005365
5366 try
5367 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005368 gl::Context *context = gl::getContext();
5369
5370 if (context)
5371 {
5372 gl::Program *programObject = context->getProgram(program);
5373
5374 if (!programObject)
5375 {
5376 if (context->getShader(program))
5377 {
5378 return error(GL_INVALID_OPERATION);
5379 }
5380 else
5381 {
5382 return error(GL_INVALID_VALUE);
5383 }
5384 }
5385
5386 programObject->validate();
5387 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005388 }
5389 catch(std::bad_alloc&)
5390 {
5391 return error(GL_OUT_OF_MEMORY);
5392 }
5393}
5394
5395void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5396{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005397 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005398
5399 try
5400 {
5401 if (index >= gl::MAX_VERTEX_ATTRIBS)
5402 {
5403 return error(GL_INVALID_VALUE);
5404 }
5405
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005406 gl::Context *context = gl::getContext();
5407
5408 if (context)
5409 {
5410 GLfloat vals[4] = { x, 0, 0, 1 };
5411 context->setVertexAttrib(index, vals);
5412 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005413 }
5414 catch(std::bad_alloc&)
5415 {
5416 return error(GL_OUT_OF_MEMORY);
5417 }
5418}
5419
5420void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5421{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005422 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005423
5424 try
5425 {
5426 if (index >= gl::MAX_VERTEX_ATTRIBS)
5427 {
5428 return error(GL_INVALID_VALUE);
5429 }
5430
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005431 gl::Context *context = gl::getContext();
5432
5433 if (context)
5434 {
5435 GLfloat vals[4] = { values[0], 0, 0, 1 };
5436 context->setVertexAttrib(index, vals);
5437 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005438 }
5439 catch(std::bad_alloc&)
5440 {
5441 return error(GL_OUT_OF_MEMORY);
5442 }
5443}
5444
5445void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5446{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005447 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005448
5449 try
5450 {
5451 if (index >= gl::MAX_VERTEX_ATTRIBS)
5452 {
5453 return error(GL_INVALID_VALUE);
5454 }
5455
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005456 gl::Context *context = gl::getContext();
5457
5458 if (context)
5459 {
5460 GLfloat vals[4] = { x, y, 0, 1 };
5461 context->setVertexAttrib(index, vals);
5462 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005463 }
5464 catch(std::bad_alloc&)
5465 {
5466 return error(GL_OUT_OF_MEMORY);
5467 }
5468}
5469
5470void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5471{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005472 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005473
5474 try
5475 {
5476 if (index >= gl::MAX_VERTEX_ATTRIBS)
5477 {
5478 return error(GL_INVALID_VALUE);
5479 }
5480
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005481 gl::Context *context = gl::getContext();
5482
5483 if (context)
5484 {
5485 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5486 context->setVertexAttrib(index, vals);
5487 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005488 }
5489 catch(std::bad_alloc&)
5490 {
5491 return error(GL_OUT_OF_MEMORY);
5492 }
5493}
5494
5495void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5496{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005497 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005498
5499 try
5500 {
5501 if (index >= gl::MAX_VERTEX_ATTRIBS)
5502 {
5503 return error(GL_INVALID_VALUE);
5504 }
5505
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005506 gl::Context *context = gl::getContext();
5507
5508 if (context)
5509 {
5510 GLfloat vals[4] = { x, y, z, 1 };
5511 context->setVertexAttrib(index, vals);
5512 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005513 }
5514 catch(std::bad_alloc&)
5515 {
5516 return error(GL_OUT_OF_MEMORY);
5517 }
5518}
5519
5520void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5521{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005522 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005523
5524 try
5525 {
5526 if (index >= gl::MAX_VERTEX_ATTRIBS)
5527 {
5528 return error(GL_INVALID_VALUE);
5529 }
5530
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005531 gl::Context *context = gl::getContext();
5532
5533 if (context)
5534 {
5535 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5536 context->setVertexAttrib(index, vals);
5537 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005538 }
5539 catch(std::bad_alloc&)
5540 {
5541 return error(GL_OUT_OF_MEMORY);
5542 }
5543}
5544
5545void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5546{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005547 TRACE("(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 +00005548
5549 try
5550 {
5551 if (index >= gl::MAX_VERTEX_ATTRIBS)
5552 {
5553 return error(GL_INVALID_VALUE);
5554 }
5555
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005556 gl::Context *context = gl::getContext();
5557
5558 if (context)
5559 {
5560 GLfloat vals[4] = { x, y, z, w };
5561 context->setVertexAttrib(index, vals);
5562 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005563 }
5564 catch(std::bad_alloc&)
5565 {
5566 return error(GL_OUT_OF_MEMORY);
5567 }
5568}
5569
5570void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5571{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005572 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005573
5574 try
5575 {
5576 if (index >= gl::MAX_VERTEX_ATTRIBS)
5577 {
5578 return error(GL_INVALID_VALUE);
5579 }
5580
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005581 gl::Context *context = gl::getContext();
5582
5583 if (context)
5584 {
5585 context->setVertexAttrib(index, values);
5586 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005587 }
5588 catch(std::bad_alloc&)
5589 {
5590 return error(GL_OUT_OF_MEMORY);
5591 }
5592}
5593
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005594void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005595{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005596 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005597 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005598 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005599
5600 try
5601 {
5602 if (index >= gl::MAX_VERTEX_ATTRIBS)
5603 {
5604 return error(GL_INVALID_VALUE);
5605 }
5606
5607 if (size < 1 || size > 4)
5608 {
5609 return error(GL_INVALID_VALUE);
5610 }
5611
5612 switch (type)
5613 {
5614 case GL_BYTE:
5615 case GL_UNSIGNED_BYTE:
5616 case GL_SHORT:
5617 case GL_UNSIGNED_SHORT:
5618 case GL_FIXED:
5619 case GL_FLOAT:
5620 break;
5621 default:
5622 return error(GL_INVALID_ENUM);
5623 }
5624
5625 if (stride < 0)
5626 {
5627 return error(GL_INVALID_VALUE);
5628 }
5629
5630 gl::Context *context = gl::getContext();
5631
5632 if (context)
5633 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005634 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005635 }
5636 }
5637 catch(std::bad_alloc&)
5638 {
5639 return error(GL_OUT_OF_MEMORY);
5640 }
5641}
5642
5643void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5644{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005645 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005646
5647 try
5648 {
5649 if (width < 0 || height < 0)
5650 {
5651 return error(GL_INVALID_VALUE);
5652 }
5653
5654 gl::Context *context = gl::getContext();
5655
5656 if (context)
5657 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005658 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005659 }
5660 }
5661 catch(std::bad_alloc&)
5662 {
5663 return error(GL_OUT_OF_MEMORY);
5664 }
5665}
5666
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005667void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5668 GLbitfield mask, GLenum filter)
5669{
5670 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5671 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5672 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5673 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5674
5675 try
5676 {
5677 switch (filter)
5678 {
5679 case GL_NEAREST:
5680 break;
5681 default:
5682 return error(GL_INVALID_ENUM);
5683 }
5684
5685 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5686 {
5687 return error(GL_INVALID_VALUE);
5688 }
5689
5690 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5691 {
5692 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5693 return error(GL_INVALID_OPERATION);
5694 }
5695
5696 gl::Context *context = gl::getContext();
5697
5698 if (context)
5699 {
5700 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5701 {
5702 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5703 return error(GL_INVALID_OPERATION);
5704 }
5705
5706 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5707 }
5708 }
5709 catch(std::bad_alloc&)
5710 {
5711 return error(GL_OUT_OF_MEMORY);
5712 }
5713}
5714
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005715void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5716 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005717{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005718 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5719 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005720 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005721 target, level, internalformat, width, height, depth, border, format, type, pixels);
5722
5723 try
5724 {
5725 UNIMPLEMENTED(); // FIXME
5726 }
5727 catch(std::bad_alloc&)
5728 {
5729 return error(GL_OUT_OF_MEMORY);
5730 }
5731}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005732
5733__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5734{
5735 struct Extension
5736 {
5737 const char *name;
5738 __eglMustCastToProperFunctionPointerType address;
5739 };
5740
5741 static const Extension glExtensions[] =
5742 {
5743 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00005744 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00005745 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005746 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
5747 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
5748 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
5749 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
5750 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
5751 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
5752 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005753 };
5754
5755 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5756 {
5757 if (strcmp(procname, glExtensions[ext].name) == 0)
5758 {
5759 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5760 }
5761 }
5762
5763 return NULL;
5764}
5765
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005766}