blob: ce3cb43102ae7c00136623f6032746a13cb4c324 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +00002// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +000017#include "common/version.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000018
19#include "libGLESv2/main.h"
20#include "libGLESv2/mathutil.h"
21#include "libGLESv2/utilities.h"
22#include "libGLESv2/Buffer.h"
23#include "libGLESv2/Context.h"
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000024#include "libGLESv2/Fence.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000025#include "libGLESv2/Framebuffer.h"
26#include "libGLESv2/Program.h"
27#include "libGLESv2/Renderbuffer.h"
28#include "libGLESv2/Shader.h"
29#include "libGLESv2/Texture.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000030
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +000031bool validImageSize(GLint level, GLsizei width, GLsizei height)
32{
33 if (level < 0 || width < 0 || height < 0)
34 {
35 return false;
36 }
37
38 if (gl::getContext() && gl::getContext()->supportsNonPower2Texture())
39 {
40 return true;
41 }
42
43 if (level == 0)
44 {
45 return true;
46 }
47
48 if (gl::isPow2(width) && gl::isPow2(height))
49 {
50 return true;
51 }
52
53 return false;
54}
55
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000056extern "C"
57{
58
59void __stdcall glActiveTexture(GLenum texture)
60{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +000061 EVENT("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000062
63 try
64 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +000065 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000066
67 if (context)
68 {
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +000069 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
70 {
71 return error(GL_INVALID_ENUM);
72 }
73
daniel@transgaming.com428d1582010-05-04 03:35:25 +000074 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000075 }
76 }
77 catch(std::bad_alloc&)
78 {
79 return error(GL_OUT_OF_MEMORY);
80 }
81}
82
83void __stdcall glAttachShader(GLuint program, GLuint shader)
84{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +000085 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000086
87 try
88 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +000089 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090
91 if (context)
92 {
93 gl::Program *programObject = context->getProgram(program);
94 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000095
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000096 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000097 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000098 if (context->getShader(program))
99 {
100 return error(GL_INVALID_OPERATION);
101 }
102 else
103 {
104 return error(GL_INVALID_VALUE);
105 }
106 }
107
108 if (!shaderObject)
109 {
110 if (context->getProgram(shader))
111 {
112 return error(GL_INVALID_OPERATION);
113 }
114 else
115 {
116 return error(GL_INVALID_VALUE);
117 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000118 }
119
120 if (!programObject->attachShader(shaderObject))
121 {
122 return error(GL_INVALID_OPERATION);
123 }
124 }
125 }
126 catch(std::bad_alloc&)
127 {
128 return error(GL_OUT_OF_MEMORY);
129 }
130}
131
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000132void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000133{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000134 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000135
136 try
137 {
138 if (index >= gl::MAX_VERTEX_ATTRIBS)
139 {
140 return error(GL_INVALID_VALUE);
141 }
142
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000143 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000144
145 if (context)
146 {
147 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000148
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000149 if (!programObject)
150 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000151 if (context->getShader(program))
152 {
153 return error(GL_INVALID_OPERATION);
154 }
155 else
156 {
157 return error(GL_INVALID_VALUE);
158 }
159 }
160
161 if (strncmp(name, "gl_", 3) == 0)
162 {
163 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164 }
165
166 programObject->bindAttributeLocation(index, name);
167 }
168 }
169 catch(std::bad_alloc&)
170 {
171 return error(GL_OUT_OF_MEMORY);
172 }
173}
174
175void __stdcall glBindBuffer(GLenum target, GLuint buffer)
176{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000177 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000178
179 try
180 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000181 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000182
183 if (context)
184 {
185 switch (target)
186 {
187 case GL_ARRAY_BUFFER:
188 context->bindArrayBuffer(buffer);
189 return;
190 case GL_ELEMENT_ARRAY_BUFFER:
191 context->bindElementArrayBuffer(buffer);
192 return;
193 default:
194 return error(GL_INVALID_ENUM);
195 }
196 }
197 }
198 catch(std::bad_alloc&)
199 {
200 return error(GL_OUT_OF_MEMORY);
201 }
202}
203
204void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
205{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000206 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000207
208 try
209 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000210 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000211 {
212 return error(GL_INVALID_ENUM);
213 }
214
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000215 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000216
217 if (context)
218 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000219 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
220 {
221 context->bindReadFramebuffer(framebuffer);
222 }
223
224 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
225 {
226 context->bindDrawFramebuffer(framebuffer);
227 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228 }
229 }
230 catch(std::bad_alloc&)
231 {
232 return error(GL_OUT_OF_MEMORY);
233 }
234}
235
236void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
237{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000238 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000239
240 try
241 {
242 if (target != GL_RENDERBUFFER)
243 {
244 return error(GL_INVALID_ENUM);
245 }
246
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000247 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000248
249 if (context)
250 {
251 context->bindRenderbuffer(renderbuffer);
252 }
253 }
254 catch(std::bad_alloc&)
255 {
256 return error(GL_OUT_OF_MEMORY);
257 }
258}
259
260void __stdcall glBindTexture(GLenum target, GLuint texture)
261{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000262 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000263
264 try
265 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000266 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000267
268 if (context)
269 {
270 gl::Texture *textureObject = context->getTexture(texture);
271
272 if (textureObject && textureObject->getTarget() != target && texture != 0)
273 {
274 return error(GL_INVALID_OPERATION);
275 }
276
277 switch (target)
278 {
279 case GL_TEXTURE_2D:
280 context->bindTexture2D(texture);
281 return;
282 case GL_TEXTURE_CUBE_MAP:
283 context->bindTextureCubeMap(texture);
284 return;
285 default:
286 return error(GL_INVALID_ENUM);
287 }
288 }
289 }
290 catch(std::bad_alloc&)
291 {
292 return error(GL_OUT_OF_MEMORY);
293 }
294}
295
296void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
297{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000298 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000299 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000300
301 try
302 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000303 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000304
305 if (context)
306 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000307 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000308 }
309 }
310 catch(std::bad_alloc&)
311 {
312 return error(GL_OUT_OF_MEMORY);
313 }
314}
315
316void __stdcall glBlendEquation(GLenum mode)
317{
318 glBlendEquationSeparate(mode, mode);
319}
320
321void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
322{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000323 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000324
325 try
326 {
327 switch (modeRGB)
328 {
329 case GL_FUNC_ADD:
330 case GL_FUNC_SUBTRACT:
331 case GL_FUNC_REVERSE_SUBTRACT:
332 break;
333 default:
334 return error(GL_INVALID_ENUM);
335 }
336
337 switch (modeAlpha)
338 {
339 case GL_FUNC_ADD:
340 case GL_FUNC_SUBTRACT:
341 case GL_FUNC_REVERSE_SUBTRACT:
342 break;
343 default:
344 return error(GL_INVALID_ENUM);
345 }
346
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000347 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000348
349 if (context)
350 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000351 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000352 }
353 }
354 catch(std::bad_alloc&)
355 {
356 return error(GL_OUT_OF_MEMORY);
357 }
358}
359
360void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
361{
362 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
363}
364
365void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
366{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000367 EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000368 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000369
370 try
371 {
372 switch (srcRGB)
373 {
374 case GL_ZERO:
375 case GL_ONE:
376 case GL_SRC_COLOR:
377 case GL_ONE_MINUS_SRC_COLOR:
378 case GL_DST_COLOR:
379 case GL_ONE_MINUS_DST_COLOR:
380 case GL_SRC_ALPHA:
381 case GL_ONE_MINUS_SRC_ALPHA:
382 case GL_DST_ALPHA:
383 case GL_ONE_MINUS_DST_ALPHA:
384 case GL_CONSTANT_COLOR:
385 case GL_ONE_MINUS_CONSTANT_COLOR:
386 case GL_CONSTANT_ALPHA:
387 case GL_ONE_MINUS_CONSTANT_ALPHA:
388 case GL_SRC_ALPHA_SATURATE:
389 break;
390 default:
391 return error(GL_INVALID_ENUM);
392 }
393
394 switch (dstRGB)
395 {
396 case GL_ZERO:
397 case GL_ONE:
398 case GL_SRC_COLOR:
399 case GL_ONE_MINUS_SRC_COLOR:
400 case GL_DST_COLOR:
401 case GL_ONE_MINUS_DST_COLOR:
402 case GL_SRC_ALPHA:
403 case GL_ONE_MINUS_SRC_ALPHA:
404 case GL_DST_ALPHA:
405 case GL_ONE_MINUS_DST_ALPHA:
406 case GL_CONSTANT_COLOR:
407 case GL_ONE_MINUS_CONSTANT_COLOR:
408 case GL_CONSTANT_ALPHA:
409 case GL_ONE_MINUS_CONSTANT_ALPHA:
410 break;
411 default:
412 return error(GL_INVALID_ENUM);
413 }
414
415 switch (srcAlpha)
416 {
417 case GL_ZERO:
418 case GL_ONE:
419 case GL_SRC_COLOR:
420 case GL_ONE_MINUS_SRC_COLOR:
421 case GL_DST_COLOR:
422 case GL_ONE_MINUS_DST_COLOR:
423 case GL_SRC_ALPHA:
424 case GL_ONE_MINUS_SRC_ALPHA:
425 case GL_DST_ALPHA:
426 case GL_ONE_MINUS_DST_ALPHA:
427 case GL_CONSTANT_COLOR:
428 case GL_ONE_MINUS_CONSTANT_COLOR:
429 case GL_CONSTANT_ALPHA:
430 case GL_ONE_MINUS_CONSTANT_ALPHA:
431 case GL_SRC_ALPHA_SATURATE:
432 break;
433 default:
434 return error(GL_INVALID_ENUM);
435 }
436
437 switch (dstAlpha)
438 {
439 case GL_ZERO:
440 case GL_ONE:
441 case GL_SRC_COLOR:
442 case GL_ONE_MINUS_SRC_COLOR:
443 case GL_DST_COLOR:
444 case GL_ONE_MINUS_DST_COLOR:
445 case GL_SRC_ALPHA:
446 case GL_ONE_MINUS_SRC_ALPHA:
447 case GL_DST_ALPHA:
448 case GL_ONE_MINUS_DST_ALPHA:
449 case GL_CONSTANT_COLOR:
450 case GL_ONE_MINUS_CONSTANT_COLOR:
451 case GL_CONSTANT_ALPHA:
452 case GL_ONE_MINUS_CONSTANT_ALPHA:
453 break;
454 default:
455 return error(GL_INVALID_ENUM);
456 }
457
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000458 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
459 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
460
461 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
462 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
463
464 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000465 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000466 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
467 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000468 }
469
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000470 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000471
472 if (context)
473 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000474 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000475 }
476 }
477 catch(std::bad_alloc&)
478 {
479 return error(GL_OUT_OF_MEMORY);
480 }
481}
482
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000483void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000484{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000485 EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000486 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000487
488 try
489 {
490 if (size < 0)
491 {
492 return error(GL_INVALID_VALUE);
493 }
494
495 switch (usage)
496 {
497 case GL_STREAM_DRAW:
498 case GL_STATIC_DRAW:
499 case GL_DYNAMIC_DRAW:
500 break;
501 default:
502 return error(GL_INVALID_ENUM);
503 }
504
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000505 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000506
507 if (context)
508 {
509 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000510
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000511 switch (target)
512 {
513 case GL_ARRAY_BUFFER:
514 buffer = context->getArrayBuffer();
515 break;
516 case GL_ELEMENT_ARRAY_BUFFER:
517 buffer = context->getElementArrayBuffer();
518 break;
519 default:
520 return error(GL_INVALID_ENUM);
521 }
522
523 if (!buffer)
524 {
525 return error(GL_INVALID_OPERATION);
526 }
527
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000528 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000529 }
530 }
531 catch(std::bad_alloc&)
532 {
533 return error(GL_OUT_OF_MEMORY);
534 }
535}
536
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000537void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000538{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000539 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000540 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000541
542 try
543 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000544 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000545 {
546 return error(GL_INVALID_VALUE);
547 }
548
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000549 if (data == NULL)
550 {
551 return;
552 }
553
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000554 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000555
556 if (context)
557 {
558 gl::Buffer *buffer;
559
560 switch (target)
561 {
562 case GL_ARRAY_BUFFER:
563 buffer = context->getArrayBuffer();
564 break;
565 case GL_ELEMENT_ARRAY_BUFFER:
566 buffer = context->getElementArrayBuffer();
567 break;
568 default:
569 return error(GL_INVALID_ENUM);
570 }
571
572 if (!buffer)
573 {
574 return error(GL_INVALID_OPERATION);
575 }
576
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000577 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000578 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000579 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000580 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000581
582 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000583 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000584 }
585 catch(std::bad_alloc&)
586 {
587 return error(GL_OUT_OF_MEMORY);
588 }
589}
590
591GLenum __stdcall glCheckFramebufferStatus(GLenum target)
592{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000593 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000594
595 try
596 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000597 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000598 {
599 return error(GL_INVALID_ENUM, 0);
600 }
601
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000602 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000603
604 if (context)
605 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000606 gl::Framebuffer *framebuffer = NULL;
607 if (target == GL_READ_FRAMEBUFFER_ANGLE)
608 {
609 framebuffer = context->getReadFramebuffer();
610 }
611 else
612 {
613 framebuffer = context->getDrawFramebuffer();
614 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000615
616 return framebuffer->completeness();
617 }
618 }
619 catch(std::bad_alloc&)
620 {
621 return error(GL_OUT_OF_MEMORY, 0);
622 }
623
624 return 0;
625}
626
627void __stdcall glClear(GLbitfield mask)
628{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000629 EVENT("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000630
631 try
632 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000633 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000634
635 if (context)
636 {
637 context->clear(mask);
638 }
639 }
640 catch(std::bad_alloc&)
641 {
642 return error(GL_OUT_OF_MEMORY);
643 }
644}
645
646void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
647{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000648 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000649 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000650
651 try
652 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000653 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000654
655 if (context)
656 {
657 context->setClearColor(red, green, blue, alpha);
658 }
659 }
660 catch(std::bad_alloc&)
661 {
662 return error(GL_OUT_OF_MEMORY);
663 }
664}
665
666void __stdcall glClearDepthf(GLclampf depth)
667{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000668 EVENT("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000669
670 try
671 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000672 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000673
674 if (context)
675 {
676 context->setClearDepth(depth);
677 }
678 }
679 catch(std::bad_alloc&)
680 {
681 return error(GL_OUT_OF_MEMORY);
682 }
683}
684
685void __stdcall glClearStencil(GLint s)
686{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000687 EVENT("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000688
689 try
690 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000691 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000692
693 if (context)
694 {
695 context->setClearStencil(s);
696 }
697 }
698 catch(std::bad_alloc&)
699 {
700 return error(GL_OUT_OF_MEMORY);
701 }
702}
703
704void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
705{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000706 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000707 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000708
709 try
710 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000711 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000712
713 if (context)
714 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000715 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000716 }
717 }
718 catch(std::bad_alloc&)
719 {
720 return error(GL_OUT_OF_MEMORY);
721 }
722}
723
724void __stdcall glCompileShader(GLuint shader)
725{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000726 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000727
728 try
729 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000730 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000731
732 if (context)
733 {
734 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000735
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000736 if (!shaderObject)
737 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000738 if (context->getProgram(shader))
739 {
740 return error(GL_INVALID_OPERATION);
741 }
742 else
743 {
744 return error(GL_INVALID_VALUE);
745 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000746 }
747
748 shaderObject->compile();
749 }
750 }
751 catch(std::bad_alloc&)
752 {
753 return error(GL_OUT_OF_MEMORY);
754 }
755}
756
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000757void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
758 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000759{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000760 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000761 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000762 target, level, internalformat, width, height, border, imageSize, data);
763
764 try
765 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000766 if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000767 {
768 return error(GL_INVALID_VALUE);
769 }
770
daniel@transgaming.com01868132010-08-24 19:21:17 +0000771 switch (internalformat)
772 {
773 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
774 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +0000775 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
776 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +0000777 break;
778 default:
779 return error(GL_INVALID_ENUM);
780 }
781
782 if (border != 0)
783 {
784 return error(GL_INVALID_VALUE);
785 }
786
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000787 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000788
789 if (context)
790 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000791 if (level > context->getMaximumTextureLevel())
792 {
793 return error(GL_INVALID_VALUE);
794 }
795
796 switch (target)
797 {
798 case GL_TEXTURE_2D:
799 if (width > (context->getMaximumTextureDimension() >> level) ||
800 height > (context->getMaximumTextureDimension() >> level))
801 {
802 return error(GL_INVALID_VALUE);
803 }
804 break;
805 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
806 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
807 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
808 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
809 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
810 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
811 if (width != height)
812 {
813 return error(GL_INVALID_VALUE);
814 }
815
816 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
817 height > (context->getMaximumCubeTextureDimension() >> level))
818 {
819 return error(GL_INVALID_VALUE);
820 }
821 break;
822 default:
823 return error(GL_INVALID_ENUM);
824 }
825
gman@chromium.org50c526d2011-08-10 05:19:44 +0000826 switch (internalformat) {
827 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
828 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
829 if (!context->supportsDXT1Textures())
830 {
831 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
832 }
833 break;
834 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
835 if (!context->supportsDXT3Textures())
836 {
837 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
838 }
839 break;
840 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
841 if (!context->supportsDXT5Textures())
842 {
843 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
844 }
845 break;
846 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000847 }
848
849 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
850 {
851 return error(GL_INVALID_VALUE);
852 }
853
854 if (target == GL_TEXTURE_2D)
855 {
856 gl::Texture2D *texture = context->getTexture2D();
857
858 if (!texture)
859 {
860 return error(GL_INVALID_OPERATION);
861 }
862
863 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
864 }
865 else
866 {
867 gl::TextureCubeMap *texture = context->getTextureCubeMap();
868
869 if (!texture)
870 {
871 return error(GL_INVALID_OPERATION);
872 }
873
874 switch (target)
875 {
876 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
877 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
878 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
879 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
880 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
881 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
882 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
883 break;
884 default: UNREACHABLE();
885 }
886 }
887 }
888
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000889 }
890 catch(std::bad_alloc&)
891 {
892 return error(GL_OUT_OF_MEMORY);
893 }
894}
895
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000896void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
897 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000898{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000899 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000900 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000901 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000902 target, level, xoffset, yoffset, width, height, format, imageSize, data);
903
904 try
905 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000906 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000907 {
908 return error(GL_INVALID_ENUM);
909 }
910
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000911 if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000912 {
913 return error(GL_INVALID_VALUE);
914 }
915
daniel@transgaming.com01868132010-08-24 19:21:17 +0000916 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000917 {
daniel@transgaming.com01868132010-08-24 19:21:17 +0000918 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
919 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +0000920 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
921 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +0000922 break;
923 default:
924 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +0000925 }
926
daniel@transgaming.com01868132010-08-24 19:21:17 +0000927 if (width == 0 || height == 0 || data == NULL)
928 {
929 return;
930 }
931
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000932 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000933
934 if (context)
935 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000936 if (level > context->getMaximumTextureLevel())
937 {
938 return error(GL_INVALID_VALUE);
939 }
940
gman@chromium.org50c526d2011-08-10 05:19:44 +0000941 switch (format) {
942 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
943 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
944 if (!context->supportsDXT1Textures())
945 {
946 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
947 }
948 break;
949 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
950 if (!context->supportsDXT3Textures())
951 {
952 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
953 }
954 break;
955 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
956 if (!context->supportsDXT5Textures())
957 {
958 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
959 }
960 break;
961 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000962 }
963
964 if (imageSize != gl::ComputeCompressedSize(width, height, format))
965 {
966 return error(GL_INVALID_VALUE);
967 }
968
969 if (xoffset % 4 != 0 || yoffset % 4 != 0)
970 {
971 return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
gman@chromium.org50c526d2011-08-10 05:19:44 +0000972 // does not exist unless DXT textures are supported.
daniel@transgaming.com01868132010-08-24 19:21:17 +0000973 }
974
975 if (target == GL_TEXTURE_2D)
976 {
977 gl::Texture2D *texture = context->getTexture2D();
978
979 if (!texture)
980 {
981 return error(GL_INVALID_OPERATION);
982 }
983
984 if (!texture->isCompressed())
985 {
986 return error(GL_INVALID_OPERATION);
987 }
988
989 if ((width % 4 != 0 && width != texture->getWidth()) ||
990 (height % 4 != 0 && height != texture->getHeight()))
991 {
992 return error(GL_INVALID_OPERATION);
993 }
994
995 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
996 }
997 else if (gl::IsCubemapTextureTarget(target))
998 {
999 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1000
1001 if (!texture)
1002 {
1003 return error(GL_INVALID_OPERATION);
1004 }
1005
1006 if (!texture->isCompressed())
1007 {
1008 return error(GL_INVALID_OPERATION);
1009 }
1010
1011 if ((width % 4 != 0 && width != texture->getWidth()) ||
1012 (height % 4 != 0 && height != texture->getHeight()))
1013 {
1014 return error(GL_INVALID_OPERATION);
1015 }
1016
1017 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
1018 }
1019 else
1020 {
1021 UNREACHABLE();
1022 }
1023 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001024 }
1025 catch(std::bad_alloc&)
1026 {
1027 return error(GL_OUT_OF_MEMORY);
1028 }
1029}
1030
1031void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1032{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001033 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001034 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001035 target, level, internalformat, x, y, width, height, border);
1036
1037 try
1038 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001039 if (!validImageSize(level, width, height))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001040 {
1041 return error(GL_INVALID_VALUE);
1042 }
1043
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001044 if (border != 0)
1045 {
1046 return error(GL_INVALID_VALUE);
1047 }
1048
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001049 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001050
1051 if (context)
1052 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001053 switch (target)
1054 {
1055 case GL_TEXTURE_2D:
1056 if (width > (context->getMaximumTextureDimension() >> level) ||
1057 height > (context->getMaximumTextureDimension() >> level))
1058 {
1059 return error(GL_INVALID_VALUE);
1060 }
1061 break;
1062 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1063 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1064 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1065 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1066 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1067 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1068 if (width != height)
1069 {
1070 return error(GL_INVALID_VALUE);
1071 }
1072
1073 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1074 height > (context->getMaximumCubeTextureDimension() >> level))
1075 {
1076 return error(GL_INVALID_VALUE);
1077 }
1078 break;
1079 default:
1080 return error(GL_INVALID_ENUM);
1081 }
1082
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001083 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001084
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001085 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1086 {
1087 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1088 }
1089
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001090 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1091 {
1092 return error(GL_INVALID_OPERATION);
1093 }
1094
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001095 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001096 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001097
1098 // [OpenGL ES 2.0.24] table 3.9
1099 switch (internalformat)
1100 {
1101 case GL_ALPHA:
1102 if (colorbufferFormat != GL_ALPHA &&
1103 colorbufferFormat != GL_RGBA &&
1104 colorbufferFormat != GL_RGBA4 &&
1105 colorbufferFormat != GL_RGB5_A1 &&
1106 colorbufferFormat != GL_RGBA8_OES)
1107 {
1108 return error(GL_INVALID_OPERATION);
1109 }
1110 break;
1111 case GL_LUMINANCE:
1112 case GL_RGB:
1113 if (colorbufferFormat != GL_RGB &&
1114 colorbufferFormat != GL_RGB565 &&
1115 colorbufferFormat != GL_RGB8_OES &&
1116 colorbufferFormat != GL_RGBA &&
1117 colorbufferFormat != GL_RGBA4 &&
1118 colorbufferFormat != GL_RGB5_A1 &&
1119 colorbufferFormat != GL_RGBA8_OES)
1120 {
1121 return error(GL_INVALID_OPERATION);
1122 }
1123 break;
1124 case GL_LUMINANCE_ALPHA:
1125 case GL_RGBA:
1126 if (colorbufferFormat != GL_RGBA &&
1127 colorbufferFormat != GL_RGBA4 &&
1128 colorbufferFormat != GL_RGB5_A1 &&
1129 colorbufferFormat != GL_RGBA8_OES)
1130 {
1131 return error(GL_INVALID_OPERATION);
1132 }
1133 break;
1134 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1135 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001136 if (context->supportsDXT1Textures())
1137 {
1138 return error(GL_INVALID_OPERATION);
1139 }
1140 else
1141 {
1142 return error(GL_INVALID_ENUM);
1143 }
1144 break;
1145 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1146 if (context->supportsDXT3Textures())
1147 {
1148 return error(GL_INVALID_OPERATION);
1149 }
1150 else
1151 {
1152 return error(GL_INVALID_ENUM);
1153 }
1154 break;
1155 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1156 if (context->supportsDXT5Textures())
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001157 {
1158 return error(GL_INVALID_OPERATION);
1159 }
1160 else
1161 {
1162 return error(GL_INVALID_ENUM);
1163 }
1164 break;
1165 default:
1166 return error(GL_INVALID_ENUM);
1167 }
1168
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001169 if (target == GL_TEXTURE_2D)
1170 {
1171 gl::Texture2D *texture = context->getTexture2D();
1172
1173 if (!texture)
1174 {
1175 return error(GL_INVALID_OPERATION);
1176 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001177
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001178 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001179 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001180 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001181 {
1182 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1183
1184 if (!texture)
1185 {
1186 return error(GL_INVALID_OPERATION);
1187 }
1188
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001189 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001190 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001191 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001192 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001193 }
1194 catch(std::bad_alloc&)
1195 {
1196 return error(GL_OUT_OF_MEMORY);
1197 }
1198}
1199
1200void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1201{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001202 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001203 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001204 target, level, xoffset, yoffset, x, y, width, height);
1205
1206 try
1207 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001208 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001209 {
1210 return error(GL_INVALID_ENUM);
1211 }
1212
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001213 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001214 {
1215 return error(GL_INVALID_VALUE);
1216 }
1217
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001218 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1219 {
1220 return error(GL_INVALID_VALUE);
1221 }
1222
1223 if (width == 0 || height == 0)
1224 {
1225 return;
1226 }
1227
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001228 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001229
1230 if (context)
1231 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001232 if (level > context->getMaximumTextureLevel())
1233 {
1234 return error(GL_INVALID_VALUE);
1235 }
1236
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001237 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001238
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001239 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1240 {
1241 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1242 }
1243
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001244 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1245 {
1246 return error(GL_INVALID_OPERATION);
1247 }
1248
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001249 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001250 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001251 gl::Texture *texture = NULL;
1252
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001253 if (target == GL_TEXTURE_2D)
1254 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001255 texture = context->getTexture2D();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001256 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001257 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001258 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001259 texture = context->getTextureCubeMap();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001260 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001261 else UNREACHABLE();
1262
1263 if (!texture)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001264 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001265 return error(GL_INVALID_OPERATION);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001266 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001267
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001268 GLenum textureFormat = texture->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001269
1270 // [OpenGL ES 2.0.24] table 3.9
1271 switch (textureFormat)
1272 {
1273 case GL_ALPHA:
1274 if (colorbufferFormat != GL_ALPHA &&
1275 colorbufferFormat != GL_RGBA &&
1276 colorbufferFormat != GL_RGBA4 &&
1277 colorbufferFormat != GL_RGB5_A1 &&
1278 colorbufferFormat != GL_RGBA8_OES)
1279 {
1280 return error(GL_INVALID_OPERATION);
1281 }
1282 break;
1283 case GL_LUMINANCE:
1284 case GL_RGB:
1285 if (colorbufferFormat != GL_RGB &&
1286 colorbufferFormat != GL_RGB565 &&
1287 colorbufferFormat != GL_RGB8_OES &&
1288 colorbufferFormat != GL_RGBA &&
1289 colorbufferFormat != GL_RGBA4 &&
1290 colorbufferFormat != GL_RGB5_A1 &&
1291 colorbufferFormat != GL_RGBA8_OES)
1292 {
1293 return error(GL_INVALID_OPERATION);
1294 }
1295 break;
1296 case GL_LUMINANCE_ALPHA:
1297 case GL_RGBA:
1298 if (colorbufferFormat != GL_RGBA &&
1299 colorbufferFormat != GL_RGBA4 &&
1300 colorbufferFormat != GL_RGB5_A1 &&
1301 colorbufferFormat != GL_RGBA8_OES)
1302 {
1303 return error(GL_INVALID_OPERATION);
1304 }
1305 break;
1306 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1307 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001308 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1309 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001310 return error(GL_INVALID_OPERATION);
1311 default:
1312 return error(GL_INVALID_OPERATION);
1313 }
1314
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001315 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001316 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001317 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001318
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001319 catch(std::bad_alloc&)
1320 {
1321 return error(GL_OUT_OF_MEMORY);
1322 }
1323}
1324
1325GLuint __stdcall glCreateProgram(void)
1326{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001327 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001328
1329 try
1330 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001331 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001332
1333 if (context)
1334 {
1335 return context->createProgram();
1336 }
1337 }
1338 catch(std::bad_alloc&)
1339 {
1340 return error(GL_OUT_OF_MEMORY, 0);
1341 }
1342
1343 return 0;
1344}
1345
1346GLuint __stdcall glCreateShader(GLenum type)
1347{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001348 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001349
1350 try
1351 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001352 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001353
1354 if (context)
1355 {
1356 switch (type)
1357 {
1358 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001359 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001360 return context->createShader(type);
1361 default:
1362 return error(GL_INVALID_ENUM, 0);
1363 }
1364 }
1365 }
1366 catch(std::bad_alloc&)
1367 {
1368 return error(GL_OUT_OF_MEMORY, 0);
1369 }
1370
1371 return 0;
1372}
1373
1374void __stdcall glCullFace(GLenum mode)
1375{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001376 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001377
1378 try
1379 {
1380 switch (mode)
1381 {
1382 case GL_FRONT:
1383 case GL_BACK:
1384 case GL_FRONT_AND_BACK:
1385 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001386 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001387
1388 if (context)
1389 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001390 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001391 }
1392 }
1393 break;
1394 default:
1395 return error(GL_INVALID_ENUM);
1396 }
1397 }
1398 catch(std::bad_alloc&)
1399 {
1400 return error(GL_OUT_OF_MEMORY);
1401 }
1402}
1403
1404void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1405{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001406 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001407
1408 try
1409 {
1410 if (n < 0)
1411 {
1412 return error(GL_INVALID_VALUE);
1413 }
1414
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001415 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001416
1417 if (context)
1418 {
1419 for (int i = 0; i < n; i++)
1420 {
1421 context->deleteBuffer(buffers[i]);
1422 }
1423 }
1424 }
1425 catch(std::bad_alloc&)
1426 {
1427 return error(GL_OUT_OF_MEMORY);
1428 }
1429}
1430
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001431void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1432{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001433 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001434
1435 try
1436 {
1437 if (n < 0)
1438 {
1439 return error(GL_INVALID_VALUE);
1440 }
1441
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001442 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001443
1444 if (context)
1445 {
1446 for (int i = 0; i < n; i++)
1447 {
1448 context->deleteFence(fences[i]);
1449 }
1450 }
1451 }
1452 catch(std::bad_alloc&)
1453 {
1454 return error(GL_OUT_OF_MEMORY);
1455 }
1456}
1457
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001458void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1459{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001460 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001461
1462 try
1463 {
1464 if (n < 0)
1465 {
1466 return error(GL_INVALID_VALUE);
1467 }
1468
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001469 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001470
1471 if (context)
1472 {
1473 for (int i = 0; i < n; i++)
1474 {
1475 if (framebuffers[i] != 0)
1476 {
1477 context->deleteFramebuffer(framebuffers[i]);
1478 }
1479 }
1480 }
1481 }
1482 catch(std::bad_alloc&)
1483 {
1484 return error(GL_OUT_OF_MEMORY);
1485 }
1486}
1487
1488void __stdcall glDeleteProgram(GLuint program)
1489{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001490 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001491
1492 try
1493 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001494 if (program == 0)
1495 {
1496 return;
1497 }
1498
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001499 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001500
1501 if (context)
1502 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001503 if (!context->getProgram(program))
1504 {
1505 if(context->getShader(program))
1506 {
1507 return error(GL_INVALID_OPERATION);
1508 }
1509 else
1510 {
1511 return error(GL_INVALID_VALUE);
1512 }
1513 }
1514
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001515 context->deleteProgram(program);
1516 }
1517 }
1518 catch(std::bad_alloc&)
1519 {
1520 return error(GL_OUT_OF_MEMORY);
1521 }
1522}
1523
1524void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1525{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001526 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001527
1528 try
1529 {
1530 if (n < 0)
1531 {
1532 return error(GL_INVALID_VALUE);
1533 }
1534
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001535 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001536
1537 if (context)
1538 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001539 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001540 {
1541 context->deleteRenderbuffer(renderbuffers[i]);
1542 }
1543 }
1544 }
1545 catch(std::bad_alloc&)
1546 {
1547 return error(GL_OUT_OF_MEMORY);
1548 }
1549}
1550
1551void __stdcall glDeleteShader(GLuint shader)
1552{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001553 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001554
1555 try
1556 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001557 if (shader == 0)
1558 {
1559 return;
1560 }
1561
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001562 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001563
1564 if (context)
1565 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001566 if (!context->getShader(shader))
1567 {
1568 if(context->getProgram(shader))
1569 {
1570 return error(GL_INVALID_OPERATION);
1571 }
1572 else
1573 {
1574 return error(GL_INVALID_VALUE);
1575 }
1576 }
1577
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001578 context->deleteShader(shader);
1579 }
1580 }
1581 catch(std::bad_alloc&)
1582 {
1583 return error(GL_OUT_OF_MEMORY);
1584 }
1585}
1586
1587void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1588{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001589 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001590
1591 try
1592 {
1593 if (n < 0)
1594 {
1595 return error(GL_INVALID_VALUE);
1596 }
1597
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001598 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001599
1600 if (context)
1601 {
1602 for (int i = 0; i < n; i++)
1603 {
1604 if (textures[i] != 0)
1605 {
1606 context->deleteTexture(textures[i]);
1607 }
1608 }
1609 }
1610 }
1611 catch(std::bad_alloc&)
1612 {
1613 return error(GL_OUT_OF_MEMORY);
1614 }
1615}
1616
1617void __stdcall glDepthFunc(GLenum func)
1618{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001619 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001620
1621 try
1622 {
1623 switch (func)
1624 {
1625 case GL_NEVER:
1626 case GL_ALWAYS:
1627 case GL_LESS:
1628 case GL_LEQUAL:
1629 case GL_EQUAL:
1630 case GL_GREATER:
1631 case GL_GEQUAL:
1632 case GL_NOTEQUAL:
1633 break;
1634 default:
1635 return error(GL_INVALID_ENUM);
1636 }
1637
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001638 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001639
1640 if (context)
1641 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001642 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001643 }
1644 }
1645 catch(std::bad_alloc&)
1646 {
1647 return error(GL_OUT_OF_MEMORY);
1648 }
1649}
1650
1651void __stdcall glDepthMask(GLboolean flag)
1652{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001653 EVENT("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001654
1655 try
1656 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001657 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001658
1659 if (context)
1660 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001661 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001662 }
1663 }
1664 catch(std::bad_alloc&)
1665 {
1666 return error(GL_OUT_OF_MEMORY);
1667 }
1668}
1669
1670void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1671{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001672 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001673
1674 try
1675 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001676 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001677
1678 if (context)
1679 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001680 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001681 }
1682 }
1683 catch(std::bad_alloc&)
1684 {
1685 return error(GL_OUT_OF_MEMORY);
1686 }
1687}
1688
1689void __stdcall glDetachShader(GLuint program, GLuint shader)
1690{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001691 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001692
1693 try
1694 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001695 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001696
1697 if (context)
1698 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001699
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001700 gl::Program *programObject = context->getProgram(program);
1701 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001702
1703 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001704 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001705 gl::Shader *shaderByProgramHandle;
1706 shaderByProgramHandle = context->getShader(program);
1707 if (!shaderByProgramHandle)
1708 {
1709 return error(GL_INVALID_VALUE);
1710 }
1711 else
1712 {
1713 return error(GL_INVALID_OPERATION);
1714 }
1715 }
1716
1717 if (!shaderObject)
1718 {
1719 gl::Program *programByShaderHandle = context->getProgram(shader);
1720 if (!programByShaderHandle)
1721 {
1722 return error(GL_INVALID_VALUE);
1723 }
1724 else
1725 {
1726 return error(GL_INVALID_OPERATION);
1727 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001728 }
1729
1730 if (!programObject->detachShader(shaderObject))
1731 {
1732 return error(GL_INVALID_OPERATION);
1733 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001734 }
1735 }
1736 catch(std::bad_alloc&)
1737 {
1738 return error(GL_OUT_OF_MEMORY);
1739 }
1740}
1741
1742void __stdcall glDisable(GLenum cap)
1743{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001744 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001745
1746 try
1747 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001748 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001749
1750 if (context)
1751 {
1752 switch (cap)
1753 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001754 case GL_CULL_FACE: context->setCullFace(false); break;
1755 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1756 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1757 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1758 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1759 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1760 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1761 case GL_BLEND: context->setBlend(false); break;
1762 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001763 default:
1764 return error(GL_INVALID_ENUM);
1765 }
1766 }
1767 }
1768 catch(std::bad_alloc&)
1769 {
1770 return error(GL_OUT_OF_MEMORY);
1771 }
1772}
1773
1774void __stdcall glDisableVertexAttribArray(GLuint index)
1775{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001776 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001777
1778 try
1779 {
1780 if (index >= gl::MAX_VERTEX_ATTRIBS)
1781 {
1782 return error(GL_INVALID_VALUE);
1783 }
1784
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001785 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001786
1787 if (context)
1788 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001789 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001790 }
1791 }
1792 catch(std::bad_alloc&)
1793 {
1794 return error(GL_OUT_OF_MEMORY);
1795 }
1796}
1797
1798void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1799{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001800 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001801
1802 try
1803 {
1804 if (count < 0 || first < 0)
1805 {
1806 return error(GL_INVALID_VALUE);
1807 }
1808
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001809 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001810
1811 if (context)
1812 {
1813 context->drawArrays(mode, first, count);
1814 }
1815 }
1816 catch(std::bad_alloc&)
1817 {
1818 return error(GL_OUT_OF_MEMORY);
1819 }
1820}
1821
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001822void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001823{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001824 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001825 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001826
1827 try
1828 {
1829 if (count < 0)
1830 {
1831 return error(GL_INVALID_VALUE);
1832 }
1833
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001834 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001835
1836 if (context)
1837 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001838 switch (type)
1839 {
1840 case GL_UNSIGNED_BYTE:
1841 case GL_UNSIGNED_SHORT:
1842 break;
1843 case GL_UNSIGNED_INT:
1844 if (!context->supports32bitIndices())
1845 {
1846 return error(GL_INVALID_ENUM);
1847 }
1848 break;
1849 default:
1850 return error(GL_INVALID_ENUM);
1851 }
1852
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001853 context->drawElements(mode, count, type, indices);
1854 }
1855 }
1856 catch(std::bad_alloc&)
1857 {
1858 return error(GL_OUT_OF_MEMORY);
1859 }
1860}
1861
1862void __stdcall glEnable(GLenum cap)
1863{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001864 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001865
1866 try
1867 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001868 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001869
1870 if (context)
1871 {
1872 switch (cap)
1873 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001874 case GL_CULL_FACE: context->setCullFace(true); break;
1875 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1876 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1877 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1878 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1879 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1880 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1881 case GL_BLEND: context->setBlend(true); break;
1882 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001883 default:
1884 return error(GL_INVALID_ENUM);
1885 }
1886 }
1887 }
1888 catch(std::bad_alloc&)
1889 {
1890 return error(GL_OUT_OF_MEMORY);
1891 }
1892}
1893
1894void __stdcall glEnableVertexAttribArray(GLuint index)
1895{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001896 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001897
1898 try
1899 {
1900 if (index >= gl::MAX_VERTEX_ATTRIBS)
1901 {
1902 return error(GL_INVALID_VALUE);
1903 }
1904
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001905 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001906
1907 if (context)
1908 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001909 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001910 }
1911 }
1912 catch(std::bad_alloc&)
1913 {
1914 return error(GL_OUT_OF_MEMORY);
1915 }
1916}
1917
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001918void __stdcall glFinishFenceNV(GLuint fence)
1919{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001920 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001921
1922 try
1923 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001924 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001925
1926 if (context)
1927 {
1928 gl::Fence* fenceObject = context->getFence(fence);
1929
1930 if (fenceObject == NULL)
1931 {
1932 return error(GL_INVALID_OPERATION);
1933 }
1934
1935 fenceObject->finishFence();
1936 }
1937 }
1938 catch(std::bad_alloc&)
1939 {
1940 return error(GL_OUT_OF_MEMORY);
1941 }
1942}
1943
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001944void __stdcall glFinish(void)
1945{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001946 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001947
1948 try
1949 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001950 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001951
1952 if (context)
1953 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00001954 context->sync(true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001955 }
1956 }
1957 catch(std::bad_alloc&)
1958 {
1959 return error(GL_OUT_OF_MEMORY);
1960 }
1961}
1962
1963void __stdcall glFlush(void)
1964{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001965 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001966
1967 try
1968 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001969 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001970
1971 if (context)
1972 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00001973 context->sync(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001974 }
1975 }
1976 catch(std::bad_alloc&)
1977 {
1978 return error(GL_OUT_OF_MEMORY);
1979 }
1980}
1981
1982void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1983{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001984 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001985 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001986
1987 try
1988 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001989 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00001990 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001991 {
1992 return error(GL_INVALID_ENUM);
1993 }
1994
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001995 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001996
1997 if (context)
1998 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001999 gl::Framebuffer *framebuffer = NULL;
2000 GLuint framebufferHandle = 0;
2001 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2002 {
2003 framebuffer = context->getReadFramebuffer();
2004 framebufferHandle = context->getReadFramebufferHandle();
2005 }
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002006 else
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002007 {
2008 framebuffer = context->getDrawFramebuffer();
2009 framebufferHandle = context->getDrawFramebufferHandle();
2010 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002011
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002012 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002013 {
2014 return error(GL_INVALID_OPERATION);
2015 }
2016
2017 switch (attachment)
2018 {
2019 case GL_COLOR_ATTACHMENT0:
2020 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2021 break;
2022 case GL_DEPTH_ATTACHMENT:
2023 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2024 break;
2025 case GL_STENCIL_ATTACHMENT:
2026 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2027 break;
2028 default:
2029 return error(GL_INVALID_ENUM);
2030 }
2031 }
2032 }
2033 catch(std::bad_alloc&)
2034 {
2035 return error(GL_OUT_OF_MEMORY);
2036 }
2037}
2038
2039void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2040{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002041 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002042 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002043
2044 try
2045 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002046 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002047 {
2048 return error(GL_INVALID_ENUM);
2049 }
2050
2051 switch (attachment)
2052 {
2053 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002054 case GL_DEPTH_ATTACHMENT:
2055 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002056 break;
2057 default:
2058 return error(GL_INVALID_ENUM);
2059 }
2060
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002061 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002062
2063 if (context)
2064 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002065 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002066 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002067 textarget = GL_NONE;
2068 }
2069 else
2070 {
2071 gl::Texture *tex = context->getTexture(texture);
2072
2073 if (tex == NULL)
2074 {
2075 return error(GL_INVALID_OPERATION);
2076 }
2077
daniel@transgaming.com01868132010-08-24 19:21:17 +00002078 if (tex->isCompressed())
2079 {
2080 return error(GL_INVALID_OPERATION);
2081 }
2082
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002083 switch (textarget)
2084 {
2085 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002086 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002087 {
2088 return error(GL_INVALID_OPERATION);
2089 }
2090 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002091
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002092 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002093 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002094 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002095 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002096 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002097 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002098 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2099 {
2100 return error(GL_INVALID_OPERATION);
2101 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002102 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002103
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002104 default:
2105 return error(GL_INVALID_ENUM);
2106 }
2107
2108 if (level != 0)
2109 {
2110 return error(GL_INVALID_VALUE);
2111 }
2112 }
2113
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002114 gl::Framebuffer *framebuffer = NULL;
2115 GLuint framebufferHandle = 0;
2116 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2117 {
2118 framebuffer = context->getReadFramebuffer();
2119 framebufferHandle = context->getReadFramebufferHandle();
2120 }
2121 else
2122 {
2123 framebuffer = context->getDrawFramebuffer();
2124 framebufferHandle = context->getDrawFramebufferHandle();
2125 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002126
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002127 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002128 {
2129 return error(GL_INVALID_OPERATION);
2130 }
2131
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002132 switch (attachment)
2133 {
2134 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2135 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2136 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2137 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002138 }
2139 }
2140 catch(std::bad_alloc&)
2141 {
2142 return error(GL_OUT_OF_MEMORY);
2143 }
2144}
2145
2146void __stdcall glFrontFace(GLenum mode)
2147{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002148 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002149
2150 try
2151 {
2152 switch (mode)
2153 {
2154 case GL_CW:
2155 case GL_CCW:
2156 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002157 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002158
2159 if (context)
2160 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002161 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002162 }
2163 }
2164 break;
2165 default:
2166 return error(GL_INVALID_ENUM);
2167 }
2168 }
2169 catch(std::bad_alloc&)
2170 {
2171 return error(GL_OUT_OF_MEMORY);
2172 }
2173}
2174
2175void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2176{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002177 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002178
2179 try
2180 {
2181 if (n < 0)
2182 {
2183 return error(GL_INVALID_VALUE);
2184 }
2185
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002186 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002187
2188 if (context)
2189 {
2190 for (int i = 0; i < n; i++)
2191 {
2192 buffers[i] = context->createBuffer();
2193 }
2194 }
2195 }
2196 catch(std::bad_alloc&)
2197 {
2198 return error(GL_OUT_OF_MEMORY);
2199 }
2200}
2201
2202void __stdcall glGenerateMipmap(GLenum target)
2203{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002204 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002205
2206 try
2207 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002208 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002209
2210 if (context)
2211 {
2212 gl::Texture *texture;
2213
2214 switch (target)
2215 {
2216 case GL_TEXTURE_2D:
2217 texture = context->getTexture2D();
2218 break;
2219
2220 case GL_TEXTURE_CUBE_MAP:
2221 texture = context->getTextureCubeMap();
2222 break;
2223
2224 default:
2225 return error(GL_INVALID_ENUM);
2226 }
2227
daniel@transgaming.com01868132010-08-24 19:21:17 +00002228 if (texture->isCompressed())
2229 {
2230 return error(GL_INVALID_OPERATION);
2231 }
2232
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002233 texture->generateMipmaps();
2234 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002235 }
2236 catch(std::bad_alloc&)
2237 {
2238 return error(GL_OUT_OF_MEMORY);
2239 }
2240}
2241
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002242void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2243{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002244 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002245
2246 try
2247 {
2248 if (n < 0)
2249 {
2250 return error(GL_INVALID_VALUE);
2251 }
2252
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002253 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002254
2255 if (context)
2256 {
2257 for (int i = 0; i < n; i++)
2258 {
2259 fences[i] = context->createFence();
2260 }
2261 }
2262 }
2263 catch(std::bad_alloc&)
2264 {
2265 return error(GL_OUT_OF_MEMORY);
2266 }
2267}
2268
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002269void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2270{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002271 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002272
2273 try
2274 {
2275 if (n < 0)
2276 {
2277 return error(GL_INVALID_VALUE);
2278 }
2279
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002280 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002281
2282 if (context)
2283 {
2284 for (int i = 0; i < n; i++)
2285 {
2286 framebuffers[i] = context->createFramebuffer();
2287 }
2288 }
2289 }
2290 catch(std::bad_alloc&)
2291 {
2292 return error(GL_OUT_OF_MEMORY);
2293 }
2294}
2295
2296void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2297{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002298 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002299
2300 try
2301 {
2302 if (n < 0)
2303 {
2304 return error(GL_INVALID_VALUE);
2305 }
2306
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002307 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002308
2309 if (context)
2310 {
2311 for (int i = 0; i < n; i++)
2312 {
2313 renderbuffers[i] = context->createRenderbuffer();
2314 }
2315 }
2316 }
2317 catch(std::bad_alloc&)
2318 {
2319 return error(GL_OUT_OF_MEMORY);
2320 }
2321}
2322
2323void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2324{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002325 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002326
2327 try
2328 {
2329 if (n < 0)
2330 {
2331 return error(GL_INVALID_VALUE);
2332 }
2333
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002334 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002335
2336 if (context)
2337 {
2338 for (int i = 0; i < n; i++)
2339 {
2340 textures[i] = context->createTexture();
2341 }
2342 }
2343 }
2344 catch(std::bad_alloc&)
2345 {
2346 return error(GL_OUT_OF_MEMORY);
2347 }
2348}
2349
daniel@transgaming.com85423182010-04-22 13:35:27 +00002350void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002351{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002352 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002353 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002354 program, index, bufsize, length, size, type, name);
2355
2356 try
2357 {
2358 if (bufsize < 0)
2359 {
2360 return error(GL_INVALID_VALUE);
2361 }
2362
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002363 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com85423182010-04-22 13:35:27 +00002364
2365 if (context)
2366 {
2367 gl::Program *programObject = context->getProgram(program);
2368
2369 if (!programObject)
2370 {
2371 if (context->getShader(program))
2372 {
2373 return error(GL_INVALID_OPERATION);
2374 }
2375 else
2376 {
2377 return error(GL_INVALID_VALUE);
2378 }
2379 }
2380
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002381 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002382 {
2383 return error(GL_INVALID_VALUE);
2384 }
2385
2386 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2387 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002388 }
2389 catch(std::bad_alloc&)
2390 {
2391 return error(GL_OUT_OF_MEMORY);
2392 }
2393}
2394
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002395void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002396{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002397 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002398 "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 +00002399 program, index, bufsize, length, size, type, name);
2400
2401 try
2402 {
2403 if (bufsize < 0)
2404 {
2405 return error(GL_INVALID_VALUE);
2406 }
2407
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002408 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002409
2410 if (context)
2411 {
2412 gl::Program *programObject = context->getProgram(program);
2413
2414 if (!programObject)
2415 {
2416 if (context->getShader(program))
2417 {
2418 return error(GL_INVALID_OPERATION);
2419 }
2420 else
2421 {
2422 return error(GL_INVALID_VALUE);
2423 }
2424 }
2425
2426 if (index >= (GLuint)programObject->getActiveUniformCount())
2427 {
2428 return error(GL_INVALID_VALUE);
2429 }
2430
2431 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2432 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002433 }
2434 catch(std::bad_alloc&)
2435 {
2436 return error(GL_OUT_OF_MEMORY);
2437 }
2438}
2439
2440void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2441{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002442 EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002443 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002444
2445 try
2446 {
2447 if (maxcount < 0)
2448 {
2449 return error(GL_INVALID_VALUE);
2450 }
2451
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002452 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002453
2454 if (context)
2455 {
2456 gl::Program *programObject = context->getProgram(program);
2457
2458 if (!programObject)
2459 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002460 if (context->getShader(program))
2461 {
2462 return error(GL_INVALID_OPERATION);
2463 }
2464 else
2465 {
2466 return error(GL_INVALID_VALUE);
2467 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002468 }
2469
2470 return programObject->getAttachedShaders(maxcount, count, shaders);
2471 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002472 }
2473 catch(std::bad_alloc&)
2474 {
2475 return error(GL_OUT_OF_MEMORY);
2476 }
2477}
2478
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002479int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002480{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002481 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002482
2483 try
2484 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002485 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002486
2487 if (context)
2488 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002489
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002490 gl::Program *programObject = context->getProgram(program);
2491
2492 if (!programObject)
2493 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002494 if (context->getShader(program))
2495 {
2496 return error(GL_INVALID_OPERATION, -1);
2497 }
2498 else
2499 {
2500 return error(GL_INVALID_VALUE, -1);
2501 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002502 }
2503
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002504 if (!programObject->isLinked())
2505 {
2506 return error(GL_INVALID_OPERATION, -1);
2507 }
2508
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002509 return programObject->getAttributeLocation(name);
2510 }
2511 }
2512 catch(std::bad_alloc&)
2513 {
2514 return error(GL_OUT_OF_MEMORY, -1);
2515 }
2516
2517 return -1;
2518}
2519
2520void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2521{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002522 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002523
2524 try
2525 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002526 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002527
2528 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002529 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002530 if (!(context->getBooleanv(pname, params)))
2531 {
2532 GLenum nativeType;
2533 unsigned int numParams = 0;
2534 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2535 return error(GL_INVALID_ENUM);
2536
2537 if (numParams == 0)
2538 return; // it is known that the pname is valid, but there are no parameters to return
2539
2540 if (nativeType == GL_FLOAT)
2541 {
2542 GLfloat *floatParams = NULL;
2543 floatParams = new GLfloat[numParams];
2544
2545 context->getFloatv(pname, floatParams);
2546
2547 for (unsigned int i = 0; i < numParams; ++i)
2548 {
2549 if (floatParams[i] == 0.0f)
2550 params[i] = GL_FALSE;
2551 else
2552 params[i] = GL_TRUE;
2553 }
2554
2555 delete [] floatParams;
2556 }
2557 else if (nativeType == GL_INT)
2558 {
2559 GLint *intParams = NULL;
2560 intParams = new GLint[numParams];
2561
2562 context->getIntegerv(pname, intParams);
2563
2564 for (unsigned int i = 0; i < numParams; ++i)
2565 {
2566 if (intParams[i] == 0)
2567 params[i] = GL_FALSE;
2568 else
2569 params[i] = GL_TRUE;
2570 }
2571
2572 delete [] intParams;
2573 }
2574 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002575 }
2576 }
2577 catch(std::bad_alloc&)
2578 {
2579 return error(GL_OUT_OF_MEMORY);
2580 }
2581}
2582
2583void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2584{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002585 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002586
2587 try
2588 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002589 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002590
2591 if (context)
2592 {
2593 gl::Buffer *buffer;
2594
2595 switch (target)
2596 {
2597 case GL_ARRAY_BUFFER:
2598 buffer = context->getArrayBuffer();
2599 break;
2600 case GL_ELEMENT_ARRAY_BUFFER:
2601 buffer = context->getElementArrayBuffer();
2602 break;
2603 default: return error(GL_INVALID_ENUM);
2604 }
2605
2606 if (!buffer)
2607 {
2608 // A null buffer means that "0" is bound to the requested buffer target
2609 return error(GL_INVALID_OPERATION);
2610 }
2611
2612 switch (pname)
2613 {
2614 case GL_BUFFER_USAGE:
2615 *params = buffer->usage();
2616 break;
2617 case GL_BUFFER_SIZE:
2618 *params = buffer->size();
2619 break;
2620 default: return error(GL_INVALID_ENUM);
2621 }
2622 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002623 }
2624 catch(std::bad_alloc&)
2625 {
2626 return error(GL_OUT_OF_MEMORY);
2627 }
2628}
2629
2630GLenum __stdcall glGetError(void)
2631{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002632 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002633
2634 gl::Context *context = gl::getContext();
2635
2636 if (context)
2637 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002638 if (context->isContextLost())
2639 return GL_OUT_OF_MEMORY;
2640 else
2641 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002642 }
2643
2644 return GL_NO_ERROR;
2645}
2646
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002647void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2648{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002649 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002650
2651 try
2652 {
2653
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002654 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002655
2656 if (context)
2657 {
2658 gl::Fence *fenceObject = context->getFence(fence);
2659
2660 if (fenceObject == NULL)
2661 {
2662 return error(GL_INVALID_OPERATION);
2663 }
2664
2665 fenceObject->getFenceiv(pname, params);
2666 }
2667 }
2668 catch(std::bad_alloc&)
2669 {
2670 return error(GL_OUT_OF_MEMORY);
2671 }
2672}
2673
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002674void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2675{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002676 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002677
2678 try
2679 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002680 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002681
2682 if (context)
2683 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002684 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002685 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002686 GLenum nativeType;
2687 unsigned int numParams = 0;
2688 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2689 return error(GL_INVALID_ENUM);
2690
2691 if (numParams == 0)
2692 return; // it is known that the pname is valid, but that there are no parameters to return.
2693
2694 if (nativeType == GL_BOOL)
2695 {
2696 GLboolean *boolParams = NULL;
2697 boolParams = new GLboolean[numParams];
2698
2699 context->getBooleanv(pname, boolParams);
2700
2701 for (unsigned int i = 0; i < numParams; ++i)
2702 {
2703 if (boolParams[i] == GL_FALSE)
2704 params[i] = 0.0f;
2705 else
2706 params[i] = 1.0f;
2707 }
2708
2709 delete [] boolParams;
2710 }
2711 else if (nativeType == GL_INT)
2712 {
2713 GLint *intParams = NULL;
2714 intParams = new GLint[numParams];
2715
2716 context->getIntegerv(pname, intParams);
2717
2718 for (unsigned int i = 0; i < numParams; ++i)
2719 {
2720 params[i] = (GLfloat)intParams[i];
2721 }
2722
2723 delete [] intParams;
2724 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002725 }
2726 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002727 }
2728 catch(std::bad_alloc&)
2729 {
2730 return error(GL_OUT_OF_MEMORY);
2731 }
2732}
2733
2734void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2735{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002736 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002737 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002738
2739 try
2740 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002741 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002742
2743 if (context)
2744 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002745 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002746 {
2747 return error(GL_INVALID_ENUM);
2748 }
2749
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002750 gl::Framebuffer *framebuffer = NULL;
2751 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2752 {
2753 if(context->getReadFramebufferHandle() == 0)
2754 {
2755 return error(GL_INVALID_OPERATION);
2756 }
2757
2758 framebuffer = context->getReadFramebuffer();
2759 }
2760 else
2761 {
2762 if (context->getDrawFramebufferHandle() == 0)
2763 {
2764 return error(GL_INVALID_OPERATION);
2765 }
2766
2767 framebuffer = context->getDrawFramebuffer();
2768 }
2769
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002770 GLenum attachmentType;
2771 GLuint attachmentHandle;
2772 switch (attachment)
2773 {
2774 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002775 attachmentType = framebuffer->getColorbufferType();
2776 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002777 break;
2778 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002779 attachmentType = framebuffer->getDepthbufferType();
2780 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002781 break;
2782 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002783 attachmentType = framebuffer->getStencilbufferType();
2784 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002785 break;
2786 default: return error(GL_INVALID_ENUM);
2787 }
2788
2789 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002790 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002791 {
2792 attachmentObjectType = attachmentType;
2793 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002794 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002795 {
2796 attachmentObjectType = GL_TEXTURE;
2797 }
2798 else UNREACHABLE();
2799
2800 switch (pname)
2801 {
2802 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2803 *params = attachmentObjectType;
2804 break;
2805 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2806 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2807 {
2808 *params = attachmentHandle;
2809 }
2810 else
2811 {
2812 return error(GL_INVALID_ENUM);
2813 }
2814 break;
2815 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2816 if (attachmentObjectType == GL_TEXTURE)
2817 {
2818 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2819 }
2820 else
2821 {
2822 return error(GL_INVALID_ENUM);
2823 }
2824 break;
2825 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2826 if (attachmentObjectType == GL_TEXTURE)
2827 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002828 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002829 {
2830 *params = attachmentType;
2831 }
2832 else
2833 {
2834 *params = 0;
2835 }
2836 }
2837 else
2838 {
2839 return error(GL_INVALID_ENUM);
2840 }
2841 break;
2842 default:
2843 return error(GL_INVALID_ENUM);
2844 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002845 }
2846 }
2847 catch(std::bad_alloc&)
2848 {
2849 return error(GL_OUT_OF_MEMORY);
2850 }
2851}
2852
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00002853GLenum __stdcall glGetGraphicsResetStatusEXT(void)
2854{
2855 EVENT("()");
2856
2857 try
2858 {
2859 gl::Context *context = gl::getContext();
2860
2861 if (context)
2862 {
2863 return context->getResetStatus();
2864 }
2865
2866 return GL_NO_ERROR;
2867 }
2868 catch(std::bad_alloc&)
2869 {
2870 return GL_OUT_OF_MEMORY;
2871 }
2872}
2873
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002874void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2875{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002876 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002877
2878 try
2879 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002880 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002881
2882 if (context)
2883 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002884 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002885 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002886 GLenum nativeType;
2887 unsigned int numParams = 0;
2888 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2889 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002890
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002891 if (numParams == 0)
2892 return; // it is known that pname is valid, but there are no parameters to return
2893
2894 if (nativeType == GL_BOOL)
2895 {
2896 GLboolean *boolParams = NULL;
2897 boolParams = new GLboolean[numParams];
2898
2899 context->getBooleanv(pname, boolParams);
2900
2901 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002902 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002903 if (boolParams[i] == GL_FALSE)
2904 params[i] = 0;
2905 else
2906 params[i] = 1;
2907 }
2908
2909 delete [] boolParams;
2910 }
2911 else if (nativeType == GL_FLOAT)
2912 {
2913 GLfloat *floatParams = NULL;
2914 floatParams = new GLfloat[numParams];
2915
2916 context->getFloatv(pname, floatParams);
2917
2918 for (unsigned int i = 0; i < numParams; ++i)
2919 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002920 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 +00002921 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002922 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002923 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002924 else
2925 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 +00002926 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002927
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002928 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002929 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002930 }
2931 }
2932 }
2933 catch(std::bad_alloc&)
2934 {
2935 return error(GL_OUT_OF_MEMORY);
2936 }
2937}
2938
2939void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2940{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002941 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002942
2943 try
2944 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002945 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002946
2947 if (context)
2948 {
2949 gl::Program *programObject = context->getProgram(program);
2950
2951 if (!programObject)
2952 {
2953 return error(GL_INVALID_VALUE);
2954 }
2955
2956 switch (pname)
2957 {
2958 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002959 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002960 return;
2961 case GL_LINK_STATUS:
2962 *params = programObject->isLinked();
2963 return;
2964 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002965 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002966 return;
2967 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002968 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002969 return;
2970 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002971 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002972 return;
2973 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002974 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002975 return;
2976 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002977 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002978 return;
2979 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002980 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002981 return;
2982 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002983 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002984 return;
2985 default:
2986 return error(GL_INVALID_ENUM);
2987 }
2988 }
2989 }
2990 catch(std::bad_alloc&)
2991 {
2992 return error(GL_OUT_OF_MEMORY);
2993 }
2994}
2995
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002996void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002997{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002998 EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002999 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003000
3001 try
3002 {
3003 if (bufsize < 0)
3004 {
3005 return error(GL_INVALID_VALUE);
3006 }
3007
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003008 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003009
3010 if (context)
3011 {
3012 gl::Program *programObject = context->getProgram(program);
3013
3014 if (!programObject)
3015 {
3016 return error(GL_INVALID_VALUE);
3017 }
3018
3019 programObject->getInfoLog(bufsize, length, infolog);
3020 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003021 }
3022 catch(std::bad_alloc&)
3023 {
3024 return error(GL_OUT_OF_MEMORY);
3025 }
3026}
3027
3028void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3029{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003030 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003031
3032 try
3033 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003034 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003035
3036 if (context)
3037 {
3038 if (target != GL_RENDERBUFFER)
3039 {
3040 return error(GL_INVALID_ENUM);
3041 }
3042
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003043 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003044 {
3045 return error(GL_INVALID_OPERATION);
3046 }
3047
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003048 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003049
3050 switch (pname)
3051 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003052 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3053 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3054 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3055 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3056 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3057 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3058 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3059 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3060 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003061 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003062 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003063 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003064 *params = renderbuffer->getSamples();
3065 }
3066 else
3067 {
3068 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003069 }
3070 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003071 default:
3072 return error(GL_INVALID_ENUM);
3073 }
3074 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003075 }
3076 catch(std::bad_alloc&)
3077 {
3078 return error(GL_OUT_OF_MEMORY);
3079 }
3080}
3081
3082void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3083{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003084 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003085
3086 try
3087 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003088 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003089
3090 if (context)
3091 {
3092 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003093
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003094 if (!shaderObject)
3095 {
3096 return error(GL_INVALID_VALUE);
3097 }
3098
3099 switch (pname)
3100 {
3101 case GL_SHADER_TYPE:
3102 *params = shaderObject->getType();
3103 return;
3104 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003105 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003106 return;
3107 case GL_COMPILE_STATUS:
3108 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3109 return;
3110 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003111 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003112 return;
3113 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003114 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003115 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003116 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3117 *params = shaderObject->getTranslatedSourceLength();
3118 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003119 default:
3120 return error(GL_INVALID_ENUM);
3121 }
3122 }
3123 }
3124 catch(std::bad_alloc&)
3125 {
3126 return error(GL_OUT_OF_MEMORY);
3127 }
3128}
3129
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003130void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003131{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003132 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003133 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003134
3135 try
3136 {
3137 if (bufsize < 0)
3138 {
3139 return error(GL_INVALID_VALUE);
3140 }
3141
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003142 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003143
3144 if (context)
3145 {
3146 gl::Shader *shaderObject = context->getShader(shader);
3147
3148 if (!shaderObject)
3149 {
3150 return error(GL_INVALID_VALUE);
3151 }
3152
3153 shaderObject->getInfoLog(bufsize, length, infolog);
3154 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003155 }
3156 catch(std::bad_alloc&)
3157 {
3158 return error(GL_OUT_OF_MEMORY);
3159 }
3160}
3161
3162void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3163{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003164 EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003165 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003166
3167 try
3168 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003169 switch (shadertype)
3170 {
3171 case GL_VERTEX_SHADER:
3172 case GL_FRAGMENT_SHADER:
3173 break;
3174 default:
3175 return error(GL_INVALID_ENUM);
3176 }
3177
3178 switch (precisiontype)
3179 {
3180 case GL_LOW_FLOAT:
3181 case GL_MEDIUM_FLOAT:
3182 case GL_HIGH_FLOAT:
3183 // Assume IEEE 754 precision
3184 range[0] = 127;
3185 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003186 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003187 break;
3188 case GL_LOW_INT:
3189 case GL_MEDIUM_INT:
3190 case GL_HIGH_INT:
3191 // Some (most) hardware only supports single-precision floating-point numbers,
3192 // which can accurately represent integers up to +/-16777216
3193 range[0] = 24;
3194 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003195 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003196 break;
3197 default:
3198 return error(GL_INVALID_ENUM);
3199 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003200 }
3201 catch(std::bad_alloc&)
3202 {
3203 return error(GL_OUT_OF_MEMORY);
3204 }
3205}
3206
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003207void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003208{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003209 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003210 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003211
3212 try
3213 {
3214 if (bufsize < 0)
3215 {
3216 return error(GL_INVALID_VALUE);
3217 }
3218
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003219 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003220
3221 if (context)
3222 {
3223 gl::Shader *shaderObject = context->getShader(shader);
3224
3225 if (!shaderObject)
3226 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003227 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003228 }
3229
3230 shaderObject->getSource(bufsize, length, source);
3231 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003232 }
3233 catch(std::bad_alloc&)
3234 {
3235 return error(GL_OUT_OF_MEMORY);
3236 }
3237}
3238
zmo@google.coma574f782011-10-03 21:45:23 +00003239void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3240{
3241 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3242 shader, bufsize, length, source);
3243
3244 try
3245 {
3246 if (bufsize < 0)
3247 {
3248 return error(GL_INVALID_VALUE);
3249 }
3250
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003251 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003252
3253 if (context)
3254 {
3255 gl::Shader *shaderObject = context->getShader(shader);
3256
3257 if (!shaderObject)
3258 {
3259 return error(GL_INVALID_OPERATION);
3260 }
3261
3262 shaderObject->getTranslatedSource(bufsize, length, source);
3263 }
3264 }
3265 catch(std::bad_alloc&)
3266 {
3267 return error(GL_OUT_OF_MEMORY);
3268 }
3269}
3270
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003271const GLubyte* __stdcall glGetString(GLenum name)
3272{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003273 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003274
3275 try
3276 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003277 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003278
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003279 switch (name)
3280 {
3281 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003282 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003283 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003284 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003285 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003286 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003287 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003288 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003289 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003290 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003291 default:
3292 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3293 }
3294 }
3295 catch(std::bad_alloc&)
3296 {
3297 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3298 }
3299
3300 return NULL;
3301}
3302
3303void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3304{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003305 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003306
3307 try
3308 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003309 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003310
3311 if (context)
3312 {
3313 gl::Texture *texture;
3314
3315 switch (target)
3316 {
3317 case GL_TEXTURE_2D:
3318 texture = context->getTexture2D();
3319 break;
3320 case GL_TEXTURE_CUBE_MAP:
3321 texture = context->getTextureCubeMap();
3322 break;
3323 default:
3324 return error(GL_INVALID_ENUM);
3325 }
3326
3327 switch (pname)
3328 {
3329 case GL_TEXTURE_MAG_FILTER:
3330 *params = (GLfloat)texture->getMagFilter();
3331 break;
3332 case GL_TEXTURE_MIN_FILTER:
3333 *params = (GLfloat)texture->getMinFilter();
3334 break;
3335 case GL_TEXTURE_WRAP_S:
3336 *params = (GLfloat)texture->getWrapS();
3337 break;
3338 case GL_TEXTURE_WRAP_T:
3339 *params = (GLfloat)texture->getWrapT();
3340 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003341 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3342 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3343 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003344 default:
3345 return error(GL_INVALID_ENUM);
3346 }
3347 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003348 }
3349 catch(std::bad_alloc&)
3350 {
3351 return error(GL_OUT_OF_MEMORY);
3352 }
3353}
3354
3355void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3356{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003357 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003358
3359 try
3360 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003361 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003362
3363 if (context)
3364 {
3365 gl::Texture *texture;
3366
3367 switch (target)
3368 {
3369 case GL_TEXTURE_2D:
3370 texture = context->getTexture2D();
3371 break;
3372 case GL_TEXTURE_CUBE_MAP:
3373 texture = context->getTextureCubeMap();
3374 break;
3375 default:
3376 return error(GL_INVALID_ENUM);
3377 }
3378
3379 switch (pname)
3380 {
3381 case GL_TEXTURE_MAG_FILTER:
3382 *params = texture->getMagFilter();
3383 break;
3384 case GL_TEXTURE_MIN_FILTER:
3385 *params = texture->getMinFilter();
3386 break;
3387 case GL_TEXTURE_WRAP_S:
3388 *params = texture->getWrapS();
3389 break;
3390 case GL_TEXTURE_WRAP_T:
3391 *params = texture->getWrapT();
3392 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003393 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3394 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3395 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003396 default:
3397 return error(GL_INVALID_ENUM);
3398 }
3399 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003400 }
3401 catch(std::bad_alloc&)
3402 {
3403 return error(GL_OUT_OF_MEMORY);
3404 }
3405}
3406
3407void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3408{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003409 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003410
3411 try
3412 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003413 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003414
3415 if (context)
3416 {
3417 if (program == 0)
3418 {
3419 return error(GL_INVALID_VALUE);
3420 }
3421
3422 gl::Program *programObject = context->getProgram(program);
3423
3424 if (!programObject || !programObject->isLinked())
3425 {
3426 return error(GL_INVALID_OPERATION);
3427 }
3428
3429 if (!programObject->getUniformfv(location, params))
3430 {
3431 return error(GL_INVALID_OPERATION);
3432 }
3433 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003434 }
3435 catch(std::bad_alloc&)
3436 {
3437 return error(GL_OUT_OF_MEMORY);
3438 }
3439}
3440
3441void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3442{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003443 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003444
3445 try
3446 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003447 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003448
3449 if (context)
3450 {
3451 if (program == 0)
3452 {
3453 return error(GL_INVALID_VALUE);
3454 }
3455
3456 gl::Program *programObject = context->getProgram(program);
3457
3458 if (!programObject || !programObject->isLinked())
3459 {
3460 return error(GL_INVALID_OPERATION);
3461 }
3462
3463 if (!programObject)
3464 {
3465 return error(GL_INVALID_OPERATION);
3466 }
3467
3468 if (!programObject->getUniformiv(location, params))
3469 {
3470 return error(GL_INVALID_OPERATION);
3471 }
3472 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003473 }
3474 catch(std::bad_alloc&)
3475 {
3476 return error(GL_OUT_OF_MEMORY);
3477 }
3478}
3479
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003480int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003481{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003482 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003483
3484 try
3485 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003486 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003487
3488 if (strstr(name, "gl_") == name)
3489 {
3490 return -1;
3491 }
3492
3493 if (context)
3494 {
3495 gl::Program *programObject = context->getProgram(program);
3496
3497 if (!programObject)
3498 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003499 if (context->getShader(program))
3500 {
3501 return error(GL_INVALID_OPERATION, -1);
3502 }
3503 else
3504 {
3505 return error(GL_INVALID_VALUE, -1);
3506 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003507 }
3508
3509 if (!programObject->isLinked())
3510 {
3511 return error(GL_INVALID_OPERATION, -1);
3512 }
3513
daniel@transgaming.com024f1a92011-09-20 16:06:25 +00003514 return programObject->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003515 }
3516 }
3517 catch(std::bad_alloc&)
3518 {
3519 return error(GL_OUT_OF_MEMORY, -1);
3520 }
3521
3522 return -1;
3523}
3524
3525void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3526{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003527 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003528
3529 try
3530 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003531 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003532
daniel@transgaming.come0078962010-04-15 20:45:08 +00003533 if (context)
3534 {
3535 if (index >= gl::MAX_VERTEX_ATTRIBS)
3536 {
3537 return error(GL_INVALID_VALUE);
3538 }
3539
daniel@transgaming.com83921382011-01-08 05:46:00 +00003540 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003541
daniel@transgaming.come0078962010-04-15 20:45:08 +00003542 switch (pname)
3543 {
3544 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003545 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003546 break;
3547 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003548 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003549 break;
3550 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003551 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003552 break;
3553 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003554 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003555 break;
3556 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003557 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003558 break;
3559 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003560 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003561 break;
3562 case GL_CURRENT_VERTEX_ATTRIB:
3563 for (int i = 0; i < 4; ++i)
3564 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003565 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003566 }
3567 break;
3568 default: return error(GL_INVALID_ENUM);
3569 }
3570 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003571 }
3572 catch(std::bad_alloc&)
3573 {
3574 return error(GL_OUT_OF_MEMORY);
3575 }
3576}
3577
3578void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3579{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003580 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003581
3582 try
3583 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003584 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003585
daniel@transgaming.come0078962010-04-15 20:45:08 +00003586 if (context)
3587 {
3588 if (index >= gl::MAX_VERTEX_ATTRIBS)
3589 {
3590 return error(GL_INVALID_VALUE);
3591 }
3592
daniel@transgaming.com83921382011-01-08 05:46:00 +00003593 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003594
daniel@transgaming.come0078962010-04-15 20:45:08 +00003595 switch (pname)
3596 {
3597 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003598 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003599 break;
3600 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003601 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003602 break;
3603 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003604 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003605 break;
3606 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003607 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003608 break;
3609 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003610 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003611 break;
3612 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003613 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003614 break;
3615 case GL_CURRENT_VERTEX_ATTRIB:
3616 for (int i = 0; i < 4; ++i)
3617 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003618 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003619 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3620 }
3621 break;
3622 default: return error(GL_INVALID_ENUM);
3623 }
3624 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003625 }
3626 catch(std::bad_alloc&)
3627 {
3628 return error(GL_OUT_OF_MEMORY);
3629 }
3630}
3631
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003632void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003633{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003634 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003635
3636 try
3637 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003638 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003639
daniel@transgaming.come0078962010-04-15 20:45:08 +00003640 if (context)
3641 {
3642 if (index >= gl::MAX_VERTEX_ATTRIBS)
3643 {
3644 return error(GL_INVALID_VALUE);
3645 }
3646
3647 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3648 {
3649 return error(GL_INVALID_ENUM);
3650 }
3651
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003652 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003653 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003654 }
3655 catch(std::bad_alloc&)
3656 {
3657 return error(GL_OUT_OF_MEMORY);
3658 }
3659}
3660
3661void __stdcall glHint(GLenum target, GLenum mode)
3662{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003663 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003664
3665 try
3666 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003667 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003668 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003669 case GL_FASTEST:
3670 case GL_NICEST:
3671 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003672 break;
3673 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003674 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003675 }
3676
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003677 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003678 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003679 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003680 case GL_GENERATE_MIPMAP_HINT:
3681 if (context) context->setGenerateMipmapHint(mode);
3682 break;
3683 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3684 if (context) context->setFragmentShaderDerivativeHint(mode);
3685 break;
3686 default:
3687 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003688 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003689 }
3690 catch(std::bad_alloc&)
3691 {
3692 return error(GL_OUT_OF_MEMORY);
3693 }
3694}
3695
3696GLboolean __stdcall glIsBuffer(GLuint buffer)
3697{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003698 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003699
3700 try
3701 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003702 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003703
3704 if (context && buffer)
3705 {
3706 gl::Buffer *bufferObject = context->getBuffer(buffer);
3707
3708 if (bufferObject)
3709 {
3710 return GL_TRUE;
3711 }
3712 }
3713 }
3714 catch(std::bad_alloc&)
3715 {
3716 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3717 }
3718
3719 return GL_FALSE;
3720}
3721
3722GLboolean __stdcall glIsEnabled(GLenum cap)
3723{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003724 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003725
3726 try
3727 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003728 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003729
3730 if (context)
3731 {
3732 switch (cap)
3733 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003734 case GL_CULL_FACE: return context->isCullFaceEnabled();
3735 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3736 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3737 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3738 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3739 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3740 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3741 case GL_BLEND: return context->isBlendEnabled();
3742 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003743 default:
3744 return error(GL_INVALID_ENUM, false);
3745 }
3746 }
3747 }
3748 catch(std::bad_alloc&)
3749 {
3750 return error(GL_OUT_OF_MEMORY, false);
3751 }
3752
3753 return false;
3754}
3755
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003756GLboolean __stdcall glIsFenceNV(GLuint fence)
3757{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003758 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003759
3760 try
3761 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003762 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003763
3764 if (context)
3765 {
3766 gl::Fence *fenceObject = context->getFence(fence);
3767
3768 if (fenceObject == NULL)
3769 {
3770 return GL_FALSE;
3771 }
3772
3773 return fenceObject->isFence();
3774 }
3775 }
3776 catch(std::bad_alloc&)
3777 {
3778 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3779 }
3780
3781 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003782}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003783
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003784GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3785{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003786 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003787
3788 try
3789 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003790 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003791
3792 if (context && framebuffer)
3793 {
3794 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3795
3796 if (framebufferObject)
3797 {
3798 return GL_TRUE;
3799 }
3800 }
3801 }
3802 catch(std::bad_alloc&)
3803 {
3804 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3805 }
3806
3807 return GL_FALSE;
3808}
3809
3810GLboolean __stdcall glIsProgram(GLuint program)
3811{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003812 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003813
3814 try
3815 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003816 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003817
3818 if (context && program)
3819 {
3820 gl::Program *programObject = context->getProgram(program);
3821
3822 if (programObject)
3823 {
3824 return GL_TRUE;
3825 }
3826 }
3827 }
3828 catch(std::bad_alloc&)
3829 {
3830 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3831 }
3832
3833 return GL_FALSE;
3834}
3835
3836GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3837{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003838 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003839
3840 try
3841 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003842 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003843
3844 if (context && renderbuffer)
3845 {
3846 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3847
3848 if (renderbufferObject)
3849 {
3850 return GL_TRUE;
3851 }
3852 }
3853 }
3854 catch(std::bad_alloc&)
3855 {
3856 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3857 }
3858
3859 return GL_FALSE;
3860}
3861
3862GLboolean __stdcall glIsShader(GLuint shader)
3863{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003864 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003865
3866 try
3867 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003868 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003869
3870 if (context && shader)
3871 {
3872 gl::Shader *shaderObject = context->getShader(shader);
3873
3874 if (shaderObject)
3875 {
3876 return GL_TRUE;
3877 }
3878 }
3879 }
3880 catch(std::bad_alloc&)
3881 {
3882 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3883 }
3884
3885 return GL_FALSE;
3886}
3887
3888GLboolean __stdcall glIsTexture(GLuint texture)
3889{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003890 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003891
3892 try
3893 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003894 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003895
3896 if (context && texture)
3897 {
3898 gl::Texture *textureObject = context->getTexture(texture);
3899
3900 if (textureObject)
3901 {
3902 return GL_TRUE;
3903 }
3904 }
3905 }
3906 catch(std::bad_alloc&)
3907 {
3908 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3909 }
3910
3911 return GL_FALSE;
3912}
3913
3914void __stdcall glLineWidth(GLfloat width)
3915{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003916 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003917
3918 try
3919 {
3920 if (width <= 0.0f)
3921 {
3922 return error(GL_INVALID_VALUE);
3923 }
3924
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003925 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003926
3927 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003928 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003929 context->setLineWidth(width);
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 glLinkProgram(GLuint program)
3939{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003940 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003941
3942 try
3943 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003944 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003945
3946 if (context)
3947 {
3948 gl::Program *programObject = context->getProgram(program);
3949
3950 if (!programObject)
3951 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003952 if (context->getShader(program))
3953 {
3954 return error(GL_INVALID_OPERATION);
3955 }
3956 else
3957 {
3958 return error(GL_INVALID_VALUE);
3959 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003960 }
3961
3962 programObject->link();
3963 }
3964 }
3965 catch(std::bad_alloc&)
3966 {
3967 return error(GL_OUT_OF_MEMORY);
3968 }
3969}
3970
3971void __stdcall glPixelStorei(GLenum pname, GLint param)
3972{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003973 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003974
3975 try
3976 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003977 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003978
3979 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003980 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003981 switch (pname)
3982 {
3983 case GL_UNPACK_ALIGNMENT:
3984 if (param != 1 && param != 2 && param != 4 && param != 8)
3985 {
3986 return error(GL_INVALID_VALUE);
3987 }
3988
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003989 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003990 break;
3991
3992 case GL_PACK_ALIGNMENT:
3993 if (param != 1 && param != 2 && param != 4 && param != 8)
3994 {
3995 return error(GL_INVALID_VALUE);
3996 }
3997
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003998 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003999 break;
4000
4001 default:
4002 return error(GL_INVALID_ENUM);
4003 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004004 }
4005 }
4006 catch(std::bad_alloc&)
4007 {
4008 return error(GL_OUT_OF_MEMORY);
4009 }
4010}
4011
4012void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4013{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004014 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004015
4016 try
4017 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004018 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004019
4020 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004021 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004022 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004023 }
4024 }
4025 catch(std::bad_alloc&)
4026 {
4027 return error(GL_OUT_OF_MEMORY);
4028 }
4029}
4030
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004031void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004032{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004033 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004034 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004035 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004036
4037 try
4038 {
4039 if (width < 0 || height < 0)
4040 {
4041 return error(GL_INVALID_VALUE);
4042 }
4043
4044 switch (format)
4045 {
4046 case GL_RGBA:
4047 switch (type)
4048 {
4049 case GL_UNSIGNED_BYTE:
4050 break;
4051 default:
4052 return error(GL_INVALID_OPERATION);
4053 }
4054 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004055 case GL_BGRA_EXT:
4056 switch (type)
4057 {
4058 case GL_UNSIGNED_BYTE:
4059 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
4060 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
4061 break;
4062 default:
4063 return error(GL_INVALID_OPERATION);
4064 }
4065 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004066 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
4067 switch (type)
4068 {
4069 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
4070 break;
4071 default:
4072 return error(GL_INVALID_OPERATION);
4073 }
4074 break;
4075 default:
4076 return error(GL_INVALID_OPERATION);
4077 }
4078
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004079 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004080
4081 if (context)
4082 {
4083 context->readPixels(x, y, width, height, format, type, pixels);
4084 }
4085 }
4086 catch(std::bad_alloc&)
4087 {
4088 return error(GL_OUT_OF_MEMORY);
4089 }
4090}
4091
4092void __stdcall glReleaseShaderCompiler(void)
4093{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004094 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004095
4096 try
4097 {
4098 gl::Shader::releaseCompiler();
4099 }
4100 catch(std::bad_alloc&)
4101 {
4102 return error(GL_OUT_OF_MEMORY);
4103 }
4104}
4105
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004106void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004107{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004108 EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004109 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004110
4111 try
4112 {
4113 switch (target)
4114 {
4115 case GL_RENDERBUFFER:
4116 break;
4117 default:
4118 return error(GL_INVALID_ENUM);
4119 }
4120
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004121 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004122 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004123 return error(GL_INVALID_ENUM);
4124 }
4125
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004126 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004127 {
4128 return error(GL_INVALID_VALUE);
4129 }
4130
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004131 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004132
4133 if (context)
4134 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004135 if (width > context->getMaximumRenderbufferDimension() ||
4136 height > context->getMaximumRenderbufferDimension() ||
4137 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004138 {
4139 return error(GL_INVALID_VALUE);
4140 }
4141
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004142 GLuint handle = context->getRenderbufferHandle();
4143 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004144 {
4145 return error(GL_INVALID_OPERATION);
4146 }
4147
4148 switch (internalformat)
4149 {
4150 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004151 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004152 break;
4153 case GL_RGBA4:
4154 case GL_RGB5_A1:
4155 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004156 case GL_RGB8_OES:
4157 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004158 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004159 break;
4160 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004161 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004162 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004163 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004164 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004165 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004166 default:
4167 return error(GL_INVALID_ENUM);
4168 }
4169 }
4170 }
4171 catch(std::bad_alloc&)
4172 {
4173 return error(GL_OUT_OF_MEMORY);
4174 }
4175}
4176
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004177void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4178{
4179 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4180}
4181
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004182void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4183{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004184 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004185
4186 try
4187 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004188 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004189
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004190 if (context)
4191 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004192 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004193 }
4194 }
4195 catch(std::bad_alloc&)
4196 {
4197 return error(GL_OUT_OF_MEMORY);
4198 }
4199}
4200
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004201void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4202{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004203 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004204
4205 try
4206 {
4207 if (condition != GL_ALL_COMPLETED_NV)
4208 {
4209 return error(GL_INVALID_ENUM);
4210 }
4211
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004212 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004213
4214 if (context)
4215 {
4216 gl::Fence *fenceObject = context->getFence(fence);
4217
4218 if (fenceObject == NULL)
4219 {
4220 return error(GL_INVALID_OPERATION);
4221 }
4222
4223 fenceObject->setFence(condition);
4224 }
4225 }
4226 catch(std::bad_alloc&)
4227 {
4228 return error(GL_OUT_OF_MEMORY);
4229 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004230}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004231
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004232void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4233{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004234 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004235
4236 try
4237 {
4238 if (width < 0 || height < 0)
4239 {
4240 return error(GL_INVALID_VALUE);
4241 }
4242
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004243 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004244
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004245 if (context)
4246 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004247 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004248 }
4249 }
4250 catch(std::bad_alloc&)
4251 {
4252 return error(GL_OUT_OF_MEMORY);
4253 }
4254}
4255
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004256void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004257{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004258 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004259 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004260 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004261
4262 try
4263 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004264 // No binary shader formats are supported.
4265 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004266 }
4267 catch(std::bad_alloc&)
4268 {
4269 return error(GL_OUT_OF_MEMORY);
4270 }
4271}
4272
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004273void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004274{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004275 EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004276 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004277
4278 try
4279 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004280 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004281 {
4282 return error(GL_INVALID_VALUE);
4283 }
4284
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004285 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004286
4287 if (context)
4288 {
4289 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004290
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004291 if (!shaderObject)
4292 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004293 if (context->getProgram(shader))
4294 {
4295 return error(GL_INVALID_OPERATION);
4296 }
4297 else
4298 {
4299 return error(GL_INVALID_VALUE);
4300 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004301 }
4302
4303 shaderObject->setSource(count, string, length);
4304 }
4305 }
4306 catch(std::bad_alloc&)
4307 {
4308 return error(GL_OUT_OF_MEMORY);
4309 }
4310}
4311
4312void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4313{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004314 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004315}
4316
4317void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4318{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004319 EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004320
4321 try
4322 {
4323 switch (face)
4324 {
4325 case GL_FRONT:
4326 case GL_BACK:
4327 case GL_FRONT_AND_BACK:
4328 break;
4329 default:
4330 return error(GL_INVALID_ENUM);
4331 }
4332
4333 switch (func)
4334 {
4335 case GL_NEVER:
4336 case GL_ALWAYS:
4337 case GL_LESS:
4338 case GL_LEQUAL:
4339 case GL_EQUAL:
4340 case GL_GEQUAL:
4341 case GL_GREATER:
4342 case GL_NOTEQUAL:
4343 break;
4344 default:
4345 return error(GL_INVALID_ENUM);
4346 }
4347
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004348 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004349
4350 if (context)
4351 {
4352 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4353 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004354 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004355 }
4356
4357 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4358 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004359 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004360 }
4361 }
4362 }
4363 catch(std::bad_alloc&)
4364 {
4365 return error(GL_OUT_OF_MEMORY);
4366 }
4367}
4368
4369void __stdcall glStencilMask(GLuint mask)
4370{
4371 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4372}
4373
4374void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4375{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004376 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004377
4378 try
4379 {
4380 switch (face)
4381 {
4382 case GL_FRONT:
4383 case GL_BACK:
4384 case GL_FRONT_AND_BACK:
4385 break;
4386 default:
4387 return error(GL_INVALID_ENUM);
4388 }
4389
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004390 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004391
4392 if (context)
4393 {
4394 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4395 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004396 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004397 }
4398
4399 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4400 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004401 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004402 }
4403 }
4404 }
4405 catch(std::bad_alloc&)
4406 {
4407 return error(GL_OUT_OF_MEMORY);
4408 }
4409}
4410
4411void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4412{
4413 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4414}
4415
4416void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4417{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004418 EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004419 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004420
4421 try
4422 {
4423 switch (face)
4424 {
4425 case GL_FRONT:
4426 case GL_BACK:
4427 case GL_FRONT_AND_BACK:
4428 break;
4429 default:
4430 return error(GL_INVALID_ENUM);
4431 }
4432
4433 switch (fail)
4434 {
4435 case GL_ZERO:
4436 case GL_KEEP:
4437 case GL_REPLACE:
4438 case GL_INCR:
4439 case GL_DECR:
4440 case GL_INVERT:
4441 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004442 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004443 break;
4444 default:
4445 return error(GL_INVALID_ENUM);
4446 }
4447
4448 switch (zfail)
4449 {
4450 case GL_ZERO:
4451 case GL_KEEP:
4452 case GL_REPLACE:
4453 case GL_INCR:
4454 case GL_DECR:
4455 case GL_INVERT:
4456 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004457 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004458 break;
4459 default:
4460 return error(GL_INVALID_ENUM);
4461 }
4462
4463 switch (zpass)
4464 {
4465 case GL_ZERO:
4466 case GL_KEEP:
4467 case GL_REPLACE:
4468 case GL_INCR:
4469 case GL_DECR:
4470 case GL_INVERT:
4471 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004472 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004473 break;
4474 default:
4475 return error(GL_INVALID_ENUM);
4476 }
4477
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004478 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004479
4480 if (context)
4481 {
4482 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4483 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004484 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004485 }
4486
4487 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4488 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004489 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004490 }
4491 }
4492 }
4493 catch(std::bad_alloc&)
4494 {
4495 return error(GL_OUT_OF_MEMORY);
4496 }
4497}
4498
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004499GLboolean __stdcall glTestFenceNV(GLuint fence)
4500{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004501 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004502
4503 try
4504 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004505 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004506
4507 if (context)
4508 {
4509 gl::Fence *fenceObject = context->getFence(fence);
4510
4511 if (fenceObject == NULL)
4512 {
4513 return error(GL_INVALID_OPERATION, GL_TRUE);
4514 }
4515
4516 return fenceObject->testFence();
4517 }
4518 }
4519 catch(std::bad_alloc&)
4520 {
4521 error(GL_OUT_OF_MEMORY);
4522 }
4523
4524 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004525}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004526
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004527void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4528 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004529{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004530 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004531 "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 +00004532 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004533
4534 try
4535 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00004536 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004537 {
4538 return error(GL_INVALID_VALUE);
4539 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004540
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004541 if (internalformat != format)
4542 {
4543 return error(GL_INVALID_OPERATION);
4544 }
4545
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004546 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004547 {
4548 case GL_ALPHA:
4549 case GL_LUMINANCE:
4550 case GL_LUMINANCE_ALPHA:
4551 switch (type)
4552 {
4553 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004554 case GL_FLOAT:
4555 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004556 break;
4557 default:
4558 return error(GL_INVALID_ENUM);
4559 }
4560 break;
4561 case GL_RGB:
4562 switch (type)
4563 {
4564 case GL_UNSIGNED_BYTE:
4565 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004566 case GL_FLOAT:
4567 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004568 break;
4569 default:
4570 return error(GL_INVALID_ENUM);
4571 }
4572 break;
4573 case GL_RGBA:
4574 switch (type)
4575 {
4576 case GL_UNSIGNED_BYTE:
4577 case GL_UNSIGNED_SHORT_4_4_4_4:
4578 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004579 case GL_FLOAT:
4580 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004581 break;
4582 default:
4583 return error(GL_INVALID_ENUM);
4584 }
4585 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004586 case GL_BGRA_EXT:
4587 switch (type)
4588 {
4589 case GL_UNSIGNED_BYTE:
4590 break;
4591 default:
4592 return error(GL_INVALID_ENUM);
4593 }
4594 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004595 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4596 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00004597 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4598 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00004599 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004600 default:
4601 return error(GL_INVALID_VALUE);
4602 }
4603
4604 if (border != 0)
4605 {
4606 return error(GL_INVALID_VALUE);
4607 }
4608
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004609 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004610
4611 if (context)
4612 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004613 switch (target)
4614 {
4615 case GL_TEXTURE_2D:
4616 if (width > (context->getMaximumTextureDimension() >> level) ||
4617 height > (context->getMaximumTextureDimension() >> level))
4618 {
4619 return error(GL_INVALID_VALUE);
4620 }
4621 break;
4622 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4623 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4624 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4625 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4626 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4627 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4628 if (width != height)
4629 {
4630 return error(GL_INVALID_VALUE);
4631 }
4632
4633 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4634 height > (context->getMaximumCubeTextureDimension() >> level))
4635 {
4636 return error(GL_INVALID_VALUE);
4637 }
4638 break;
4639 default:
4640 return error(GL_INVALID_ENUM);
4641 }
4642
gman@chromium.org50c526d2011-08-10 05:19:44 +00004643 switch (format) {
4644 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
4645 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4646 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00004647 {
4648 return error(GL_INVALID_OPERATION);
4649 }
4650 else
4651 {
4652 return error(GL_INVALID_ENUM);
4653 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00004654 break;
4655 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4656 if (context->supportsDXT3Textures())
4657 {
4658 return error(GL_INVALID_OPERATION);
4659 }
4660 else
4661 {
4662 return error(GL_INVALID_ENUM);
4663 }
4664 break;
4665 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
4666 if (context->supportsDXT5Textures())
4667 {
4668 return error(GL_INVALID_OPERATION);
4669 }
4670 else
4671 {
4672 return error(GL_INVALID_ENUM);
4673 }
4674 break;
4675 default:
4676 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004677 }
4678
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004679 if (type == GL_FLOAT)
4680 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004681 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004682 {
4683 return error(GL_INVALID_ENUM);
4684 }
4685 }
4686 else if (type == GL_HALF_FLOAT_OES)
4687 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004688 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004689 {
4690 return error(GL_INVALID_ENUM);
4691 }
4692 }
4693
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004694 if (target == GL_TEXTURE_2D)
4695 {
4696 gl::Texture2D *texture = context->getTexture2D();
4697
4698 if (!texture)
4699 {
4700 return error(GL_INVALID_OPERATION);
4701 }
4702
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004703 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004704 }
4705 else
4706 {
4707 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4708
4709 if (!texture)
4710 {
4711 return error(GL_INVALID_OPERATION);
4712 }
4713
4714 switch (target)
4715 {
4716 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004717 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004718 break;
4719 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004720 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004721 break;
4722 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004723 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004724 break;
4725 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004726 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004727 break;
4728 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004729 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004730 break;
4731 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004732 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004733 break;
4734 default: UNREACHABLE();
4735 }
4736 }
4737 }
4738 }
4739 catch(std::bad_alloc&)
4740 {
4741 return error(GL_OUT_OF_MEMORY);
4742 }
4743}
4744
4745void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4746{
4747 glTexParameteri(target, pname, (GLint)param);
4748}
4749
4750void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4751{
4752 glTexParameteri(target, pname, (GLint)*params);
4753}
4754
4755void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4756{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004757 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004758
4759 try
4760 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004761 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004762
4763 if (context)
4764 {
4765 gl::Texture *texture;
4766
4767 switch (target)
4768 {
4769 case GL_TEXTURE_2D:
4770 texture = context->getTexture2D();
4771 break;
4772 case GL_TEXTURE_CUBE_MAP:
4773 texture = context->getTextureCubeMap();
4774 break;
4775 default:
4776 return error(GL_INVALID_ENUM);
4777 }
4778
4779 switch (pname)
4780 {
4781 case GL_TEXTURE_WRAP_S:
4782 if (!texture->setWrapS((GLenum)param))
4783 {
4784 return error(GL_INVALID_ENUM);
4785 }
4786 break;
4787 case GL_TEXTURE_WRAP_T:
4788 if (!texture->setWrapT((GLenum)param))
4789 {
4790 return error(GL_INVALID_ENUM);
4791 }
4792 break;
4793 case GL_TEXTURE_MIN_FILTER:
4794 if (!texture->setMinFilter((GLenum)param))
4795 {
4796 return error(GL_INVALID_ENUM);
4797 }
4798 break;
4799 case GL_TEXTURE_MAG_FILTER:
4800 if (!texture->setMagFilter((GLenum)param))
4801 {
4802 return error(GL_INVALID_ENUM);
4803 }
4804 break;
4805 default:
4806 return error(GL_INVALID_ENUM);
4807 }
4808 }
4809 }
4810 catch(std::bad_alloc&)
4811 {
4812 return error(GL_OUT_OF_MEMORY);
4813 }
4814}
4815
4816void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4817{
4818 glTexParameteri(target, pname, *params);
4819}
4820
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004821void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4822 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004823{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004824 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004825 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004826 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004827 target, level, xoffset, yoffset, width, height, format, type, pixels);
4828
4829 try
4830 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004831 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004832 {
4833 return error(GL_INVALID_ENUM);
4834 }
4835
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004836 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004837 {
4838 return error(GL_INVALID_VALUE);
4839 }
4840
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004841 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4842 {
4843 return error(GL_INVALID_VALUE);
4844 }
4845
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004846 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004847 {
4848 return error(GL_INVALID_ENUM);
4849 }
4850
4851 if (width == 0 || height == 0 || pixels == NULL)
4852 {
4853 return;
4854 }
4855
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004856 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004857
4858 if (context)
4859 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004860 if (level > context->getMaximumTextureLevel())
4861 {
4862 return error(GL_INVALID_VALUE);
4863 }
4864
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004865 if (format == GL_FLOAT)
4866 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004867 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004868 {
4869 return error(GL_INVALID_ENUM);
4870 }
4871 }
4872 else if (format == GL_HALF_FLOAT_OES)
4873 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004874 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004875 {
4876 return error(GL_INVALID_ENUM);
4877 }
4878 }
4879
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004880 if (target == GL_TEXTURE_2D)
4881 {
4882 gl::Texture2D *texture = context->getTexture2D();
4883
4884 if (!texture)
4885 {
4886 return error(GL_INVALID_OPERATION);
4887 }
4888
daniel@transgaming.com01868132010-08-24 19:21:17 +00004889 if (texture->isCompressed())
4890 {
4891 return error(GL_INVALID_OPERATION);
4892 }
4893
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00004894 if (format != texture->getInternalFormat())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004895 {
4896 return error(GL_INVALID_OPERATION);
4897 }
4898
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004899 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004900 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004901 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004902 {
4903 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4904
4905 if (!texture)
4906 {
4907 return error(GL_INVALID_OPERATION);
4908 }
4909
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004910 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004911 }
4912 else
4913 {
4914 UNREACHABLE();
4915 }
4916 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004917 }
4918 catch(std::bad_alloc&)
4919 {
4920 return error(GL_OUT_OF_MEMORY);
4921 }
4922}
4923
4924void __stdcall glUniform1f(GLint location, GLfloat x)
4925{
4926 glUniform1fv(location, 1, &x);
4927}
4928
4929void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4930{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004931 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004932
4933 try
4934 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004935 if (count < 0)
4936 {
4937 return error(GL_INVALID_VALUE);
4938 }
4939
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004940 if (location == -1)
4941 {
4942 return;
4943 }
4944
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004945 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004946
4947 if (context)
4948 {
4949 gl::Program *program = context->getCurrentProgram();
4950
4951 if (!program)
4952 {
4953 return error(GL_INVALID_OPERATION);
4954 }
4955
4956 if (!program->setUniform1fv(location, count, v))
4957 {
4958 return error(GL_INVALID_OPERATION);
4959 }
4960 }
4961 }
4962 catch(std::bad_alloc&)
4963 {
4964 return error(GL_OUT_OF_MEMORY);
4965 }
4966}
4967
4968void __stdcall glUniform1i(GLint location, GLint x)
4969{
4970 glUniform1iv(location, 1, &x);
4971}
4972
4973void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4974{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004975 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004976
4977 try
4978 {
4979 if (count < 0)
4980 {
4981 return error(GL_INVALID_VALUE);
4982 }
4983
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004984 if (location == -1)
4985 {
4986 return;
4987 }
4988
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004989 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004990
4991 if (context)
4992 {
4993 gl::Program *program = context->getCurrentProgram();
4994
4995 if (!program)
4996 {
4997 return error(GL_INVALID_OPERATION);
4998 }
4999
5000 if (!program->setUniform1iv(location, count, v))
5001 {
5002 return error(GL_INVALID_OPERATION);
5003 }
5004 }
5005 }
5006 catch(std::bad_alloc&)
5007 {
5008 return error(GL_OUT_OF_MEMORY);
5009 }
5010}
5011
5012void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5013{
5014 GLfloat xy[2] = {x, y};
5015
5016 glUniform2fv(location, 1, (GLfloat*)&xy);
5017}
5018
5019void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5020{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005021 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005022
5023 try
5024 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005025 if (count < 0)
5026 {
5027 return error(GL_INVALID_VALUE);
5028 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005029
5030 if (location == -1)
5031 {
5032 return;
5033 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005034
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005035 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005036
5037 if (context)
5038 {
5039 gl::Program *program = context->getCurrentProgram();
5040
5041 if (!program)
5042 {
5043 return error(GL_INVALID_OPERATION);
5044 }
5045
5046 if (!program->setUniform2fv(location, count, v))
5047 {
5048 return error(GL_INVALID_OPERATION);
5049 }
5050 }
5051 }
5052 catch(std::bad_alloc&)
5053 {
5054 return error(GL_OUT_OF_MEMORY);
5055 }
5056}
5057
5058void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5059{
5060 GLint xy[4] = {x, y};
5061
5062 glUniform2iv(location, 1, (GLint*)&xy);
5063}
5064
5065void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5066{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005067 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005068
5069 try
5070 {
5071 if (count < 0)
5072 {
5073 return error(GL_INVALID_VALUE);
5074 }
5075
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005076 if (location == -1)
5077 {
5078 return;
5079 }
5080
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005081 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005082
5083 if (context)
5084 {
5085 gl::Program *program = context->getCurrentProgram();
5086
5087 if (!program)
5088 {
5089 return error(GL_INVALID_OPERATION);
5090 }
5091
5092 if (!program->setUniform2iv(location, count, v))
5093 {
5094 return error(GL_INVALID_OPERATION);
5095 }
5096 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005097 }
5098 catch(std::bad_alloc&)
5099 {
5100 return error(GL_OUT_OF_MEMORY);
5101 }
5102}
5103
5104void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5105{
5106 GLfloat xyz[3] = {x, y, z};
5107
5108 glUniform3fv(location, 1, (GLfloat*)&xyz);
5109}
5110
5111void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5112{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005113 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005114
5115 try
5116 {
5117 if (count < 0)
5118 {
5119 return error(GL_INVALID_VALUE);
5120 }
5121
5122 if (location == -1)
5123 {
5124 return;
5125 }
5126
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005127 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005128
5129 if (context)
5130 {
5131 gl::Program *program = context->getCurrentProgram();
5132
5133 if (!program)
5134 {
5135 return error(GL_INVALID_OPERATION);
5136 }
5137
5138 if (!program->setUniform3fv(location, count, v))
5139 {
5140 return error(GL_INVALID_OPERATION);
5141 }
5142 }
5143 }
5144 catch(std::bad_alloc&)
5145 {
5146 return error(GL_OUT_OF_MEMORY);
5147 }
5148}
5149
5150void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5151{
5152 GLint xyz[3] = {x, y, z};
5153
5154 glUniform3iv(location, 1, (GLint*)&xyz);
5155}
5156
5157void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5158{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005159 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005160
5161 try
5162 {
5163 if (count < 0)
5164 {
5165 return error(GL_INVALID_VALUE);
5166 }
5167
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005168 if (location == -1)
5169 {
5170 return;
5171 }
5172
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005173 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005174
5175 if (context)
5176 {
5177 gl::Program *program = context->getCurrentProgram();
5178
5179 if (!program)
5180 {
5181 return error(GL_INVALID_OPERATION);
5182 }
5183
5184 if (!program->setUniform3iv(location, count, v))
5185 {
5186 return error(GL_INVALID_OPERATION);
5187 }
5188 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005189 }
5190 catch(std::bad_alloc&)
5191 {
5192 return error(GL_OUT_OF_MEMORY);
5193 }
5194}
5195
5196void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5197{
5198 GLfloat xyzw[4] = {x, y, z, w};
5199
5200 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5201}
5202
5203void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5204{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005205 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005206
5207 try
5208 {
5209 if (count < 0)
5210 {
5211 return error(GL_INVALID_VALUE);
5212 }
5213
5214 if (location == -1)
5215 {
5216 return;
5217 }
5218
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005219 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005220
5221 if (context)
5222 {
5223 gl::Program *program = context->getCurrentProgram();
5224
5225 if (!program)
5226 {
5227 return error(GL_INVALID_OPERATION);
5228 }
5229
5230 if (!program->setUniform4fv(location, count, v))
5231 {
5232 return error(GL_INVALID_OPERATION);
5233 }
5234 }
5235 }
5236 catch(std::bad_alloc&)
5237 {
5238 return error(GL_OUT_OF_MEMORY);
5239 }
5240}
5241
5242void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5243{
5244 GLint xyzw[4] = {x, y, z, w};
5245
5246 glUniform4iv(location, 1, (GLint*)&xyzw);
5247}
5248
5249void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5250{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005251 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005252
5253 try
5254 {
5255 if (count < 0)
5256 {
5257 return error(GL_INVALID_VALUE);
5258 }
5259
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005260 if (location == -1)
5261 {
5262 return;
5263 }
5264
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005265 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005266
5267 if (context)
5268 {
5269 gl::Program *program = context->getCurrentProgram();
5270
5271 if (!program)
5272 {
5273 return error(GL_INVALID_OPERATION);
5274 }
5275
5276 if (!program->setUniform4iv(location, count, v))
5277 {
5278 return error(GL_INVALID_OPERATION);
5279 }
5280 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005281 }
5282 catch(std::bad_alloc&)
5283 {
5284 return error(GL_OUT_OF_MEMORY);
5285 }
5286}
5287
5288void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5289{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005290 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005291 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005292
5293 try
5294 {
5295 if (count < 0 || transpose != GL_FALSE)
5296 {
5297 return error(GL_INVALID_VALUE);
5298 }
5299
5300 if (location == -1)
5301 {
5302 return;
5303 }
5304
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005305 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005306
5307 if (context)
5308 {
5309 gl::Program *program = context->getCurrentProgram();
5310
5311 if (!program)
5312 {
5313 return error(GL_INVALID_OPERATION);
5314 }
5315
5316 if (!program->setUniformMatrix2fv(location, count, value))
5317 {
5318 return error(GL_INVALID_OPERATION);
5319 }
5320 }
5321 }
5322 catch(std::bad_alloc&)
5323 {
5324 return error(GL_OUT_OF_MEMORY);
5325 }
5326}
5327
5328void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5329{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005330 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005331 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005332
5333 try
5334 {
5335 if (count < 0 || transpose != GL_FALSE)
5336 {
5337 return error(GL_INVALID_VALUE);
5338 }
5339
5340 if (location == -1)
5341 {
5342 return;
5343 }
5344
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005345 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005346
5347 if (context)
5348 {
5349 gl::Program *program = context->getCurrentProgram();
5350
5351 if (!program)
5352 {
5353 return error(GL_INVALID_OPERATION);
5354 }
5355
5356 if (!program->setUniformMatrix3fv(location, count, value))
5357 {
5358 return error(GL_INVALID_OPERATION);
5359 }
5360 }
5361 }
5362 catch(std::bad_alloc&)
5363 {
5364 return error(GL_OUT_OF_MEMORY);
5365 }
5366}
5367
5368void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5369{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005370 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005371 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005372
5373 try
5374 {
5375 if (count < 0 || transpose != GL_FALSE)
5376 {
5377 return error(GL_INVALID_VALUE);
5378 }
5379
5380 if (location == -1)
5381 {
5382 return;
5383 }
5384
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005385 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005386
5387 if (context)
5388 {
5389 gl::Program *program = context->getCurrentProgram();
5390
5391 if (!program)
5392 {
5393 return error(GL_INVALID_OPERATION);
5394 }
5395
5396 if (!program->setUniformMatrix4fv(location, count, value))
5397 {
5398 return error(GL_INVALID_OPERATION);
5399 }
5400 }
5401 }
5402 catch(std::bad_alloc&)
5403 {
5404 return error(GL_OUT_OF_MEMORY);
5405 }
5406}
5407
5408void __stdcall glUseProgram(GLuint program)
5409{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005410 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005411
5412 try
5413 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005414 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005415
5416 if (context)
5417 {
5418 gl::Program *programObject = context->getProgram(program);
5419
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005420 if (!programObject && program != 0)
5421 {
5422 if (context->getShader(program))
5423 {
5424 return error(GL_INVALID_OPERATION);
5425 }
5426 else
5427 {
5428 return error(GL_INVALID_VALUE);
5429 }
5430 }
5431
5432 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005433 {
5434 return error(GL_INVALID_OPERATION);
5435 }
5436
5437 context->useProgram(program);
5438 }
5439 }
5440 catch(std::bad_alloc&)
5441 {
5442 return error(GL_OUT_OF_MEMORY);
5443 }
5444}
5445
5446void __stdcall glValidateProgram(GLuint program)
5447{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005448 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005449
5450 try
5451 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005452 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005453
5454 if (context)
5455 {
5456 gl::Program *programObject = context->getProgram(program);
5457
5458 if (!programObject)
5459 {
5460 if (context->getShader(program))
5461 {
5462 return error(GL_INVALID_OPERATION);
5463 }
5464 else
5465 {
5466 return error(GL_INVALID_VALUE);
5467 }
5468 }
5469
5470 programObject->validate();
5471 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005472 }
5473 catch(std::bad_alloc&)
5474 {
5475 return error(GL_OUT_OF_MEMORY);
5476 }
5477}
5478
5479void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5480{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005481 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005482
5483 try
5484 {
5485 if (index >= gl::MAX_VERTEX_ATTRIBS)
5486 {
5487 return error(GL_INVALID_VALUE);
5488 }
5489
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005490 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005491
5492 if (context)
5493 {
5494 GLfloat vals[4] = { x, 0, 0, 1 };
5495 context->setVertexAttrib(index, vals);
5496 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005497 }
5498 catch(std::bad_alloc&)
5499 {
5500 return error(GL_OUT_OF_MEMORY);
5501 }
5502}
5503
5504void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5505{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005506 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005507
5508 try
5509 {
5510 if (index >= gl::MAX_VERTEX_ATTRIBS)
5511 {
5512 return error(GL_INVALID_VALUE);
5513 }
5514
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005515 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005516
5517 if (context)
5518 {
5519 GLfloat vals[4] = { values[0], 0, 0, 1 };
5520 context->setVertexAttrib(index, vals);
5521 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005522 }
5523 catch(std::bad_alloc&)
5524 {
5525 return error(GL_OUT_OF_MEMORY);
5526 }
5527}
5528
5529void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5530{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005531 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005532
5533 try
5534 {
5535 if (index >= gl::MAX_VERTEX_ATTRIBS)
5536 {
5537 return error(GL_INVALID_VALUE);
5538 }
5539
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005540 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005541
5542 if (context)
5543 {
5544 GLfloat vals[4] = { x, y, 0, 1 };
5545 context->setVertexAttrib(index, vals);
5546 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005547 }
5548 catch(std::bad_alloc&)
5549 {
5550 return error(GL_OUT_OF_MEMORY);
5551 }
5552}
5553
5554void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5555{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005556 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005557
5558 try
5559 {
5560 if (index >= gl::MAX_VERTEX_ATTRIBS)
5561 {
5562 return error(GL_INVALID_VALUE);
5563 }
5564
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005565 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005566
5567 if (context)
5568 {
5569 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5570 context->setVertexAttrib(index, vals);
5571 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005572 }
5573 catch(std::bad_alloc&)
5574 {
5575 return error(GL_OUT_OF_MEMORY);
5576 }
5577}
5578
5579void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5580{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005581 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005582
5583 try
5584 {
5585 if (index >= gl::MAX_VERTEX_ATTRIBS)
5586 {
5587 return error(GL_INVALID_VALUE);
5588 }
5589
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005590 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005591
5592 if (context)
5593 {
5594 GLfloat vals[4] = { x, y, z, 1 };
5595 context->setVertexAttrib(index, vals);
5596 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005597 }
5598 catch(std::bad_alloc&)
5599 {
5600 return error(GL_OUT_OF_MEMORY);
5601 }
5602}
5603
5604void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5605{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005606 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005607
5608 try
5609 {
5610 if (index >= gl::MAX_VERTEX_ATTRIBS)
5611 {
5612 return error(GL_INVALID_VALUE);
5613 }
5614
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005615 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005616
5617 if (context)
5618 {
5619 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5620 context->setVertexAttrib(index, vals);
5621 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005622 }
5623 catch(std::bad_alloc&)
5624 {
5625 return error(GL_OUT_OF_MEMORY);
5626 }
5627}
5628
5629void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5630{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005631 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005632
5633 try
5634 {
5635 if (index >= gl::MAX_VERTEX_ATTRIBS)
5636 {
5637 return error(GL_INVALID_VALUE);
5638 }
5639
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005640 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005641
5642 if (context)
5643 {
5644 GLfloat vals[4] = { x, y, z, w };
5645 context->setVertexAttrib(index, vals);
5646 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005647 }
5648 catch(std::bad_alloc&)
5649 {
5650 return error(GL_OUT_OF_MEMORY);
5651 }
5652}
5653
5654void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5655{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005656 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005657
5658 try
5659 {
5660 if (index >= gl::MAX_VERTEX_ATTRIBS)
5661 {
5662 return error(GL_INVALID_VALUE);
5663 }
5664
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005665 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005666
5667 if (context)
5668 {
5669 context->setVertexAttrib(index, values);
5670 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005671 }
5672 catch(std::bad_alloc&)
5673 {
5674 return error(GL_OUT_OF_MEMORY);
5675 }
5676}
5677
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005678void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005679{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005680 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005681 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005682 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005683
5684 try
5685 {
5686 if (index >= gl::MAX_VERTEX_ATTRIBS)
5687 {
5688 return error(GL_INVALID_VALUE);
5689 }
5690
5691 if (size < 1 || size > 4)
5692 {
5693 return error(GL_INVALID_VALUE);
5694 }
5695
5696 switch (type)
5697 {
5698 case GL_BYTE:
5699 case GL_UNSIGNED_BYTE:
5700 case GL_SHORT:
5701 case GL_UNSIGNED_SHORT:
5702 case GL_FIXED:
5703 case GL_FLOAT:
5704 break;
5705 default:
5706 return error(GL_INVALID_ENUM);
5707 }
5708
5709 if (stride < 0)
5710 {
5711 return error(GL_INVALID_VALUE);
5712 }
5713
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005714 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005715
5716 if (context)
5717 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005718 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005719 }
5720 }
5721 catch(std::bad_alloc&)
5722 {
5723 return error(GL_OUT_OF_MEMORY);
5724 }
5725}
5726
5727void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5728{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005729 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005730
5731 try
5732 {
5733 if (width < 0 || height < 0)
5734 {
5735 return error(GL_INVALID_VALUE);
5736 }
5737
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005738 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005739
5740 if (context)
5741 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005742 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005743 }
5744 }
5745 catch(std::bad_alloc&)
5746 {
5747 return error(GL_OUT_OF_MEMORY);
5748 }
5749}
5750
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005751void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5752 GLbitfield mask, GLenum filter)
5753{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005754 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005755 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5756 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5757 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5758
5759 try
5760 {
5761 switch (filter)
5762 {
5763 case GL_NEAREST:
5764 break;
5765 default:
5766 return error(GL_INVALID_ENUM);
5767 }
5768
5769 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5770 {
5771 return error(GL_INVALID_VALUE);
5772 }
5773
5774 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5775 {
5776 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5777 return error(GL_INVALID_OPERATION);
5778 }
5779
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005780 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005781
5782 if (context)
5783 {
5784 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5785 {
5786 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5787 return error(GL_INVALID_OPERATION);
5788 }
5789
5790 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5791 }
5792 }
5793 catch(std::bad_alloc&)
5794 {
5795 return error(GL_OUT_OF_MEMORY);
5796 }
5797}
5798
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005799void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5800 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005801{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005802 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005803 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005804 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005805 target, level, internalformat, width, height, depth, border, format, type, pixels);
5806
5807 try
5808 {
5809 UNIMPLEMENTED(); // FIXME
5810 }
5811 catch(std::bad_alloc&)
5812 {
5813 return error(GL_OUT_OF_MEMORY);
5814 }
5815}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005816
5817__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5818{
5819 struct Extension
5820 {
5821 const char *name;
5822 __eglMustCastToProperFunctionPointerType address;
5823 };
5824
5825 static const Extension glExtensions[] =
5826 {
5827 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00005828 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00005829 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005830 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
5831 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00005832 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005833 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
5834 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
5835 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
5836 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
5837 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00005838 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005839 };
5840
5841 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5842 {
5843 if (strcmp(procname, glExtensions[ext].name) == 0)
5844 {
5845 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5846 }
5847 }
5848
5849 return NULL;
5850}
5851
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00005852// Non-public functions used by EGL
5853
jbauman@chromium.orgae345802011-03-30 22:04:25 +00005854void __stdcall glBindTexImage(egl::Surface *surface)
5855{
5856 EVENT("(egl::Surface* surface = 0x%0.8p)",
5857 surface);
5858
5859 try
5860 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005861 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00005862
5863 if (context)
5864 {
5865 gl::Texture2D *textureObject = context->getTexture2D();
5866
5867 if (textureObject)
5868 {
5869 textureObject->bindTexImage(surface);
5870 }
5871 }
5872 }
5873 catch(std::bad_alloc&)
5874 {
5875 return error(GL_OUT_OF_MEMORY);
5876 }
5877}
5878
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005879}