blob: 62bf20f29673a63ab9ef128f31cc57820d430f06 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002// Copyright (c) 2002-2012 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"
apatrick@chromium.orgea09f9b2012-06-08 00:45:32 +000027#include "libGLESv2/ProgramBinary.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000028#include "libGLESv2/Renderbuffer.h"
29#include "libGLESv2/Shader.h"
30#include "libGLESv2/Texture.h"
daniel@transgaming.com86bdb822012-01-20 18:24:39 +000031#include "libGLESv2/Query.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000032
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +000033bool validImageSize(GLint level, GLsizei width, GLsizei height)
34{
35 if (level < 0 || width < 0 || height < 0)
36 {
37 return false;
38 }
39
40 if (gl::getContext() && gl::getContext()->supportsNonPower2Texture())
41 {
42 return true;
43 }
44
45 if (level == 0)
46 {
47 return true;
48 }
49
50 if (gl::isPow2(width) && gl::isPow2(height))
51 {
52 return true;
53 }
54
55 return false;
56}
57
daniel@transgaming.com8833dd22012-06-05 19:49:58 +000058// Verify that format/type are one of the combinations from table 3.4.
59bool checkTextureFormatType(GLenum format, GLenum type)
60{
61 // validate <format> by itself (used as secondary key below)
62 switch (format)
63 {
64 case GL_RGBA:
65 case GL_BGRA_EXT:
66 case GL_RGB:
67 case GL_ALPHA:
68 case GL_LUMINANCE:
69 case GL_LUMINANCE_ALPHA:
70 case GL_DEPTH_COMPONENT:
71 case GL_DEPTH_STENCIL_OES:
72 break;
73 default:
74 return error(GL_INVALID_ENUM, false);
75 }
76
77 // invalid <type> -> sets INVALID_ENUM
78 // invalid <format>+<type> combination -> sets INVALID_OPERATION
79 switch (type)
80 {
81 case GL_UNSIGNED_BYTE:
82 switch (format)
83 {
84 case GL_RGBA:
85 case GL_BGRA_EXT:
86 case GL_RGB:
87 case GL_ALPHA:
88 case GL_LUMINANCE:
89 case GL_LUMINANCE_ALPHA:
90 return true;
91 default:
92 return error(GL_INVALID_OPERATION, false);
93 }
94
95 case GL_FLOAT:
96 case GL_HALF_FLOAT_OES:
97 switch (format)
98 {
99 case GL_RGBA:
100 case GL_RGB:
101 case GL_ALPHA:
102 case GL_LUMINANCE:
103 case GL_LUMINANCE_ALPHA:
104 return true;
105 default:
106 return error(GL_INVALID_OPERATION, false);
107 }
108
109 case GL_UNSIGNED_SHORT_4_4_4_4:
110 case GL_UNSIGNED_SHORT_5_5_5_1:
111 switch (format)
112 {
113 case GL_RGBA:
114 return true;
115 default:
116 return error(GL_INVALID_OPERATION, false);
117 }
118
119 case GL_UNSIGNED_SHORT_5_6_5:
120 switch (format)
121 {
122 case GL_RGB:
123 return true;
124 default:
125 return error(GL_INVALID_OPERATION, false);
126 }
127
128 case GL_UNSIGNED_SHORT:
129 case GL_UNSIGNED_INT:
130 switch (format)
131 {
132 case GL_DEPTH_COMPONENT:
133 return true;
134 default:
135 return error(GL_INVALID_OPERATION, false);
136 }
137
138 case GL_UNSIGNED_INT_24_8_OES:
139 switch (format)
140 {
141 case GL_DEPTH_STENCIL_OES:
142 return true;
143 default:
144 return error(GL_INVALID_OPERATION, false);
145 }
146
147 default:
148 return error(GL_INVALID_ENUM, false);
149 }
150}
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000151bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
152 GLint xoffset, GLint yoffset, GLint level, GLenum format,
153 gl::Texture2D *texture)
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000154{
155 if (!texture)
156 {
157 return error(GL_INVALID_OPERATION, false);
158 }
159
daniel@transgaming.com92f49922012-05-09 15:49:19 +0000160 if (compressed != texture->isCompressed(level))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000161 {
162 return error(GL_INVALID_OPERATION, false);
163 }
164
daniel@transgaming.com92f49922012-05-09 15:49:19 +0000165 if (format != GL_NONE && format != texture->getInternalFormat(level))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000166 {
167 return error(GL_INVALID_OPERATION, false);
168 }
169
170 if (compressed)
171 {
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000172 if ((width % 4 != 0 && width != texture->getWidth(0)) ||
173 (height % 4 != 0 && height != texture->getHeight(0)))
174 {
175 return error(GL_INVALID_OPERATION, false);
176 }
177 }
178
179 if (xoffset + width > texture->getWidth(level) ||
180 yoffset + height > texture->getHeight(level))
181 {
182 return error(GL_INVALID_VALUE, false);
183 }
184
185 return true;
186}
187
188bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000189 GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format,
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000190 gl::TextureCubeMap *texture)
191{
192 if (!texture)
193 {
194 return error(GL_INVALID_OPERATION, false);
195 }
196
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000197 if (compressed != texture->isCompressed(target, level))
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000198 {
199 return error(GL_INVALID_OPERATION, false);
200 }
201
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000202 if (format != GL_NONE && format != texture->getInternalFormat(target, level))
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000203 {
204 return error(GL_INVALID_OPERATION, false);
205 }
206
207 if (compressed)
208 {
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000209 if ((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
210 (height % 4 != 0 && height != texture->getHeight(target, 0)))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000211 {
212 return error(GL_INVALID_OPERATION, false);
213 }
214 }
215
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000216 if (xoffset + width > texture->getWidth(target, level) ||
217 yoffset + height > texture->getHeight(target, level))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000218 {
219 return error(GL_INVALID_VALUE, false);
220 }
221
222 return true;
223}
224
daniel@transgaming.comb7915a52011-11-12 03:14:20 +0000225// check for combinations of format and type that are valid for ReadPixels
226bool validReadFormatType(GLenum format, GLenum type)
227{
228 switch (format)
229 {
230 case GL_RGBA:
231 switch (type)
232 {
233 case GL_UNSIGNED_BYTE:
234 break;
235 default:
236 return false;
237 }
238 break;
239 case GL_BGRA_EXT:
240 switch (type)
241 {
242 case GL_UNSIGNED_BYTE:
243 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
244 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
245 break;
246 default:
247 return false;
248 }
249 break;
daniel@transgaming.comb7915a52011-11-12 03:14:20 +0000250 default:
251 return false;
252 }
253 return true;
254}
255
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000256extern "C"
257{
258
259void __stdcall glActiveTexture(GLenum texture)
260{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000261 EVENT("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000262
263 try
264 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000265 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000266
267 if (context)
268 {
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +0000269 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
270 {
271 return error(GL_INVALID_ENUM);
272 }
273
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000274 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000275 }
276 }
277 catch(std::bad_alloc&)
278 {
279 return error(GL_OUT_OF_MEMORY);
280 }
281}
282
283void __stdcall glAttachShader(GLuint program, GLuint shader)
284{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000285 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000286
287 try
288 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000289 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000290
291 if (context)
292 {
293 gl::Program *programObject = context->getProgram(program);
294 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000295
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000296 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000297 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000298 if (context->getShader(program))
299 {
300 return error(GL_INVALID_OPERATION);
301 }
302 else
303 {
304 return error(GL_INVALID_VALUE);
305 }
306 }
307
308 if (!shaderObject)
309 {
310 if (context->getProgram(shader))
311 {
312 return error(GL_INVALID_OPERATION);
313 }
314 else
315 {
316 return error(GL_INVALID_VALUE);
317 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000318 }
319
320 if (!programObject->attachShader(shaderObject))
321 {
322 return error(GL_INVALID_OPERATION);
323 }
324 }
325 }
326 catch(std::bad_alloc&)
327 {
328 return error(GL_OUT_OF_MEMORY);
329 }
330}
331
daniel@transgaming.com86bdb822012-01-20 18:24:39 +0000332void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
333{
334 EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
335
336 try
337 {
338 switch (target)
339 {
340 case GL_ANY_SAMPLES_PASSED_EXT:
341 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
342 break;
343 default:
344 return error(GL_INVALID_ENUM);
345 }
346
347 if (id == 0)
348 {
349 return error(GL_INVALID_OPERATION);
350 }
351
352 gl::Context *context = gl::getNonLostContext();
353
354 if (context)
355 {
356 context->beginQuery(target, id);
357 }
358 }
359 catch(std::bad_alloc&)
360 {
361 return error(GL_OUT_OF_MEMORY);
362 }
363}
364
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000365void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000366{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000367 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000368
369 try
370 {
371 if (index >= gl::MAX_VERTEX_ATTRIBS)
372 {
373 return error(GL_INVALID_VALUE);
374 }
375
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000376 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000377
378 if (context)
379 {
380 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000381
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000382 if (!programObject)
383 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000384 if (context->getShader(program))
385 {
386 return error(GL_INVALID_OPERATION);
387 }
388 else
389 {
390 return error(GL_INVALID_VALUE);
391 }
392 }
393
394 if (strncmp(name, "gl_", 3) == 0)
395 {
396 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000397 }
398
399 programObject->bindAttributeLocation(index, name);
400 }
401 }
402 catch(std::bad_alloc&)
403 {
404 return error(GL_OUT_OF_MEMORY);
405 }
406}
407
408void __stdcall glBindBuffer(GLenum target, GLuint buffer)
409{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000410 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000411
412 try
413 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000414 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000415
416 if (context)
417 {
418 switch (target)
419 {
420 case GL_ARRAY_BUFFER:
421 context->bindArrayBuffer(buffer);
422 return;
423 case GL_ELEMENT_ARRAY_BUFFER:
424 context->bindElementArrayBuffer(buffer);
425 return;
426 default:
427 return error(GL_INVALID_ENUM);
428 }
429 }
430 }
431 catch(std::bad_alloc&)
432 {
433 return error(GL_OUT_OF_MEMORY);
434 }
435}
436
437void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
438{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000439 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000440
441 try
442 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000443 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000444 {
445 return error(GL_INVALID_ENUM);
446 }
447
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000448 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000449
450 if (context)
451 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000452 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
453 {
454 context->bindReadFramebuffer(framebuffer);
455 }
456
457 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
458 {
459 context->bindDrawFramebuffer(framebuffer);
460 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000461 }
462 }
463 catch(std::bad_alloc&)
464 {
465 return error(GL_OUT_OF_MEMORY);
466 }
467}
468
469void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
470{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000471 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000472
473 try
474 {
475 if (target != GL_RENDERBUFFER)
476 {
477 return error(GL_INVALID_ENUM);
478 }
479
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000480 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000481
482 if (context)
483 {
484 context->bindRenderbuffer(renderbuffer);
485 }
486 }
487 catch(std::bad_alloc&)
488 {
489 return error(GL_OUT_OF_MEMORY);
490 }
491}
492
493void __stdcall glBindTexture(GLenum target, GLuint texture)
494{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000495 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000496
497 try
498 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000499 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000500
501 if (context)
502 {
503 gl::Texture *textureObject = context->getTexture(texture);
504
505 if (textureObject && textureObject->getTarget() != target && texture != 0)
506 {
507 return error(GL_INVALID_OPERATION);
508 }
509
510 switch (target)
511 {
512 case GL_TEXTURE_2D:
513 context->bindTexture2D(texture);
514 return;
515 case GL_TEXTURE_CUBE_MAP:
516 context->bindTextureCubeMap(texture);
517 return;
518 default:
519 return error(GL_INVALID_ENUM);
520 }
521 }
522 }
523 catch(std::bad_alloc&)
524 {
525 return error(GL_OUT_OF_MEMORY);
526 }
527}
528
529void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
530{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000531 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000532 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000533
534 try
535 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000536 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000537
538 if (context)
539 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000540 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000541 }
542 }
543 catch(std::bad_alloc&)
544 {
545 return error(GL_OUT_OF_MEMORY);
546 }
547}
548
549void __stdcall glBlendEquation(GLenum mode)
550{
551 glBlendEquationSeparate(mode, mode);
552}
553
554void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
555{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000556 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000557
558 try
559 {
560 switch (modeRGB)
561 {
562 case GL_FUNC_ADD:
563 case GL_FUNC_SUBTRACT:
564 case GL_FUNC_REVERSE_SUBTRACT:
565 break;
566 default:
567 return error(GL_INVALID_ENUM);
568 }
569
570 switch (modeAlpha)
571 {
572 case GL_FUNC_ADD:
573 case GL_FUNC_SUBTRACT:
574 case GL_FUNC_REVERSE_SUBTRACT:
575 break;
576 default:
577 return error(GL_INVALID_ENUM);
578 }
579
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000580 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000581
582 if (context)
583 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000584 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000585 }
586 }
587 catch(std::bad_alloc&)
588 {
589 return error(GL_OUT_OF_MEMORY);
590 }
591}
592
593void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
594{
595 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
596}
597
598void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
599{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000600 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 +0000601 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000602
603 try
604 {
605 switch (srcRGB)
606 {
607 case GL_ZERO:
608 case GL_ONE:
609 case GL_SRC_COLOR:
610 case GL_ONE_MINUS_SRC_COLOR:
611 case GL_DST_COLOR:
612 case GL_ONE_MINUS_DST_COLOR:
613 case GL_SRC_ALPHA:
614 case GL_ONE_MINUS_SRC_ALPHA:
615 case GL_DST_ALPHA:
616 case GL_ONE_MINUS_DST_ALPHA:
617 case GL_CONSTANT_COLOR:
618 case GL_ONE_MINUS_CONSTANT_COLOR:
619 case GL_CONSTANT_ALPHA:
620 case GL_ONE_MINUS_CONSTANT_ALPHA:
621 case GL_SRC_ALPHA_SATURATE:
622 break;
623 default:
624 return error(GL_INVALID_ENUM);
625 }
626
627 switch (dstRGB)
628 {
629 case GL_ZERO:
630 case GL_ONE:
631 case GL_SRC_COLOR:
632 case GL_ONE_MINUS_SRC_COLOR:
633 case GL_DST_COLOR:
634 case GL_ONE_MINUS_DST_COLOR:
635 case GL_SRC_ALPHA:
636 case GL_ONE_MINUS_SRC_ALPHA:
637 case GL_DST_ALPHA:
638 case GL_ONE_MINUS_DST_ALPHA:
639 case GL_CONSTANT_COLOR:
640 case GL_ONE_MINUS_CONSTANT_COLOR:
641 case GL_CONSTANT_ALPHA:
642 case GL_ONE_MINUS_CONSTANT_ALPHA:
643 break;
644 default:
645 return error(GL_INVALID_ENUM);
646 }
647
648 switch (srcAlpha)
649 {
650 case GL_ZERO:
651 case GL_ONE:
652 case GL_SRC_COLOR:
653 case GL_ONE_MINUS_SRC_COLOR:
654 case GL_DST_COLOR:
655 case GL_ONE_MINUS_DST_COLOR:
656 case GL_SRC_ALPHA:
657 case GL_ONE_MINUS_SRC_ALPHA:
658 case GL_DST_ALPHA:
659 case GL_ONE_MINUS_DST_ALPHA:
660 case GL_CONSTANT_COLOR:
661 case GL_ONE_MINUS_CONSTANT_COLOR:
662 case GL_CONSTANT_ALPHA:
663 case GL_ONE_MINUS_CONSTANT_ALPHA:
664 case GL_SRC_ALPHA_SATURATE:
665 break;
666 default:
667 return error(GL_INVALID_ENUM);
668 }
669
670 switch (dstAlpha)
671 {
672 case GL_ZERO:
673 case GL_ONE:
674 case GL_SRC_COLOR:
675 case GL_ONE_MINUS_SRC_COLOR:
676 case GL_DST_COLOR:
677 case GL_ONE_MINUS_DST_COLOR:
678 case GL_SRC_ALPHA:
679 case GL_ONE_MINUS_SRC_ALPHA:
680 case GL_DST_ALPHA:
681 case GL_ONE_MINUS_DST_ALPHA:
682 case GL_CONSTANT_COLOR:
683 case GL_ONE_MINUS_CONSTANT_COLOR:
684 case GL_CONSTANT_ALPHA:
685 case GL_ONE_MINUS_CONSTANT_ALPHA:
686 break;
687 default:
688 return error(GL_INVALID_ENUM);
689 }
690
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000691 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
692 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
693
694 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
695 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
696
697 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000698 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000699 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
700 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000701 }
702
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000703 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000704
705 if (context)
706 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000707 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000708 }
709 }
710 catch(std::bad_alloc&)
711 {
712 return error(GL_OUT_OF_MEMORY);
713 }
714}
715
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000716void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000717{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000718 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 +0000719 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000720
721 try
722 {
723 if (size < 0)
724 {
725 return error(GL_INVALID_VALUE);
726 }
727
728 switch (usage)
729 {
730 case GL_STREAM_DRAW:
731 case GL_STATIC_DRAW:
732 case GL_DYNAMIC_DRAW:
733 break;
734 default:
735 return error(GL_INVALID_ENUM);
736 }
737
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000738 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000739
740 if (context)
741 {
742 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000743
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000744 switch (target)
745 {
746 case GL_ARRAY_BUFFER:
747 buffer = context->getArrayBuffer();
748 break;
749 case GL_ELEMENT_ARRAY_BUFFER:
750 buffer = context->getElementArrayBuffer();
751 break;
752 default:
753 return error(GL_INVALID_ENUM);
754 }
755
756 if (!buffer)
757 {
758 return error(GL_INVALID_OPERATION);
759 }
760
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000761 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000762 }
763 }
764 catch(std::bad_alloc&)
765 {
766 return error(GL_OUT_OF_MEMORY);
767 }
768}
769
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000770void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000771{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000772 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 +0000773 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000774
775 try
776 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000777 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000778 {
779 return error(GL_INVALID_VALUE);
780 }
781
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000782 if (data == NULL)
783 {
784 return;
785 }
786
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000787 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000788
789 if (context)
790 {
791 gl::Buffer *buffer;
792
793 switch (target)
794 {
795 case GL_ARRAY_BUFFER:
796 buffer = context->getArrayBuffer();
797 break;
798 case GL_ELEMENT_ARRAY_BUFFER:
799 buffer = context->getElementArrayBuffer();
800 break;
801 default:
802 return error(GL_INVALID_ENUM);
803 }
804
805 if (!buffer)
806 {
807 return error(GL_INVALID_OPERATION);
808 }
809
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000810 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000811 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000812 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000813 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000814
815 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000816 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000817 }
818 catch(std::bad_alloc&)
819 {
820 return error(GL_OUT_OF_MEMORY);
821 }
822}
823
824GLenum __stdcall glCheckFramebufferStatus(GLenum target)
825{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000826 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000827
828 try
829 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000830 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000831 {
832 return error(GL_INVALID_ENUM, 0);
833 }
834
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000835 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000836
837 if (context)
838 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000839 gl::Framebuffer *framebuffer = NULL;
840 if (target == GL_READ_FRAMEBUFFER_ANGLE)
841 {
842 framebuffer = context->getReadFramebuffer();
843 }
844 else
845 {
846 framebuffer = context->getDrawFramebuffer();
847 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000848
849 return framebuffer->completeness();
850 }
851 }
852 catch(std::bad_alloc&)
853 {
854 return error(GL_OUT_OF_MEMORY, 0);
855 }
856
857 return 0;
858}
859
860void __stdcall glClear(GLbitfield mask)
861{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000862 EVENT("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000863
864 try
865 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000866 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000867
868 if (context)
869 {
870 context->clear(mask);
871 }
872 }
873 catch(std::bad_alloc&)
874 {
875 return error(GL_OUT_OF_MEMORY);
876 }
877}
878
879void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
880{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000881 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000882 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000883
884 try
885 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000886 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000887
888 if (context)
889 {
890 context->setClearColor(red, green, blue, alpha);
891 }
892 }
893 catch(std::bad_alloc&)
894 {
895 return error(GL_OUT_OF_MEMORY);
896 }
897}
898
899void __stdcall glClearDepthf(GLclampf depth)
900{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000901 EVENT("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000902
903 try
904 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000905 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000906
907 if (context)
908 {
909 context->setClearDepth(depth);
910 }
911 }
912 catch(std::bad_alloc&)
913 {
914 return error(GL_OUT_OF_MEMORY);
915 }
916}
917
918void __stdcall glClearStencil(GLint s)
919{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000920 EVENT("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000921
922 try
923 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000924 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000925
926 if (context)
927 {
928 context->setClearStencil(s);
929 }
930 }
931 catch(std::bad_alloc&)
932 {
933 return error(GL_OUT_OF_MEMORY);
934 }
935}
936
937void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
938{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000939 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000940 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000941
942 try
943 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000944 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000945
946 if (context)
947 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000948 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000949 }
950 }
951 catch(std::bad_alloc&)
952 {
953 return error(GL_OUT_OF_MEMORY);
954 }
955}
956
957void __stdcall glCompileShader(GLuint shader)
958{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000959 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000960
961 try
962 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000963 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000964
965 if (context)
966 {
967 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000968
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000969 if (!shaderObject)
970 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000971 if (context->getProgram(shader))
972 {
973 return error(GL_INVALID_OPERATION);
974 }
975 else
976 {
977 return error(GL_INVALID_VALUE);
978 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000979 }
980
981 shaderObject->compile();
982 }
983 }
984 catch(std::bad_alloc&)
985 {
986 return error(GL_OUT_OF_MEMORY);
987 }
988}
989
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000990void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
991 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000992{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000993 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000994 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000995 target, level, internalformat, width, height, border, imageSize, data);
996
997 try
998 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000999 if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001000 {
1001 return error(GL_INVALID_VALUE);
1002 }
1003
daniel@transgaming.com01868132010-08-24 19:21:17 +00001004 switch (internalformat)
1005 {
1006 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1007 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001008 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1009 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001010 break;
1011 default:
1012 return error(GL_INVALID_ENUM);
1013 }
1014
1015 if (border != 0)
1016 {
1017 return error(GL_INVALID_VALUE);
1018 }
1019
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001020 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001021
1022 if (context)
1023 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001024 if (level > context->getMaximumTextureLevel())
1025 {
1026 return error(GL_INVALID_VALUE);
1027 }
1028
1029 switch (target)
1030 {
1031 case GL_TEXTURE_2D:
1032 if (width > (context->getMaximumTextureDimension() >> level) ||
1033 height > (context->getMaximumTextureDimension() >> level))
1034 {
1035 return error(GL_INVALID_VALUE);
1036 }
1037 break;
1038 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1039 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1040 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1041 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1042 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1043 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1044 if (width != height)
1045 {
1046 return error(GL_INVALID_VALUE);
1047 }
1048
1049 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1050 height > (context->getMaximumCubeTextureDimension() >> level))
1051 {
1052 return error(GL_INVALID_VALUE);
1053 }
1054 break;
1055 default:
1056 return error(GL_INVALID_ENUM);
1057 }
1058
gman@chromium.org50c526d2011-08-10 05:19:44 +00001059 switch (internalformat) {
1060 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1061 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1062 if (!context->supportsDXT1Textures())
1063 {
1064 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1065 }
1066 break;
1067 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1068 if (!context->supportsDXT3Textures())
1069 {
1070 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1071 }
1072 break;
1073 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1074 if (!context->supportsDXT5Textures())
1075 {
1076 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1077 }
1078 break;
1079 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001080 }
1081
1082 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
1083 {
1084 return error(GL_INVALID_VALUE);
1085 }
1086
1087 if (target == GL_TEXTURE_2D)
1088 {
1089 gl::Texture2D *texture = context->getTexture2D();
1090
1091 if (!texture)
1092 {
1093 return error(GL_INVALID_OPERATION);
1094 }
1095
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001096 if (texture->isImmutable())
1097 {
1098 return error(GL_INVALID_OPERATION);
1099 }
1100
daniel@transgaming.com01868132010-08-24 19:21:17 +00001101 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
1102 }
1103 else
1104 {
1105 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1106
1107 if (!texture)
1108 {
1109 return error(GL_INVALID_OPERATION);
1110 }
1111
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001112 if (texture->isImmutable())
1113 {
1114 return error(GL_INVALID_OPERATION);
1115 }
1116
daniel@transgaming.com01868132010-08-24 19:21:17 +00001117 switch (target)
1118 {
1119 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1120 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1121 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1122 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1123 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1124 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1125 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
1126 break;
1127 default: UNREACHABLE();
1128 }
1129 }
1130 }
1131
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001132 }
1133 catch(std::bad_alloc&)
1134 {
1135 return error(GL_OUT_OF_MEMORY);
1136 }
1137}
1138
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001139void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
1140 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001141{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001142 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001143 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001144 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001145 target, level, xoffset, yoffset, width, height, format, imageSize, data);
1146
1147 try
1148 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00001149 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +00001150 {
1151 return error(GL_INVALID_ENUM);
1152 }
1153
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001154 if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001155 {
1156 return error(GL_INVALID_VALUE);
1157 }
1158
daniel@transgaming.com01868132010-08-24 19:21:17 +00001159 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001160 {
daniel@transgaming.com01868132010-08-24 19:21:17 +00001161 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1162 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001163 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1164 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001165 break;
1166 default:
1167 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +00001168 }
1169
daniel@transgaming.com01868132010-08-24 19:21:17 +00001170 if (width == 0 || height == 0 || data == NULL)
1171 {
1172 return;
1173 }
1174
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001175 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001176
1177 if (context)
1178 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001179 if (level > context->getMaximumTextureLevel())
1180 {
1181 return error(GL_INVALID_VALUE);
1182 }
1183
gman@chromium.org50c526d2011-08-10 05:19:44 +00001184 switch (format) {
1185 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1186 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1187 if (!context->supportsDXT1Textures())
1188 {
1189 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1190 }
1191 break;
1192 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1193 if (!context->supportsDXT3Textures())
1194 {
1195 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1196 }
1197 break;
1198 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1199 if (!context->supportsDXT5Textures())
1200 {
1201 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1202 }
1203 break;
1204 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001205 }
1206
1207 if (imageSize != gl::ComputeCompressedSize(width, height, format))
1208 {
1209 return error(GL_INVALID_VALUE);
1210 }
1211
1212 if (xoffset % 4 != 0 || yoffset % 4 != 0)
1213 {
1214 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 +00001215 // does not exist unless DXT textures are supported.
daniel@transgaming.com01868132010-08-24 19:21:17 +00001216 }
1217
1218 if (target == GL_TEXTURE_2D)
1219 {
1220 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001221 if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001222 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001223 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
daniel@transgaming.com01868132010-08-24 19:21:17 +00001224 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001225 }
1226 else if (gl::IsCubemapTextureTarget(target))
1227 {
1228 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00001229 if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, texture))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001230 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001231 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
daniel@transgaming.com01868132010-08-24 19:21:17 +00001232 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001233 }
1234 else
1235 {
1236 UNREACHABLE();
1237 }
1238 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001239 }
1240 catch(std::bad_alloc&)
1241 {
1242 return error(GL_OUT_OF_MEMORY);
1243 }
1244}
1245
1246void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1247{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001248 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001249 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001250 target, level, internalformat, x, y, width, height, border);
1251
1252 try
1253 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001254 if (!validImageSize(level, width, height))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001255 {
1256 return error(GL_INVALID_VALUE);
1257 }
1258
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001259 if (border != 0)
1260 {
1261 return error(GL_INVALID_VALUE);
1262 }
1263
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001264 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001265
1266 if (context)
1267 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00001268 if (level > context->getMaximumTextureLevel())
1269 {
1270 return error(GL_INVALID_VALUE);
1271 }
1272
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001273 switch (target)
1274 {
1275 case GL_TEXTURE_2D:
1276 if (width > (context->getMaximumTextureDimension() >> level) ||
1277 height > (context->getMaximumTextureDimension() >> level))
1278 {
1279 return error(GL_INVALID_VALUE);
1280 }
1281 break;
1282 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1283 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1284 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1285 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1286 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1287 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1288 if (width != height)
1289 {
1290 return error(GL_INVALID_VALUE);
1291 }
1292
1293 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1294 height > (context->getMaximumCubeTextureDimension() >> level))
1295 {
1296 return error(GL_INVALID_VALUE);
1297 }
1298 break;
1299 default:
1300 return error(GL_INVALID_ENUM);
1301 }
1302
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001303 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001304
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001305 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1306 {
1307 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1308 }
1309
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001310 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1311 {
1312 return error(GL_INVALID_OPERATION);
1313 }
1314
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001315 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001316 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001317
1318 // [OpenGL ES 2.0.24] table 3.9
1319 switch (internalformat)
1320 {
1321 case GL_ALPHA:
1322 if (colorbufferFormat != GL_ALPHA &&
1323 colorbufferFormat != GL_RGBA &&
1324 colorbufferFormat != GL_RGBA4 &&
1325 colorbufferFormat != GL_RGB5_A1 &&
1326 colorbufferFormat != GL_RGBA8_OES)
1327 {
1328 return error(GL_INVALID_OPERATION);
1329 }
1330 break;
1331 case GL_LUMINANCE:
1332 case GL_RGB:
1333 if (colorbufferFormat != GL_RGB &&
1334 colorbufferFormat != GL_RGB565 &&
1335 colorbufferFormat != GL_RGB8_OES &&
1336 colorbufferFormat != GL_RGBA &&
1337 colorbufferFormat != GL_RGBA4 &&
1338 colorbufferFormat != GL_RGB5_A1 &&
1339 colorbufferFormat != GL_RGBA8_OES)
1340 {
1341 return error(GL_INVALID_OPERATION);
1342 }
1343 break;
1344 case GL_LUMINANCE_ALPHA:
1345 case GL_RGBA:
1346 if (colorbufferFormat != GL_RGBA &&
1347 colorbufferFormat != GL_RGBA4 &&
1348 colorbufferFormat != GL_RGB5_A1 &&
1349 colorbufferFormat != GL_RGBA8_OES)
1350 {
1351 return error(GL_INVALID_OPERATION);
1352 }
1353 break;
1354 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1355 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001356 if (context->supportsDXT1Textures())
1357 {
1358 return error(GL_INVALID_OPERATION);
1359 }
1360 else
1361 {
1362 return error(GL_INVALID_ENUM);
1363 }
1364 break;
1365 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1366 if (context->supportsDXT3Textures())
1367 {
1368 return error(GL_INVALID_OPERATION);
1369 }
1370 else
1371 {
1372 return error(GL_INVALID_ENUM);
1373 }
1374 break;
1375 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1376 if (context->supportsDXT5Textures())
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001377 {
1378 return error(GL_INVALID_OPERATION);
1379 }
1380 else
1381 {
1382 return error(GL_INVALID_ENUM);
1383 }
1384 break;
daniel@transgaming.com0c854682012-05-31 01:14:11 +00001385 case GL_DEPTH_COMPONENT:
1386 case GL_DEPTH_COMPONENT16:
1387 case GL_DEPTH_COMPONENT32_OES:
1388 case GL_DEPTH_STENCIL_OES:
1389 case GL_DEPTH24_STENCIL8_OES:
1390 if (context->supportsDepthTextures())
1391 {
1392 return error(GL_INVALID_OPERATION);
1393 }
1394 else
1395 {
1396 return error(GL_INVALID_ENUM);
1397 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001398 default:
1399 return error(GL_INVALID_ENUM);
1400 }
1401
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001402 if (target == GL_TEXTURE_2D)
1403 {
1404 gl::Texture2D *texture = context->getTexture2D();
1405
1406 if (!texture)
1407 {
1408 return error(GL_INVALID_OPERATION);
1409 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001410
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001411 if (texture->isImmutable())
1412 {
1413 return error(GL_INVALID_OPERATION);
1414 }
1415
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001416 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001417 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001418 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001419 {
1420 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1421
1422 if (!texture)
1423 {
1424 return error(GL_INVALID_OPERATION);
1425 }
1426
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001427 if (texture->isImmutable())
1428 {
1429 return error(GL_INVALID_OPERATION);
1430 }
1431
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001432 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001433 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001434 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001435 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001436 }
1437 catch(std::bad_alloc&)
1438 {
1439 return error(GL_OUT_OF_MEMORY);
1440 }
1441}
1442
1443void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1444{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001445 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001446 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001447 target, level, xoffset, yoffset, x, y, width, height);
1448
1449 try
1450 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00001451 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001452 {
1453 return error(GL_INVALID_ENUM);
1454 }
1455
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001456 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001457 {
1458 return error(GL_INVALID_VALUE);
1459 }
1460
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001461 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1462 {
1463 return error(GL_INVALID_VALUE);
1464 }
1465
1466 if (width == 0 || height == 0)
1467 {
1468 return;
1469 }
1470
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001471 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001472
1473 if (context)
1474 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001475 if (level > context->getMaximumTextureLevel())
1476 {
1477 return error(GL_INVALID_VALUE);
1478 }
1479
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001480 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001481
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001482 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1483 {
1484 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1485 }
1486
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001487 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1488 {
1489 return error(GL_INVALID_OPERATION);
1490 }
1491
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001492 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001493 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001494 gl::Texture *texture = NULL;
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001495 GLenum textureFormat = GL_RGBA;
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001496
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001497 if (target == GL_TEXTURE_2D)
1498 {
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001499 gl::Texture2D *tex2d = context->getTexture2D();
1500
1501 if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, tex2d))
1502 {
1503 return; // error already registered by validateSubImageParams
1504 }
daniel@transgaming.com92f49922012-05-09 15:49:19 +00001505 textureFormat = tex2d->getInternalFormat(level);
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001506 texture = tex2d;
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001507 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001508 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001509 {
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001510 gl::TextureCubeMap *texcube = context->getTextureCubeMap();
1511
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00001512 if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, texcube))
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001513 {
1514 return; // error already registered by validateSubImageParams
1515 }
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00001516 textureFormat = texcube->getInternalFormat(target, level);
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001517 texture = texcube;
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001518 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001519 else UNREACHABLE();
1520
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001521 // [OpenGL ES 2.0.24] table 3.9
1522 switch (textureFormat)
1523 {
1524 case GL_ALPHA:
1525 if (colorbufferFormat != GL_ALPHA &&
1526 colorbufferFormat != GL_RGBA &&
1527 colorbufferFormat != GL_RGBA4 &&
1528 colorbufferFormat != GL_RGB5_A1 &&
1529 colorbufferFormat != GL_RGBA8_OES)
1530 {
1531 return error(GL_INVALID_OPERATION);
1532 }
1533 break;
1534 case GL_LUMINANCE:
1535 case GL_RGB:
1536 if (colorbufferFormat != GL_RGB &&
1537 colorbufferFormat != GL_RGB565 &&
1538 colorbufferFormat != GL_RGB8_OES &&
1539 colorbufferFormat != GL_RGBA &&
1540 colorbufferFormat != GL_RGBA4 &&
1541 colorbufferFormat != GL_RGB5_A1 &&
1542 colorbufferFormat != GL_RGBA8_OES)
1543 {
1544 return error(GL_INVALID_OPERATION);
1545 }
1546 break;
1547 case GL_LUMINANCE_ALPHA:
1548 case GL_RGBA:
1549 if (colorbufferFormat != GL_RGBA &&
1550 colorbufferFormat != GL_RGBA4 &&
1551 colorbufferFormat != GL_RGB5_A1 &&
1552 colorbufferFormat != GL_RGBA8_OES)
1553 {
1554 return error(GL_INVALID_OPERATION);
1555 }
1556 break;
1557 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1558 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001559 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1560 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001561 return error(GL_INVALID_OPERATION);
daniel@transgaming.com0c854682012-05-31 01:14:11 +00001562 case GL_DEPTH_COMPONENT:
1563 case GL_DEPTH_STENCIL_OES:
1564 return error(GL_INVALID_OPERATION);
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001565 default:
1566 return error(GL_INVALID_OPERATION);
1567 }
1568
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001569 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001570 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001571 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001572
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001573 catch(std::bad_alloc&)
1574 {
1575 return error(GL_OUT_OF_MEMORY);
1576 }
1577}
1578
1579GLuint __stdcall glCreateProgram(void)
1580{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001581 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001582
1583 try
1584 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001585 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001586
1587 if (context)
1588 {
1589 return context->createProgram();
1590 }
1591 }
1592 catch(std::bad_alloc&)
1593 {
1594 return error(GL_OUT_OF_MEMORY, 0);
1595 }
1596
1597 return 0;
1598}
1599
1600GLuint __stdcall glCreateShader(GLenum type)
1601{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001602 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001603
1604 try
1605 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001606 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001607
1608 if (context)
1609 {
1610 switch (type)
1611 {
1612 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001613 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001614 return context->createShader(type);
1615 default:
1616 return error(GL_INVALID_ENUM, 0);
1617 }
1618 }
1619 }
1620 catch(std::bad_alloc&)
1621 {
1622 return error(GL_OUT_OF_MEMORY, 0);
1623 }
1624
1625 return 0;
1626}
1627
1628void __stdcall glCullFace(GLenum mode)
1629{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001630 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001631
1632 try
1633 {
1634 switch (mode)
1635 {
1636 case GL_FRONT:
1637 case GL_BACK:
1638 case GL_FRONT_AND_BACK:
1639 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001640 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001641
1642 if (context)
1643 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001644 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001645 }
1646 }
1647 break;
1648 default:
1649 return error(GL_INVALID_ENUM);
1650 }
1651 }
1652 catch(std::bad_alloc&)
1653 {
1654 return error(GL_OUT_OF_MEMORY);
1655 }
1656}
1657
1658void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1659{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001660 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001661
1662 try
1663 {
1664 if (n < 0)
1665 {
1666 return error(GL_INVALID_VALUE);
1667 }
1668
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001669 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001670
1671 if (context)
1672 {
1673 for (int i = 0; i < n; i++)
1674 {
1675 context->deleteBuffer(buffers[i]);
1676 }
1677 }
1678 }
1679 catch(std::bad_alloc&)
1680 {
1681 return error(GL_OUT_OF_MEMORY);
1682 }
1683}
1684
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001685void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1686{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001687 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001688
1689 try
1690 {
1691 if (n < 0)
1692 {
1693 return error(GL_INVALID_VALUE);
1694 }
1695
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001696 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001697
1698 if (context)
1699 {
1700 for (int i = 0; i < n; i++)
1701 {
1702 context->deleteFence(fences[i]);
1703 }
1704 }
1705 }
1706 catch(std::bad_alloc&)
1707 {
1708 return error(GL_OUT_OF_MEMORY);
1709 }
1710}
1711
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001712void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1713{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001714 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001715
1716 try
1717 {
1718 if (n < 0)
1719 {
1720 return error(GL_INVALID_VALUE);
1721 }
1722
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001723 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001724
1725 if (context)
1726 {
1727 for (int i = 0; i < n; i++)
1728 {
1729 if (framebuffers[i] != 0)
1730 {
1731 context->deleteFramebuffer(framebuffers[i]);
1732 }
1733 }
1734 }
1735 }
1736 catch(std::bad_alloc&)
1737 {
1738 return error(GL_OUT_OF_MEMORY);
1739 }
1740}
1741
1742void __stdcall glDeleteProgram(GLuint program)
1743{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001744 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001745
1746 try
1747 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001748 if (program == 0)
1749 {
1750 return;
1751 }
1752
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001753 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001754
1755 if (context)
1756 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001757 if (!context->getProgram(program))
1758 {
1759 if(context->getShader(program))
1760 {
1761 return error(GL_INVALID_OPERATION);
1762 }
1763 else
1764 {
1765 return error(GL_INVALID_VALUE);
1766 }
1767 }
1768
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001769 context->deleteProgram(program);
1770 }
1771 }
1772 catch(std::bad_alloc&)
1773 {
1774 return error(GL_OUT_OF_MEMORY);
1775 }
1776}
1777
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00001778void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
1779{
1780 EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
1781
1782 try
1783 {
1784 if (n < 0)
1785 {
1786 return error(GL_INVALID_VALUE);
1787 }
1788
1789 gl::Context *context = gl::getNonLostContext();
1790
1791 if (context)
1792 {
1793 for (int i = 0; i < n; i++)
1794 {
1795 context->deleteQuery(ids[i]);
1796 }
1797 }
1798 }
1799 catch(std::bad_alloc&)
1800 {
1801 return error(GL_OUT_OF_MEMORY);
1802 }
1803}
1804
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001805void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1806{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001807 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001808
1809 try
1810 {
1811 if (n < 0)
1812 {
1813 return error(GL_INVALID_VALUE);
1814 }
1815
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001816 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001817
1818 if (context)
1819 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001820 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001821 {
1822 context->deleteRenderbuffer(renderbuffers[i]);
1823 }
1824 }
1825 }
1826 catch(std::bad_alloc&)
1827 {
1828 return error(GL_OUT_OF_MEMORY);
1829 }
1830}
1831
1832void __stdcall glDeleteShader(GLuint shader)
1833{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001834 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001835
1836 try
1837 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001838 if (shader == 0)
1839 {
1840 return;
1841 }
1842
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001843 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001844
1845 if (context)
1846 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001847 if (!context->getShader(shader))
1848 {
1849 if(context->getProgram(shader))
1850 {
1851 return error(GL_INVALID_OPERATION);
1852 }
1853 else
1854 {
1855 return error(GL_INVALID_VALUE);
1856 }
1857 }
1858
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001859 context->deleteShader(shader);
1860 }
1861 }
1862 catch(std::bad_alloc&)
1863 {
1864 return error(GL_OUT_OF_MEMORY);
1865 }
1866}
1867
1868void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1869{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001870 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001871
1872 try
1873 {
1874 if (n < 0)
1875 {
1876 return error(GL_INVALID_VALUE);
1877 }
1878
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001879 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001880
1881 if (context)
1882 {
1883 for (int i = 0; i < n; i++)
1884 {
1885 if (textures[i] != 0)
1886 {
1887 context->deleteTexture(textures[i]);
1888 }
1889 }
1890 }
1891 }
1892 catch(std::bad_alloc&)
1893 {
1894 return error(GL_OUT_OF_MEMORY);
1895 }
1896}
1897
1898void __stdcall glDepthFunc(GLenum func)
1899{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001900 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001901
1902 try
1903 {
1904 switch (func)
1905 {
1906 case GL_NEVER:
1907 case GL_ALWAYS:
1908 case GL_LESS:
1909 case GL_LEQUAL:
1910 case GL_EQUAL:
1911 case GL_GREATER:
1912 case GL_GEQUAL:
1913 case GL_NOTEQUAL:
1914 break;
1915 default:
1916 return error(GL_INVALID_ENUM);
1917 }
1918
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001919 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001920
1921 if (context)
1922 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001923 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001924 }
1925 }
1926 catch(std::bad_alloc&)
1927 {
1928 return error(GL_OUT_OF_MEMORY);
1929 }
1930}
1931
1932void __stdcall glDepthMask(GLboolean flag)
1933{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001934 EVENT("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001935
1936 try
1937 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001938 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001939
1940 if (context)
1941 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001942 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001943 }
1944 }
1945 catch(std::bad_alloc&)
1946 {
1947 return error(GL_OUT_OF_MEMORY);
1948 }
1949}
1950
1951void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1952{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001953 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001954
1955 try
1956 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001957 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001958
1959 if (context)
1960 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001961 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001962 }
1963 }
1964 catch(std::bad_alloc&)
1965 {
1966 return error(GL_OUT_OF_MEMORY);
1967 }
1968}
1969
1970void __stdcall glDetachShader(GLuint program, GLuint shader)
1971{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001972 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001973
1974 try
1975 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001976 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001977
1978 if (context)
1979 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001980
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001981 gl::Program *programObject = context->getProgram(program);
1982 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001983
1984 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001985 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001986 gl::Shader *shaderByProgramHandle;
1987 shaderByProgramHandle = context->getShader(program);
1988 if (!shaderByProgramHandle)
1989 {
1990 return error(GL_INVALID_VALUE);
1991 }
1992 else
1993 {
1994 return error(GL_INVALID_OPERATION);
1995 }
1996 }
1997
1998 if (!shaderObject)
1999 {
2000 gl::Program *programByShaderHandle = context->getProgram(shader);
2001 if (!programByShaderHandle)
2002 {
2003 return error(GL_INVALID_VALUE);
2004 }
2005 else
2006 {
2007 return error(GL_INVALID_OPERATION);
2008 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002009 }
2010
2011 if (!programObject->detachShader(shaderObject))
2012 {
2013 return error(GL_INVALID_OPERATION);
2014 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002015 }
2016 }
2017 catch(std::bad_alloc&)
2018 {
2019 return error(GL_OUT_OF_MEMORY);
2020 }
2021}
2022
2023void __stdcall glDisable(GLenum cap)
2024{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002025 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002026
2027 try
2028 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002029 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002030
2031 if (context)
2032 {
2033 switch (cap)
2034 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002035 case GL_CULL_FACE: context->setCullFace(false); break;
2036 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
2037 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
2038 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
2039 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
2040 case GL_STENCIL_TEST: context->setStencilTest(false); break;
2041 case GL_DEPTH_TEST: context->setDepthTest(false); break;
2042 case GL_BLEND: context->setBlend(false); break;
2043 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002044 default:
2045 return error(GL_INVALID_ENUM);
2046 }
2047 }
2048 }
2049 catch(std::bad_alloc&)
2050 {
2051 return error(GL_OUT_OF_MEMORY);
2052 }
2053}
2054
2055void __stdcall glDisableVertexAttribArray(GLuint index)
2056{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002057 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002058
2059 try
2060 {
2061 if (index >= gl::MAX_VERTEX_ATTRIBS)
2062 {
2063 return error(GL_INVALID_VALUE);
2064 }
2065
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002066 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002067
2068 if (context)
2069 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002070 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002071 }
2072 }
2073 catch(std::bad_alloc&)
2074 {
2075 return error(GL_OUT_OF_MEMORY);
2076 }
2077}
2078
2079void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
2080{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002081 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002082
2083 try
2084 {
2085 if (count < 0 || first < 0)
2086 {
2087 return error(GL_INVALID_VALUE);
2088 }
2089
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002090 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002091
2092 if (context)
2093 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002094 context->drawArrays(mode, first, count, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002095 }
2096 }
2097 catch(std::bad_alloc&)
2098 {
2099 return error(GL_OUT_OF_MEMORY);
2100 }
2101}
2102
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002103void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
2104{
2105 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
2106
2107 try
2108 {
2109 if (count < 0 || first < 0 || primcount < 0)
2110 {
2111 return error(GL_INVALID_VALUE);
2112 }
2113
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002114 if (primcount > 0)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002115 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002116 gl::Context *context = gl::getNonLostContext();
2117
2118 if (context)
2119 {
2120 context->drawArrays(mode, first, count, primcount);
2121 }
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002122 }
2123 }
2124 catch(std::bad_alloc&)
2125 {
2126 return error(GL_OUT_OF_MEMORY);
2127 }
2128}
2129
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002130void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002131{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002132 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 +00002133 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002134
2135 try
2136 {
2137 if (count < 0)
2138 {
2139 return error(GL_INVALID_VALUE);
2140 }
2141
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002142 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002143
2144 if (context)
2145 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002146 switch (type)
2147 {
2148 case GL_UNSIGNED_BYTE:
2149 case GL_UNSIGNED_SHORT:
2150 break;
2151 case GL_UNSIGNED_INT:
2152 if (!context->supports32bitIndices())
2153 {
2154 return error(GL_INVALID_ENUM);
2155 }
2156 break;
2157 default:
2158 return error(GL_INVALID_ENUM);
2159 }
2160
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002161 context->drawElements(mode, count, type, indices, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002162 }
2163 }
2164 catch(std::bad_alloc&)
2165 {
2166 return error(GL_OUT_OF_MEMORY);
2167 }
2168}
2169
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002170void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)
2171{
2172 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)",
2173 mode, count, type, indices, primcount);
2174
2175 try
2176 {
2177 if (count < 0 || primcount < 0)
2178 {
2179 return error(GL_INVALID_VALUE);
2180 }
2181
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002182 if (primcount > 0)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002183 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002184 gl::Context *context = gl::getNonLostContext();
2185
2186 if (context)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002187 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002188 switch (type)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002189 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002190 case GL_UNSIGNED_BYTE:
2191 case GL_UNSIGNED_SHORT:
2192 break;
2193 case GL_UNSIGNED_INT:
2194 if (!context->supports32bitIndices())
2195 {
2196 return error(GL_INVALID_ENUM);
2197 }
2198 break;
2199 default:
2200 return error(GL_INVALID_ENUM);
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002201 }
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002202
2203 context->drawElements(mode, count, type, indices, primcount);
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002204 }
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002205 }
2206 }
2207 catch(std::bad_alloc&)
2208 {
2209 return error(GL_OUT_OF_MEMORY);
2210 }
2211}
2212
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002213void __stdcall glEnable(GLenum cap)
2214{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002215 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002216
2217 try
2218 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002219 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002220
2221 if (context)
2222 {
2223 switch (cap)
2224 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002225 case GL_CULL_FACE: context->setCullFace(true); break;
2226 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
2227 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
2228 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
2229 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
2230 case GL_STENCIL_TEST: context->setStencilTest(true); break;
2231 case GL_DEPTH_TEST: context->setDepthTest(true); break;
2232 case GL_BLEND: context->setBlend(true); break;
2233 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002234 default:
2235 return error(GL_INVALID_ENUM);
2236 }
2237 }
2238 }
2239 catch(std::bad_alloc&)
2240 {
2241 return error(GL_OUT_OF_MEMORY);
2242 }
2243}
2244
2245void __stdcall glEnableVertexAttribArray(GLuint index)
2246{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002247 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002248
2249 try
2250 {
2251 if (index >= gl::MAX_VERTEX_ATTRIBS)
2252 {
2253 return error(GL_INVALID_VALUE);
2254 }
2255
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002256 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002257
2258 if (context)
2259 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002260 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002261 }
2262 }
2263 catch(std::bad_alloc&)
2264 {
2265 return error(GL_OUT_OF_MEMORY);
2266 }
2267}
2268
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00002269void __stdcall glEndQueryEXT(GLenum target)
2270{
2271 EVENT("GLenum target = 0x%X)", target);
2272
2273 try
2274 {
2275 switch (target)
2276 {
2277 case GL_ANY_SAMPLES_PASSED_EXT:
2278 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
2279 break;
2280 default:
2281 return error(GL_INVALID_ENUM);
2282 }
2283
2284 gl::Context *context = gl::getNonLostContext();
2285
2286 if (context)
2287 {
2288 context->endQuery(target);
2289 }
2290 }
2291 catch(std::bad_alloc&)
2292 {
2293 return error(GL_OUT_OF_MEMORY);
2294 }
2295}
2296
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002297void __stdcall glFinishFenceNV(GLuint fence)
2298{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002299 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002300
2301 try
2302 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002303 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002304
2305 if (context)
2306 {
2307 gl::Fence* fenceObject = context->getFence(fence);
2308
2309 if (fenceObject == NULL)
2310 {
2311 return error(GL_INVALID_OPERATION);
2312 }
2313
2314 fenceObject->finishFence();
2315 }
2316 }
2317 catch(std::bad_alloc&)
2318 {
2319 return error(GL_OUT_OF_MEMORY);
2320 }
2321}
2322
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002323void __stdcall glFinish(void)
2324{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002325 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002326
2327 try
2328 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002329 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002330
2331 if (context)
2332 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002333 context->sync(true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002334 }
2335 }
2336 catch(std::bad_alloc&)
2337 {
2338 return error(GL_OUT_OF_MEMORY);
2339 }
2340}
2341
2342void __stdcall glFlush(void)
2343{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002344 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002345
2346 try
2347 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002348 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002349
2350 if (context)
2351 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002352 context->sync(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002353 }
2354 }
2355 catch(std::bad_alloc&)
2356 {
2357 return error(GL_OUT_OF_MEMORY);
2358 }
2359}
2360
2361void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2362{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002363 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002364 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002365
2366 try
2367 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002368 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002369 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002370 {
2371 return error(GL_INVALID_ENUM);
2372 }
2373
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002374 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002375
2376 if (context)
2377 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002378 gl::Framebuffer *framebuffer = NULL;
2379 GLuint framebufferHandle = 0;
2380 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2381 {
2382 framebuffer = context->getReadFramebuffer();
2383 framebufferHandle = context->getReadFramebufferHandle();
2384 }
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002385 else
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002386 {
2387 framebuffer = context->getDrawFramebuffer();
2388 framebufferHandle = context->getDrawFramebufferHandle();
2389 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002390
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002391 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002392 {
2393 return error(GL_INVALID_OPERATION);
2394 }
2395
2396 switch (attachment)
2397 {
2398 case GL_COLOR_ATTACHMENT0:
2399 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2400 break;
2401 case GL_DEPTH_ATTACHMENT:
2402 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2403 break;
2404 case GL_STENCIL_ATTACHMENT:
2405 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2406 break;
2407 default:
2408 return error(GL_INVALID_ENUM);
2409 }
2410 }
2411 }
2412 catch(std::bad_alloc&)
2413 {
2414 return error(GL_OUT_OF_MEMORY);
2415 }
2416}
2417
2418void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2419{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002420 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002421 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002422
2423 try
2424 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002425 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002426 {
2427 return error(GL_INVALID_ENUM);
2428 }
2429
2430 switch (attachment)
2431 {
2432 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002433 case GL_DEPTH_ATTACHMENT:
2434 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002435 break;
2436 default:
2437 return error(GL_INVALID_ENUM);
2438 }
2439
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002440 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002441
2442 if (context)
2443 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002444 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002445 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002446 textarget = GL_NONE;
2447 }
2448 else
2449 {
2450 gl::Texture *tex = context->getTexture(texture);
2451
2452 if (tex == NULL)
2453 {
2454 return error(GL_INVALID_OPERATION);
2455 }
2456
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002457 switch (textarget)
2458 {
2459 case GL_TEXTURE_2D:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002460 {
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002461 if (tex->getTarget() != GL_TEXTURE_2D)
2462 {
2463 return error(GL_INVALID_OPERATION);
2464 }
2465 gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
daniel@transgaming.com92f49922012-05-09 15:49:19 +00002466 if (tex2d->isCompressed(0))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002467 {
2468 return error(GL_INVALID_OPERATION);
2469 }
2470 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002471 }
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002472
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002473 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002474 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002475 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002476 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002477 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002478 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002479 {
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002480 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2481 {
2482 return error(GL_INVALID_OPERATION);
2483 }
2484 gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00002485 if (texcube->isCompressed(textarget, level))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002486 {
2487 return error(GL_INVALID_OPERATION);
2488 }
2489 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002490 }
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002491
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002492 default:
2493 return error(GL_INVALID_ENUM);
2494 }
2495
2496 if (level != 0)
2497 {
2498 return error(GL_INVALID_VALUE);
2499 }
2500 }
2501
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002502 gl::Framebuffer *framebuffer = NULL;
2503 GLuint framebufferHandle = 0;
2504 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2505 {
2506 framebuffer = context->getReadFramebuffer();
2507 framebufferHandle = context->getReadFramebufferHandle();
2508 }
2509 else
2510 {
2511 framebuffer = context->getDrawFramebuffer();
2512 framebufferHandle = context->getDrawFramebufferHandle();
2513 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002514
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002515 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002516 {
2517 return error(GL_INVALID_OPERATION);
2518 }
2519
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002520 switch (attachment)
2521 {
2522 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2523 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2524 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2525 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002526 }
2527 }
2528 catch(std::bad_alloc&)
2529 {
2530 return error(GL_OUT_OF_MEMORY);
2531 }
2532}
2533
2534void __stdcall glFrontFace(GLenum mode)
2535{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002536 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002537
2538 try
2539 {
2540 switch (mode)
2541 {
2542 case GL_CW:
2543 case GL_CCW:
2544 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002545 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002546
2547 if (context)
2548 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002549 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002550 }
2551 }
2552 break;
2553 default:
2554 return error(GL_INVALID_ENUM);
2555 }
2556 }
2557 catch(std::bad_alloc&)
2558 {
2559 return error(GL_OUT_OF_MEMORY);
2560 }
2561}
2562
2563void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2564{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002565 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002566
2567 try
2568 {
2569 if (n < 0)
2570 {
2571 return error(GL_INVALID_VALUE);
2572 }
2573
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002574 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002575
2576 if (context)
2577 {
2578 for (int i = 0; i < n; i++)
2579 {
2580 buffers[i] = context->createBuffer();
2581 }
2582 }
2583 }
2584 catch(std::bad_alloc&)
2585 {
2586 return error(GL_OUT_OF_MEMORY);
2587 }
2588}
2589
2590void __stdcall glGenerateMipmap(GLenum target)
2591{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002592 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002593
2594 try
2595 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002596 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002597
2598 if (context)
2599 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002600 switch (target)
2601 {
2602 case GL_TEXTURE_2D:
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002603 {
2604 gl::Texture2D *tex2d = context->getTexture2D();
2605
daniel@transgaming.com92f49922012-05-09 15:49:19 +00002606 if (tex2d->isCompressed(0))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002607 {
2608 return error(GL_INVALID_OPERATION);
2609 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00002610 if (tex2d->isDepth(0))
2611 {
2612 return error(GL_INVALID_OPERATION);
2613 }
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002614
2615 tex2d->generateMipmaps();
2616 break;
2617 }
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002618
2619 case GL_TEXTURE_CUBE_MAP:
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002620 {
2621 gl::TextureCubeMap *texcube = context->getTextureCubeMap();
2622
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00002623 if (texcube->isCompressed(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002624 {
2625 return error(GL_INVALID_OPERATION);
2626 }
2627
2628 texcube->generateMipmaps();
2629 break;
2630 }
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002631
2632 default:
2633 return error(GL_INVALID_ENUM);
2634 }
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002635 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002636 }
2637 catch(std::bad_alloc&)
2638 {
2639 return error(GL_OUT_OF_MEMORY);
2640 }
2641}
2642
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002643void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2644{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002645 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002646
2647 try
2648 {
2649 if (n < 0)
2650 {
2651 return error(GL_INVALID_VALUE);
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 for (int i = 0; i < n; i++)
2659 {
2660 fences[i] = context->createFence();
2661 }
2662 }
2663 }
2664 catch(std::bad_alloc&)
2665 {
2666 return error(GL_OUT_OF_MEMORY);
2667 }
2668}
2669
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002670void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2671{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002672 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002673
2674 try
2675 {
2676 if (n < 0)
2677 {
2678 return error(GL_INVALID_VALUE);
2679 }
2680
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002681 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002682
2683 if (context)
2684 {
2685 for (int i = 0; i < n; i++)
2686 {
2687 framebuffers[i] = context->createFramebuffer();
2688 }
2689 }
2690 }
2691 catch(std::bad_alloc&)
2692 {
2693 return error(GL_OUT_OF_MEMORY);
2694 }
2695}
2696
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00002697void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
2698{
2699 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
2700
2701 try
2702 {
2703 if (n < 0)
2704 {
2705 return error(GL_INVALID_VALUE);
2706 }
2707
2708 gl::Context *context = gl::getNonLostContext();
2709
2710 if (context)
2711 {
2712 for (int i = 0; i < n; i++)
2713 {
2714 ids[i] = context->createQuery();
2715 }
2716 }
2717 }
2718 catch(std::bad_alloc&)
2719 {
2720 return error(GL_OUT_OF_MEMORY);
2721 }
2722}
2723
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002724void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2725{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002726 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002727
2728 try
2729 {
2730 if (n < 0)
2731 {
2732 return error(GL_INVALID_VALUE);
2733 }
2734
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002735 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002736
2737 if (context)
2738 {
2739 for (int i = 0; i < n; i++)
2740 {
2741 renderbuffers[i] = context->createRenderbuffer();
2742 }
2743 }
2744 }
2745 catch(std::bad_alloc&)
2746 {
2747 return error(GL_OUT_OF_MEMORY);
2748 }
2749}
2750
2751void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2752{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002753 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002754
2755 try
2756 {
2757 if (n < 0)
2758 {
2759 return error(GL_INVALID_VALUE);
2760 }
2761
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002762 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002763
2764 if (context)
2765 {
2766 for (int i = 0; i < n; i++)
2767 {
2768 textures[i] = context->createTexture();
2769 }
2770 }
2771 }
2772 catch(std::bad_alloc&)
2773 {
2774 return error(GL_OUT_OF_MEMORY);
2775 }
2776}
2777
daniel@transgaming.com85423182010-04-22 13:35:27 +00002778void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002779{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002780 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002781 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002782 program, index, bufsize, length, size, type, name);
2783
2784 try
2785 {
2786 if (bufsize < 0)
2787 {
2788 return error(GL_INVALID_VALUE);
2789 }
2790
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002791 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com85423182010-04-22 13:35:27 +00002792
2793 if (context)
2794 {
2795 gl::Program *programObject = context->getProgram(program);
2796
2797 if (!programObject)
2798 {
2799 if (context->getShader(program))
2800 {
2801 return error(GL_INVALID_OPERATION);
2802 }
2803 else
2804 {
2805 return error(GL_INVALID_VALUE);
2806 }
2807 }
2808
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002809 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002810 {
2811 return error(GL_INVALID_VALUE);
2812 }
2813
2814 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2815 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002816 }
2817 catch(std::bad_alloc&)
2818 {
2819 return error(GL_OUT_OF_MEMORY);
2820 }
2821}
2822
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002823void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002824{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002825 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002826 "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 +00002827 program, index, bufsize, length, size, type, name);
2828
2829 try
2830 {
2831 if (bufsize < 0)
2832 {
2833 return error(GL_INVALID_VALUE);
2834 }
2835
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002836 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002837
2838 if (context)
2839 {
2840 gl::Program *programObject = context->getProgram(program);
2841
2842 if (!programObject)
2843 {
2844 if (context->getShader(program))
2845 {
2846 return error(GL_INVALID_OPERATION);
2847 }
2848 else
2849 {
2850 return error(GL_INVALID_VALUE);
2851 }
2852 }
2853
2854 if (index >= (GLuint)programObject->getActiveUniformCount())
2855 {
2856 return error(GL_INVALID_VALUE);
2857 }
2858
2859 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2860 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002861 }
2862 catch(std::bad_alloc&)
2863 {
2864 return error(GL_OUT_OF_MEMORY);
2865 }
2866}
2867
2868void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2869{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002870 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 +00002871 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002872
2873 try
2874 {
2875 if (maxcount < 0)
2876 {
2877 return error(GL_INVALID_VALUE);
2878 }
2879
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002880 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002881
2882 if (context)
2883 {
2884 gl::Program *programObject = context->getProgram(program);
2885
2886 if (!programObject)
2887 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002888 if (context->getShader(program))
2889 {
2890 return error(GL_INVALID_OPERATION);
2891 }
2892 else
2893 {
2894 return error(GL_INVALID_VALUE);
2895 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002896 }
2897
2898 return programObject->getAttachedShaders(maxcount, count, shaders);
2899 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002900 }
2901 catch(std::bad_alloc&)
2902 {
2903 return error(GL_OUT_OF_MEMORY);
2904 }
2905}
2906
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002907int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002908{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002909 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002910
2911 try
2912 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002913 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002914
2915 if (context)
2916 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002917
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002918 gl::Program *programObject = context->getProgram(program);
2919
2920 if (!programObject)
2921 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002922 if (context->getShader(program))
2923 {
2924 return error(GL_INVALID_OPERATION, -1);
2925 }
2926 else
2927 {
2928 return error(GL_INVALID_VALUE, -1);
2929 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002930 }
2931
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00002932 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
daniel@transgaming.com716056c2012-07-24 18:38:59 +00002933 if (!programObject->isLinked() || !programBinary)
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002934 {
2935 return error(GL_INVALID_OPERATION, -1);
2936 }
2937
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00002938 return programBinary->getAttributeLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002939 }
2940 }
2941 catch(std::bad_alloc&)
2942 {
2943 return error(GL_OUT_OF_MEMORY, -1);
2944 }
2945
2946 return -1;
2947}
2948
2949void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2950{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002951 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002952
2953 try
2954 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002955 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002956
2957 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002958 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002959 if (!(context->getBooleanv(pname, params)))
2960 {
2961 GLenum nativeType;
2962 unsigned int numParams = 0;
2963 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2964 return error(GL_INVALID_ENUM);
2965
2966 if (numParams == 0)
2967 return; // it is known that the pname is valid, but there are no parameters to return
2968
2969 if (nativeType == GL_FLOAT)
2970 {
2971 GLfloat *floatParams = NULL;
2972 floatParams = new GLfloat[numParams];
2973
2974 context->getFloatv(pname, floatParams);
2975
2976 for (unsigned int i = 0; i < numParams; ++i)
2977 {
2978 if (floatParams[i] == 0.0f)
2979 params[i] = GL_FALSE;
2980 else
2981 params[i] = GL_TRUE;
2982 }
2983
2984 delete [] floatParams;
2985 }
2986 else if (nativeType == GL_INT)
2987 {
2988 GLint *intParams = NULL;
2989 intParams = new GLint[numParams];
2990
2991 context->getIntegerv(pname, intParams);
2992
2993 for (unsigned int i = 0; i < numParams; ++i)
2994 {
2995 if (intParams[i] == 0)
2996 params[i] = GL_FALSE;
2997 else
2998 params[i] = GL_TRUE;
2999 }
3000
3001 delete [] intParams;
3002 }
3003 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003004 }
3005 }
3006 catch(std::bad_alloc&)
3007 {
3008 return error(GL_OUT_OF_MEMORY);
3009 }
3010}
3011
3012void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
3013{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003014 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 +00003015
3016 try
3017 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003018 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00003019
3020 if (context)
3021 {
3022 gl::Buffer *buffer;
3023
3024 switch (target)
3025 {
3026 case GL_ARRAY_BUFFER:
3027 buffer = context->getArrayBuffer();
3028 break;
3029 case GL_ELEMENT_ARRAY_BUFFER:
3030 buffer = context->getElementArrayBuffer();
3031 break;
3032 default: return error(GL_INVALID_ENUM);
3033 }
3034
3035 if (!buffer)
3036 {
3037 // A null buffer means that "0" is bound to the requested buffer target
3038 return error(GL_INVALID_OPERATION);
3039 }
3040
3041 switch (pname)
3042 {
3043 case GL_BUFFER_USAGE:
3044 *params = buffer->usage();
3045 break;
3046 case GL_BUFFER_SIZE:
3047 *params = buffer->size();
3048 break;
3049 default: return error(GL_INVALID_ENUM);
3050 }
3051 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003052 }
3053 catch(std::bad_alloc&)
3054 {
3055 return error(GL_OUT_OF_MEMORY);
3056 }
3057}
3058
3059GLenum __stdcall glGetError(void)
3060{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003061 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003062
3063 gl::Context *context = gl::getContext();
3064
3065 if (context)
3066 {
daniel@transgaming.com82b28912011-12-12 21:01:35 +00003067 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003068 }
3069
3070 return GL_NO_ERROR;
3071}
3072
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003073void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
3074{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003075 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003076
3077 try
3078 {
3079
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003080 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003081
3082 if (context)
3083 {
3084 gl::Fence *fenceObject = context->getFence(fence);
3085
3086 if (fenceObject == NULL)
3087 {
3088 return error(GL_INVALID_OPERATION);
3089 }
3090
3091 fenceObject->getFenceiv(pname, params);
3092 }
3093 }
3094 catch(std::bad_alloc&)
3095 {
3096 return error(GL_OUT_OF_MEMORY);
3097 }
3098}
3099
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003100void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
3101{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003102 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003103
3104 try
3105 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003106 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003107
3108 if (context)
3109 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003110 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003111 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003112 GLenum nativeType;
3113 unsigned int numParams = 0;
3114 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3115 return error(GL_INVALID_ENUM);
3116
3117 if (numParams == 0)
3118 return; // it is known that the pname is valid, but that there are no parameters to return.
3119
3120 if (nativeType == GL_BOOL)
3121 {
3122 GLboolean *boolParams = NULL;
3123 boolParams = new GLboolean[numParams];
3124
3125 context->getBooleanv(pname, boolParams);
3126
3127 for (unsigned int i = 0; i < numParams; ++i)
3128 {
3129 if (boolParams[i] == GL_FALSE)
3130 params[i] = 0.0f;
3131 else
3132 params[i] = 1.0f;
3133 }
3134
3135 delete [] boolParams;
3136 }
3137 else if (nativeType == GL_INT)
3138 {
3139 GLint *intParams = NULL;
3140 intParams = new GLint[numParams];
3141
3142 context->getIntegerv(pname, intParams);
3143
3144 for (unsigned int i = 0; i < numParams; ++i)
3145 {
3146 params[i] = (GLfloat)intParams[i];
3147 }
3148
3149 delete [] intParams;
3150 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003151 }
3152 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003153 }
3154 catch(std::bad_alloc&)
3155 {
3156 return error(GL_OUT_OF_MEMORY);
3157 }
3158}
3159
3160void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
3161{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003162 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 +00003163 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003164
3165 try
3166 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003167 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003168
3169 if (context)
3170 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003171 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003172 {
3173 return error(GL_INVALID_ENUM);
3174 }
3175
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003176 gl::Framebuffer *framebuffer = NULL;
3177 if (target == GL_READ_FRAMEBUFFER_ANGLE)
3178 {
3179 if(context->getReadFramebufferHandle() == 0)
3180 {
3181 return error(GL_INVALID_OPERATION);
3182 }
3183
3184 framebuffer = context->getReadFramebuffer();
3185 }
3186 else
3187 {
3188 if (context->getDrawFramebufferHandle() == 0)
3189 {
3190 return error(GL_INVALID_OPERATION);
3191 }
3192
3193 framebuffer = context->getDrawFramebuffer();
3194 }
3195
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003196 GLenum attachmentType;
3197 GLuint attachmentHandle;
3198 switch (attachment)
3199 {
3200 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003201 attachmentType = framebuffer->getColorbufferType();
3202 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003203 break;
3204 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003205 attachmentType = framebuffer->getDepthbufferType();
3206 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003207 break;
3208 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003209 attachmentType = framebuffer->getStencilbufferType();
3210 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003211 break;
3212 default: return error(GL_INVALID_ENUM);
3213 }
3214
3215 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00003216 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003217 {
3218 attachmentObjectType = attachmentType;
3219 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +00003220 else if (gl::IsInternalTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003221 {
3222 attachmentObjectType = GL_TEXTURE;
3223 }
apatrick@chromium.orga1d80592012-01-25 21:52:10 +00003224 else
3225 {
3226 UNREACHABLE();
3227 return;
3228 }
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003229
3230 switch (pname)
3231 {
3232 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3233 *params = attachmentObjectType;
3234 break;
3235 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3236 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
3237 {
3238 *params = attachmentHandle;
3239 }
3240 else
3241 {
3242 return error(GL_INVALID_ENUM);
3243 }
3244 break;
3245 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3246 if (attachmentObjectType == GL_TEXTURE)
3247 {
3248 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
3249 }
3250 else
3251 {
3252 return error(GL_INVALID_ENUM);
3253 }
3254 break;
3255 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3256 if (attachmentObjectType == GL_TEXTURE)
3257 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00003258 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003259 {
3260 *params = attachmentType;
3261 }
3262 else
3263 {
3264 *params = 0;
3265 }
3266 }
3267 else
3268 {
3269 return error(GL_INVALID_ENUM);
3270 }
3271 break;
3272 default:
3273 return error(GL_INVALID_ENUM);
3274 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003275 }
3276 }
3277 catch(std::bad_alloc&)
3278 {
3279 return error(GL_OUT_OF_MEMORY);
3280 }
3281}
3282
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00003283GLenum __stdcall glGetGraphicsResetStatusEXT(void)
3284{
3285 EVENT("()");
3286
3287 try
3288 {
3289 gl::Context *context = gl::getContext();
3290
3291 if (context)
3292 {
3293 return context->getResetStatus();
3294 }
3295
3296 return GL_NO_ERROR;
3297 }
3298 catch(std::bad_alloc&)
3299 {
3300 return GL_OUT_OF_MEMORY;
3301 }
3302}
3303
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003304void __stdcall glGetIntegerv(GLenum pname, GLint* params)
3305{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003306 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003307
3308 try
3309 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003310 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003311
3312 if (context)
3313 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003314 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003315 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003316 GLenum nativeType;
3317 unsigned int numParams = 0;
3318 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3319 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003320
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003321 if (numParams == 0)
3322 return; // it is known that pname is valid, but there are no parameters to return
3323
3324 if (nativeType == GL_BOOL)
3325 {
3326 GLboolean *boolParams = NULL;
3327 boolParams = new GLboolean[numParams];
3328
3329 context->getBooleanv(pname, boolParams);
3330
3331 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003332 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003333 if (boolParams[i] == GL_FALSE)
3334 params[i] = 0;
3335 else
3336 params[i] = 1;
3337 }
3338
3339 delete [] boolParams;
3340 }
3341 else if (nativeType == GL_FLOAT)
3342 {
3343 GLfloat *floatParams = NULL;
3344 floatParams = new GLfloat[numParams];
3345
3346 context->getFloatv(pname, floatParams);
3347
3348 for (unsigned int i = 0; i < numParams; ++i)
3349 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00003350 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 +00003351 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003352 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003353 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003354 else
3355 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 +00003356 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003357
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003358 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003359 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003360 }
3361 }
3362 }
3363 catch(std::bad_alloc&)
3364 {
3365 return error(GL_OUT_OF_MEMORY);
3366 }
3367}
3368
3369void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3370{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003371 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003372
3373 try
3374 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003375 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003376
3377 if (context)
3378 {
3379 gl::Program *programObject = context->getProgram(program);
3380
3381 if (!programObject)
3382 {
3383 return error(GL_INVALID_VALUE);
3384 }
3385
3386 switch (pname)
3387 {
3388 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003389 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003390 return;
3391 case GL_LINK_STATUS:
daniel@transgaming.com716056c2012-07-24 18:38:59 +00003392 *params = programObject->isLinked();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003393 return;
3394 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003395 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003396 return;
3397 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003398 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003399 return;
3400 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003401 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003402 return;
3403 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003404 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003405 return;
3406 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003407 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003408 return;
3409 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003410 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003411 return;
3412 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003413 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003414 return;
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00003415 case GL_PROGRAM_BINARY_LENGTH_OES:
apatrick@chromium.org90080e32012-07-09 22:15:33 +00003416 *params = programObject->getProgramBinaryLength();
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00003417 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003418 default:
3419 return error(GL_INVALID_ENUM);
3420 }
3421 }
3422 }
3423 catch(std::bad_alloc&)
3424 {
3425 return error(GL_OUT_OF_MEMORY);
3426 }
3427}
3428
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003429void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003430{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003431 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 +00003432 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003433
3434 try
3435 {
3436 if (bufsize < 0)
3437 {
3438 return error(GL_INVALID_VALUE);
3439 }
3440
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003441 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003442
3443 if (context)
3444 {
3445 gl::Program *programObject = context->getProgram(program);
3446
3447 if (!programObject)
3448 {
3449 return error(GL_INVALID_VALUE);
3450 }
3451
3452 programObject->getInfoLog(bufsize, length, infolog);
3453 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003454 }
3455 catch(std::bad_alloc&)
3456 {
3457 return error(GL_OUT_OF_MEMORY);
3458 }
3459}
3460
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003461void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3462{
3463 EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
3464
3465 try
3466 {
3467 switch (pname)
3468 {
3469 case GL_CURRENT_QUERY_EXT:
3470 break;
3471 default:
3472 return error(GL_INVALID_ENUM);
3473 }
3474
3475 gl::Context *context = gl::getNonLostContext();
3476
3477 if (context)
3478 {
3479 params[0] = context->getActiveQuery(target);
3480 }
3481 }
3482 catch(std::bad_alloc&)
3483 {
3484 return error(GL_OUT_OF_MEMORY);
3485 }
3486}
3487
3488void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
3489{
3490 EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
3491
3492 try
3493 {
3494 switch (pname)
3495 {
3496 case GL_QUERY_RESULT_EXT:
3497 case GL_QUERY_RESULT_AVAILABLE_EXT:
3498 break;
3499 default:
3500 return error(GL_INVALID_ENUM);
3501 }
3502 gl::Context *context = gl::getNonLostContext();
3503
3504 if (context)
3505 {
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003506 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
3507
3508 if (!queryObject)
3509 {
3510 return error(GL_INVALID_OPERATION);
3511 }
3512
3513 if (context->getActiveQuery(queryObject->getType()) == id)
3514 {
3515 return error(GL_INVALID_OPERATION);
3516 }
3517
3518 switch(pname)
3519 {
3520 case GL_QUERY_RESULT_EXT:
3521 params[0] = queryObject->getResult();
3522 break;
3523 case GL_QUERY_RESULT_AVAILABLE_EXT:
3524 params[0] = queryObject->isResultAvailable();
3525 break;
3526 default:
3527 ASSERT(false);
3528 }
3529 }
3530 }
3531 catch(std::bad_alloc&)
3532 {
3533 return error(GL_OUT_OF_MEMORY);
3534 }
3535}
3536
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003537void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3538{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003539 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 +00003540
3541 try
3542 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003543 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003544
3545 if (context)
3546 {
3547 if (target != GL_RENDERBUFFER)
3548 {
3549 return error(GL_INVALID_ENUM);
3550 }
3551
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003552 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003553 {
3554 return error(GL_INVALID_OPERATION);
3555 }
3556
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003557 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003558
3559 switch (pname)
3560 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003561 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3562 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3563 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3564 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3565 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3566 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3567 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3568 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3569 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003570 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003571 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003572 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003573 *params = renderbuffer->getSamples();
3574 }
3575 else
3576 {
3577 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003578 }
3579 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003580 default:
3581 return error(GL_INVALID_ENUM);
3582 }
3583 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003584 }
3585 catch(std::bad_alloc&)
3586 {
3587 return error(GL_OUT_OF_MEMORY);
3588 }
3589}
3590
3591void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3592{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003593 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003594
3595 try
3596 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003597 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003598
3599 if (context)
3600 {
3601 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003602
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003603 if (!shaderObject)
3604 {
3605 return error(GL_INVALID_VALUE);
3606 }
3607
3608 switch (pname)
3609 {
3610 case GL_SHADER_TYPE:
3611 *params = shaderObject->getType();
3612 return;
3613 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003614 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003615 return;
3616 case GL_COMPILE_STATUS:
3617 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3618 return;
3619 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003620 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003621 return;
3622 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003623 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003624 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003625 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3626 *params = shaderObject->getTranslatedSourceLength();
3627 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003628 default:
3629 return error(GL_INVALID_ENUM);
3630 }
3631 }
3632 }
3633 catch(std::bad_alloc&)
3634 {
3635 return error(GL_OUT_OF_MEMORY);
3636 }
3637}
3638
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003639void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003640{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003641 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 +00003642 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003643
3644 try
3645 {
3646 if (bufsize < 0)
3647 {
3648 return error(GL_INVALID_VALUE);
3649 }
3650
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003651 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003652
3653 if (context)
3654 {
3655 gl::Shader *shaderObject = context->getShader(shader);
3656
3657 if (!shaderObject)
3658 {
3659 return error(GL_INVALID_VALUE);
3660 }
3661
3662 shaderObject->getInfoLog(bufsize, length, infolog);
3663 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003664 }
3665 catch(std::bad_alloc&)
3666 {
3667 return error(GL_OUT_OF_MEMORY);
3668 }
3669}
3670
3671void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3672{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003673 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 +00003674 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003675
3676 try
3677 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003678 switch (shadertype)
3679 {
3680 case GL_VERTEX_SHADER:
3681 case GL_FRAGMENT_SHADER:
3682 break;
3683 default:
3684 return error(GL_INVALID_ENUM);
3685 }
3686
3687 switch (precisiontype)
3688 {
3689 case GL_LOW_FLOAT:
3690 case GL_MEDIUM_FLOAT:
3691 case GL_HIGH_FLOAT:
3692 // Assume IEEE 754 precision
3693 range[0] = 127;
3694 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003695 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003696 break;
3697 case GL_LOW_INT:
3698 case GL_MEDIUM_INT:
3699 case GL_HIGH_INT:
3700 // Some (most) hardware only supports single-precision floating-point numbers,
3701 // which can accurately represent integers up to +/-16777216
3702 range[0] = 24;
3703 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003704 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003705 break;
3706 default:
3707 return error(GL_INVALID_ENUM);
3708 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003709 }
3710 catch(std::bad_alloc&)
3711 {
3712 return error(GL_OUT_OF_MEMORY);
3713 }
3714}
3715
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003716void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003717{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003718 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 +00003719 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003720
3721 try
3722 {
3723 if (bufsize < 0)
3724 {
3725 return error(GL_INVALID_VALUE);
3726 }
3727
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003728 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003729
3730 if (context)
3731 {
3732 gl::Shader *shaderObject = context->getShader(shader);
3733
3734 if (!shaderObject)
3735 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003736 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003737 }
3738
3739 shaderObject->getSource(bufsize, length, source);
3740 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003741 }
3742 catch(std::bad_alloc&)
3743 {
3744 return error(GL_OUT_OF_MEMORY);
3745 }
3746}
3747
zmo@google.coma574f782011-10-03 21:45:23 +00003748void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3749{
3750 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3751 shader, bufsize, length, source);
3752
3753 try
3754 {
3755 if (bufsize < 0)
3756 {
3757 return error(GL_INVALID_VALUE);
3758 }
3759
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003760 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003761
3762 if (context)
3763 {
3764 gl::Shader *shaderObject = context->getShader(shader);
3765
3766 if (!shaderObject)
3767 {
3768 return error(GL_INVALID_OPERATION);
3769 }
3770
3771 shaderObject->getTranslatedSource(bufsize, length, source);
3772 }
3773 }
3774 catch(std::bad_alloc&)
3775 {
3776 return error(GL_OUT_OF_MEMORY);
3777 }
3778}
3779
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003780const GLubyte* __stdcall glGetString(GLenum name)
3781{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003782 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003783
3784 try
3785 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003786 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003787
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003788 switch (name)
3789 {
3790 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003791 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003792 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003793 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003794 case GL_VERSION:
daniel@transgaming.com1825d8e2012-08-27 16:25:29 +00003795 return (GLubyte*)"OpenGL ES 2.0 (ANGLE " VERSION_STRING ")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003796 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.com1825d8e2012-08-27 16:25:29 +00003797 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " VERSION_STRING ")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003798 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003799 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003800 default:
3801 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3802 }
3803 }
3804 catch(std::bad_alloc&)
3805 {
3806 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3807 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003808}
3809
3810void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3811{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003812 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 +00003813
3814 try
3815 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003816 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003817
3818 if (context)
3819 {
3820 gl::Texture *texture;
3821
3822 switch (target)
3823 {
3824 case GL_TEXTURE_2D:
3825 texture = context->getTexture2D();
3826 break;
3827 case GL_TEXTURE_CUBE_MAP:
3828 texture = context->getTextureCubeMap();
3829 break;
3830 default:
3831 return error(GL_INVALID_ENUM);
3832 }
3833
3834 switch (pname)
3835 {
3836 case GL_TEXTURE_MAG_FILTER:
3837 *params = (GLfloat)texture->getMagFilter();
3838 break;
3839 case GL_TEXTURE_MIN_FILTER:
3840 *params = (GLfloat)texture->getMinFilter();
3841 break;
3842 case GL_TEXTURE_WRAP_S:
3843 *params = (GLfloat)texture->getWrapS();
3844 break;
3845 case GL_TEXTURE_WRAP_T:
3846 *params = (GLfloat)texture->getWrapT();
3847 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003848 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3849 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3850 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003851 case GL_TEXTURE_USAGE_ANGLE:
3852 *params = (GLfloat)texture->getUsage();
3853 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00003854 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3855 if (!context->supportsTextureFilterAnisotropy())
3856 {
3857 return error(GL_INVALID_ENUM);
3858 }
3859 *params = (GLfloat)texture->getMaxAnisotropy();
3860 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003861 default:
3862 return error(GL_INVALID_ENUM);
3863 }
3864 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003865 }
3866 catch(std::bad_alloc&)
3867 {
3868 return error(GL_OUT_OF_MEMORY);
3869 }
3870}
3871
3872void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3873{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003874 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 +00003875
3876 try
3877 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003878 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003879
3880 if (context)
3881 {
3882 gl::Texture *texture;
3883
3884 switch (target)
3885 {
3886 case GL_TEXTURE_2D:
3887 texture = context->getTexture2D();
3888 break;
3889 case GL_TEXTURE_CUBE_MAP:
3890 texture = context->getTextureCubeMap();
3891 break;
3892 default:
3893 return error(GL_INVALID_ENUM);
3894 }
3895
3896 switch (pname)
3897 {
3898 case GL_TEXTURE_MAG_FILTER:
3899 *params = texture->getMagFilter();
3900 break;
3901 case GL_TEXTURE_MIN_FILTER:
3902 *params = texture->getMinFilter();
3903 break;
3904 case GL_TEXTURE_WRAP_S:
3905 *params = texture->getWrapS();
3906 break;
3907 case GL_TEXTURE_WRAP_T:
3908 *params = texture->getWrapT();
3909 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003910 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3911 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3912 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003913 case GL_TEXTURE_USAGE_ANGLE:
3914 *params = texture->getUsage();
3915 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00003916 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3917 if (!context->supportsTextureFilterAnisotropy())
3918 {
3919 return error(GL_INVALID_ENUM);
3920 }
3921 *params = (GLint)texture->getMaxAnisotropy();
3922 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003923 default:
3924 return error(GL_INVALID_ENUM);
3925 }
3926 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003927 }
3928 catch(std::bad_alloc&)
3929 {
3930 return error(GL_OUT_OF_MEMORY);
3931 }
3932}
3933
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003934void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3935{
3936 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3937 program, location, bufSize, params);
3938
3939 try
3940 {
3941 if (bufSize < 0)
3942 {
3943 return error(GL_INVALID_VALUE);
3944 }
3945
3946 gl::Context *context = gl::getNonLostContext();
3947
3948 if (context)
3949 {
3950 if (program == 0)
3951 {
3952 return error(GL_INVALID_VALUE);
3953 }
3954
3955 gl::Program *programObject = context->getProgram(program);
3956
daniel@transgaming.com716056c2012-07-24 18:38:59 +00003957 if (!programObject || !programObject->isLinked())
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003958 {
3959 return error(GL_INVALID_OPERATION);
3960 }
3961
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003962 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
3963 if (!programBinary)
3964 {
3965 return error(GL_INVALID_OPERATION);
3966 }
3967
3968 if (!programBinary->getUniformfv(location, &bufSize, params))
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003969 {
3970 return error(GL_INVALID_OPERATION);
3971 }
3972 }
3973 }
3974 catch(std::bad_alloc&)
3975 {
3976 return error(GL_OUT_OF_MEMORY);
3977 }
3978}
3979
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003980void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3981{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003982 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003983
3984 try
3985 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003986 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003987
3988 if (context)
3989 {
3990 if (program == 0)
3991 {
3992 return error(GL_INVALID_VALUE);
3993 }
3994
3995 gl::Program *programObject = context->getProgram(program);
3996
daniel@transgaming.com716056c2012-07-24 18:38:59 +00003997 if (!programObject || !programObject->isLinked())
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003998 {
3999 return error(GL_INVALID_OPERATION);
4000 }
4001
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004002 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4003 if (!programBinary)
4004 {
4005 return error(GL_INVALID_OPERATION);
4006 }
4007
4008 if (!programBinary->getUniformfv(location, NULL, params))
daniel@transgaming.com9a849122011-11-12 03:18:00 +00004009 {
4010 return error(GL_INVALID_OPERATION);
4011 }
4012 }
4013 }
4014 catch(std::bad_alloc&)
4015 {
4016 return error(GL_OUT_OF_MEMORY);
4017 }
4018}
4019
4020void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
4021{
4022 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
4023 program, location, bufSize, params);
4024
4025 try
4026 {
4027 if (bufSize < 0)
4028 {
4029 return error(GL_INVALID_VALUE);
4030 }
4031
4032 gl::Context *context = gl::getNonLostContext();
4033
4034 if (context)
4035 {
4036 if (program == 0)
4037 {
4038 return error(GL_INVALID_VALUE);
4039 }
4040
4041 gl::Program *programObject = context->getProgram(program);
4042
daniel@transgaming.com716056c2012-07-24 18:38:59 +00004043 if (!programObject || !programObject->isLinked())
daniel@transgaming.com9a849122011-11-12 03:18:00 +00004044 {
4045 return error(GL_INVALID_OPERATION);
4046 }
4047
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004048 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4049 if (!programBinary)
4050 {
4051 return error(GL_INVALID_OPERATION);
4052 }
4053
4054 if (!programBinary->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004055 {
4056 return error(GL_INVALID_OPERATION);
4057 }
4058 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004059 }
4060 catch(std::bad_alloc&)
4061 {
4062 return error(GL_OUT_OF_MEMORY);
4063 }
4064}
4065
4066void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
4067{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004068 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004069
4070 try
4071 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004072 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004073
4074 if (context)
4075 {
4076 if (program == 0)
4077 {
4078 return error(GL_INVALID_VALUE);
4079 }
4080
4081 gl::Program *programObject = context->getProgram(program);
4082
daniel@transgaming.com716056c2012-07-24 18:38:59 +00004083 if (!programObject || !programObject->isLinked())
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004084 {
4085 return error(GL_INVALID_OPERATION);
4086 }
4087
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004088 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4089 if (!programBinary)
4090 {
4091 return error(GL_INVALID_OPERATION);
4092 }
4093
4094 if (!programBinary->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004095 {
4096 return error(GL_INVALID_OPERATION);
4097 }
4098 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004099 }
4100 catch(std::bad_alloc&)
4101 {
4102 return error(GL_OUT_OF_MEMORY);
4103 }
4104}
4105
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004106int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004107{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004108 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004109
4110 try
4111 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004112 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004113
4114 if (strstr(name, "gl_") == name)
4115 {
4116 return -1;
4117 }
4118
4119 if (context)
4120 {
4121 gl::Program *programObject = context->getProgram(program);
4122
4123 if (!programObject)
4124 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00004125 if (context->getShader(program))
4126 {
4127 return error(GL_INVALID_OPERATION, -1);
4128 }
4129 else
4130 {
4131 return error(GL_INVALID_VALUE, -1);
4132 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004133 }
4134
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004135 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
daniel@transgaming.com716056c2012-07-24 18:38:59 +00004136 if (!programObject->isLinked() || !programBinary)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004137 {
4138 return error(GL_INVALID_OPERATION, -1);
4139 }
4140
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004141 return programBinary->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004142 }
4143 }
4144 catch(std::bad_alloc&)
4145 {
4146 return error(GL_OUT_OF_MEMORY, -1);
4147 }
4148
4149 return -1;
4150}
4151
4152void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
4153{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004154 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004155
4156 try
4157 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004158 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004159
daniel@transgaming.come0078962010-04-15 20:45:08 +00004160 if (context)
4161 {
4162 if (index >= gl::MAX_VERTEX_ATTRIBS)
4163 {
4164 return error(GL_INVALID_VALUE);
4165 }
4166
daniel@transgaming.com83921382011-01-08 05:46:00 +00004167 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004168
daniel@transgaming.come0078962010-04-15 20:45:08 +00004169 switch (pname)
4170 {
4171 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004172 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004173 break;
4174 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004175 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004176 break;
4177 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004178 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004179 break;
4180 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004181 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004182 break;
4183 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004184 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004185 break;
4186 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004187 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004188 break;
4189 case GL_CURRENT_VERTEX_ATTRIB:
4190 for (int i = 0; i < 4; ++i)
4191 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004192 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004193 }
4194 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004195 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4196 *params = (GLfloat)attribState.mDivisor;
4197 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004198 default: return error(GL_INVALID_ENUM);
4199 }
4200 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004201 }
4202 catch(std::bad_alloc&)
4203 {
4204 return error(GL_OUT_OF_MEMORY);
4205 }
4206}
4207
4208void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
4209{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004210 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004211
4212 try
4213 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004214 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004215
daniel@transgaming.come0078962010-04-15 20:45:08 +00004216 if (context)
4217 {
4218 if (index >= gl::MAX_VERTEX_ATTRIBS)
4219 {
4220 return error(GL_INVALID_VALUE);
4221 }
4222
daniel@transgaming.com83921382011-01-08 05:46:00 +00004223 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004224
daniel@transgaming.come0078962010-04-15 20:45:08 +00004225 switch (pname)
4226 {
4227 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004228 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004229 break;
4230 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004231 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004232 break;
4233 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004234 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004235 break;
4236 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004237 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004238 break;
4239 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004240 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004241 break;
4242 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004243 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004244 break;
4245 case GL_CURRENT_VERTEX_ATTRIB:
4246 for (int i = 0; i < 4; ++i)
4247 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004248 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004249 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4250 }
4251 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004252 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4253 *params = (GLint)attribState.mDivisor;
4254 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004255 default: return error(GL_INVALID_ENUM);
4256 }
4257 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004258 }
4259 catch(std::bad_alloc&)
4260 {
4261 return error(GL_OUT_OF_MEMORY);
4262 }
4263}
4264
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004265void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004266{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004267 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004268
4269 try
4270 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004271 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004272
daniel@transgaming.come0078962010-04-15 20:45:08 +00004273 if (context)
4274 {
4275 if (index >= gl::MAX_VERTEX_ATTRIBS)
4276 {
4277 return error(GL_INVALID_VALUE);
4278 }
4279
4280 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4281 {
4282 return error(GL_INVALID_ENUM);
4283 }
4284
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004285 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00004286 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004287 }
4288 catch(std::bad_alloc&)
4289 {
4290 return error(GL_OUT_OF_MEMORY);
4291 }
4292}
4293
4294void __stdcall glHint(GLenum target, GLenum mode)
4295{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004296 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004297
4298 try
4299 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004300 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004301 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004302 case GL_FASTEST:
4303 case GL_NICEST:
4304 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004305 break;
4306 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004307 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004308 }
4309
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004310 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004311 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004312 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004313 case GL_GENERATE_MIPMAP_HINT:
4314 if (context) context->setGenerateMipmapHint(mode);
4315 break;
4316 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4317 if (context) context->setFragmentShaderDerivativeHint(mode);
4318 break;
4319 default:
4320 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004321 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004322 }
4323 catch(std::bad_alloc&)
4324 {
4325 return error(GL_OUT_OF_MEMORY);
4326 }
4327}
4328
4329GLboolean __stdcall glIsBuffer(GLuint buffer)
4330{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004331 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004332
4333 try
4334 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004335 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004336
4337 if (context && buffer)
4338 {
4339 gl::Buffer *bufferObject = context->getBuffer(buffer);
4340
4341 if (bufferObject)
4342 {
4343 return GL_TRUE;
4344 }
4345 }
4346 }
4347 catch(std::bad_alloc&)
4348 {
4349 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4350 }
4351
4352 return GL_FALSE;
4353}
4354
4355GLboolean __stdcall glIsEnabled(GLenum cap)
4356{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004357 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004358
4359 try
4360 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004361 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004362
4363 if (context)
4364 {
4365 switch (cap)
4366 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004367 case GL_CULL_FACE: return context->isCullFaceEnabled();
4368 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4369 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4370 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4371 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4372 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4373 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4374 case GL_BLEND: return context->isBlendEnabled();
4375 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004376 default:
4377 return error(GL_INVALID_ENUM, false);
4378 }
4379 }
4380 }
4381 catch(std::bad_alloc&)
4382 {
4383 return error(GL_OUT_OF_MEMORY, false);
4384 }
4385
4386 return false;
4387}
4388
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004389GLboolean __stdcall glIsFenceNV(GLuint fence)
4390{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004391 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004392
4393 try
4394 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004395 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004396
4397 if (context)
4398 {
4399 gl::Fence *fenceObject = context->getFence(fence);
4400
4401 if (fenceObject == NULL)
4402 {
4403 return GL_FALSE;
4404 }
4405
4406 return fenceObject->isFence();
4407 }
4408 }
4409 catch(std::bad_alloc&)
4410 {
4411 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4412 }
4413
4414 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004415}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004416
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004417GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
4418{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004419 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004420
4421 try
4422 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004423 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004424
4425 if (context && framebuffer)
4426 {
4427 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4428
4429 if (framebufferObject)
4430 {
4431 return GL_TRUE;
4432 }
4433 }
4434 }
4435 catch(std::bad_alloc&)
4436 {
4437 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4438 }
4439
4440 return GL_FALSE;
4441}
4442
4443GLboolean __stdcall glIsProgram(GLuint program)
4444{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004445 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004446
4447 try
4448 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004449 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004450
4451 if (context && program)
4452 {
4453 gl::Program *programObject = context->getProgram(program);
4454
4455 if (programObject)
4456 {
4457 return GL_TRUE;
4458 }
4459 }
4460 }
4461 catch(std::bad_alloc&)
4462 {
4463 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4464 }
4465
4466 return GL_FALSE;
4467}
4468
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00004469GLboolean __stdcall glIsQueryEXT(GLuint id)
4470{
4471 EVENT("(GLuint id = %d)", id);
4472
4473 try
4474 {
4475 if (id == 0)
4476 {
4477 return GL_FALSE;
4478 }
4479
4480 gl::Context *context = gl::getNonLostContext();
4481
4482 if (context)
4483 {
4484 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
4485
4486 if (queryObject)
4487 {
4488 return GL_TRUE;
4489 }
4490 }
4491 }
4492 catch(std::bad_alloc&)
4493 {
4494 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4495 }
4496
4497 return GL_FALSE;
4498}
4499
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004500GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
4501{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004502 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004503
4504 try
4505 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004506 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004507
4508 if (context && renderbuffer)
4509 {
4510 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4511
4512 if (renderbufferObject)
4513 {
4514 return GL_TRUE;
4515 }
4516 }
4517 }
4518 catch(std::bad_alloc&)
4519 {
4520 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4521 }
4522
4523 return GL_FALSE;
4524}
4525
4526GLboolean __stdcall glIsShader(GLuint shader)
4527{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004528 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004529
4530 try
4531 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004532 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004533
4534 if (context && shader)
4535 {
4536 gl::Shader *shaderObject = context->getShader(shader);
4537
4538 if (shaderObject)
4539 {
4540 return GL_TRUE;
4541 }
4542 }
4543 }
4544 catch(std::bad_alloc&)
4545 {
4546 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4547 }
4548
4549 return GL_FALSE;
4550}
4551
4552GLboolean __stdcall glIsTexture(GLuint texture)
4553{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004554 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004555
4556 try
4557 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004558 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004559
4560 if (context && texture)
4561 {
4562 gl::Texture *textureObject = context->getTexture(texture);
4563
4564 if (textureObject)
4565 {
4566 return GL_TRUE;
4567 }
4568 }
4569 }
4570 catch(std::bad_alloc&)
4571 {
4572 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4573 }
4574
4575 return GL_FALSE;
4576}
4577
4578void __stdcall glLineWidth(GLfloat width)
4579{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004580 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004581
4582 try
4583 {
4584 if (width <= 0.0f)
4585 {
4586 return error(GL_INVALID_VALUE);
4587 }
4588
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004589 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004590
4591 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004592 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004593 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004594 }
4595 }
4596 catch(std::bad_alloc&)
4597 {
4598 return error(GL_OUT_OF_MEMORY);
4599 }
4600}
4601
4602void __stdcall glLinkProgram(GLuint program)
4603{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004604 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004605
4606 try
4607 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004608 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004609
4610 if (context)
4611 {
4612 gl::Program *programObject = context->getProgram(program);
4613
4614 if (!programObject)
4615 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004616 if (context->getShader(program))
4617 {
4618 return error(GL_INVALID_OPERATION);
4619 }
4620 else
4621 {
4622 return error(GL_INVALID_VALUE);
4623 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004624 }
4625
daniel@transgaming.com95d29422012-07-24 18:36:10 +00004626 context->linkProgram(program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004627 }
4628 }
4629 catch(std::bad_alloc&)
4630 {
4631 return error(GL_OUT_OF_MEMORY);
4632 }
4633}
4634
4635void __stdcall glPixelStorei(GLenum pname, GLint param)
4636{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004637 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004638
4639 try
4640 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004641 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004642
4643 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004644 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004645 switch (pname)
4646 {
4647 case GL_UNPACK_ALIGNMENT:
4648 if (param != 1 && param != 2 && param != 4 && param != 8)
4649 {
4650 return error(GL_INVALID_VALUE);
4651 }
4652
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004653 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004654 break;
4655
4656 case GL_PACK_ALIGNMENT:
4657 if (param != 1 && param != 2 && param != 4 && param != 8)
4658 {
4659 return error(GL_INVALID_VALUE);
4660 }
4661
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004662 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004663 break;
4664
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004665 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4666 context->setPackReverseRowOrder(param != 0);
4667 break;
4668
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004669 default:
4670 return error(GL_INVALID_ENUM);
4671 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004672 }
4673 }
4674 catch(std::bad_alloc&)
4675 {
4676 return error(GL_OUT_OF_MEMORY);
4677 }
4678}
4679
4680void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4681{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004682 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004683
4684 try
4685 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004686 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004687
4688 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004689 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004690 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004691 }
4692 }
4693 catch(std::bad_alloc&)
4694 {
4695 return error(GL_OUT_OF_MEMORY);
4696 }
4697}
4698
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004699void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4700 GLenum format, GLenum type, GLsizei bufSize,
4701 GLvoid *data)
4702{
4703 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4704 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4705 x, y, width, height, format, type, bufSize, data);
4706
4707 try
4708 {
4709 if (width < 0 || height < 0 || bufSize < 0)
4710 {
4711 return error(GL_INVALID_VALUE);
4712 }
4713
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004714 gl::Context *context = gl::getNonLostContext();
4715
4716 if (context)
4717 {
daniel@transgaming.com42944b02012-09-27 17:45:57 +00004718 GLenum currentFormat, currentType;
4719
4720 // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound,
4721 // and attempting to read back if that's the case is an error. The error will be registered
4722 // by getCurrentReadFormat.
4723 if (!context->getCurrentReadFormatType(&currentFormat, &currentType))
4724 return;
4725
4726 if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type))
4727 {
4728 return error(GL_INVALID_OPERATION);
4729 }
4730
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004731 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4732 }
4733 }
4734 catch(std::bad_alloc&)
4735 {
4736 return error(GL_OUT_OF_MEMORY);
4737 }
4738}
4739
4740void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4741 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004742{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004743 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004744 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004745 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004746
4747 try
4748 {
4749 if (width < 0 || height < 0)
4750 {
4751 return error(GL_INVALID_VALUE);
4752 }
4753
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004754 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004755
4756 if (context)
4757 {
daniel@transgaming.com42944b02012-09-27 17:45:57 +00004758 GLenum currentFormat, currentType;
4759
4760 // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound,
4761 // and attempting to read back if that's the case is an error. The error will be registered
4762 // by getCurrentReadFormat.
4763 if (!context->getCurrentReadFormatType(&currentFormat, &currentType))
4764 return;
4765
4766 if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type))
4767 {
4768 return error(GL_INVALID_OPERATION);
4769 }
4770
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004771 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004772 }
4773 }
4774 catch(std::bad_alloc&)
4775 {
4776 return error(GL_OUT_OF_MEMORY);
4777 }
4778}
4779
4780void __stdcall glReleaseShaderCompiler(void)
4781{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004782 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004783
4784 try
4785 {
4786 gl::Shader::releaseCompiler();
4787 }
4788 catch(std::bad_alloc&)
4789 {
4790 return error(GL_OUT_OF_MEMORY);
4791 }
4792}
4793
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004794void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004795{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004796 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 +00004797 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004798
4799 try
4800 {
4801 switch (target)
4802 {
4803 case GL_RENDERBUFFER:
4804 break;
4805 default:
4806 return error(GL_INVALID_ENUM);
4807 }
4808
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004809 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004810 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004811 return error(GL_INVALID_ENUM);
4812 }
4813
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004814 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004815 {
4816 return error(GL_INVALID_VALUE);
4817 }
4818
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004819 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004820
4821 if (context)
4822 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004823 if (width > context->getMaximumRenderbufferDimension() ||
4824 height > context->getMaximumRenderbufferDimension() ||
4825 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004826 {
4827 return error(GL_INVALID_VALUE);
4828 }
4829
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004830 GLuint handle = context->getRenderbufferHandle();
4831 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004832 {
4833 return error(GL_INVALID_OPERATION);
4834 }
4835
4836 switch (internalformat)
4837 {
4838 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004839 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004840 break;
4841 case GL_RGBA4:
4842 case GL_RGB5_A1:
4843 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004844 case GL_RGB8_OES:
4845 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004846 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004847 break;
4848 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004849 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004850 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004851 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004852 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004853 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004854 default:
4855 return error(GL_INVALID_ENUM);
4856 }
4857 }
4858 }
4859 catch(std::bad_alloc&)
4860 {
4861 return error(GL_OUT_OF_MEMORY);
4862 }
4863}
4864
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004865void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4866{
4867 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4868}
4869
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004870void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4871{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004872 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004873
4874 try
4875 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004876 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004877
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004878 if (context)
4879 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004880 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004881 }
4882 }
4883 catch(std::bad_alloc&)
4884 {
4885 return error(GL_OUT_OF_MEMORY);
4886 }
4887}
4888
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004889void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4890{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004891 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004892
4893 try
4894 {
4895 if (condition != GL_ALL_COMPLETED_NV)
4896 {
4897 return error(GL_INVALID_ENUM);
4898 }
4899
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004900 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004901
4902 if (context)
4903 {
4904 gl::Fence *fenceObject = context->getFence(fence);
4905
4906 if (fenceObject == NULL)
4907 {
4908 return error(GL_INVALID_OPERATION);
4909 }
4910
4911 fenceObject->setFence(condition);
4912 }
4913 }
4914 catch(std::bad_alloc&)
4915 {
4916 return error(GL_OUT_OF_MEMORY);
4917 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004918}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004919
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004920void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4921{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004922 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 +00004923
4924 try
4925 {
4926 if (width < 0 || height < 0)
4927 {
4928 return error(GL_INVALID_VALUE);
4929 }
4930
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004931 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004932
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004933 if (context)
4934 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004935 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004936 }
4937 }
4938 catch(std::bad_alloc&)
4939 {
4940 return error(GL_OUT_OF_MEMORY);
4941 }
4942}
4943
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004944void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004945{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004946 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004947 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004948 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004949
4950 try
4951 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004952 // No binary shader formats are supported.
4953 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004954 }
4955 catch(std::bad_alloc&)
4956 {
4957 return error(GL_OUT_OF_MEMORY);
4958 }
4959}
4960
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004961void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004962{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004963 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 +00004964 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004965
4966 try
4967 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004968 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004969 {
4970 return error(GL_INVALID_VALUE);
4971 }
4972
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004973 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004974
4975 if (context)
4976 {
4977 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004978
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004979 if (!shaderObject)
4980 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004981 if (context->getProgram(shader))
4982 {
4983 return error(GL_INVALID_OPERATION);
4984 }
4985 else
4986 {
4987 return error(GL_INVALID_VALUE);
4988 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004989 }
4990
4991 shaderObject->setSource(count, string, length);
4992 }
4993 }
4994 catch(std::bad_alloc&)
4995 {
4996 return error(GL_OUT_OF_MEMORY);
4997 }
4998}
4999
5000void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
5001{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005002 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005003}
5004
5005void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
5006{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005007 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 +00005008
5009 try
5010 {
5011 switch (face)
5012 {
5013 case GL_FRONT:
5014 case GL_BACK:
5015 case GL_FRONT_AND_BACK:
5016 break;
5017 default:
5018 return error(GL_INVALID_ENUM);
5019 }
5020
5021 switch (func)
5022 {
5023 case GL_NEVER:
5024 case GL_ALWAYS:
5025 case GL_LESS:
5026 case GL_LEQUAL:
5027 case GL_EQUAL:
5028 case GL_GEQUAL:
5029 case GL_GREATER:
5030 case GL_NOTEQUAL:
5031 break;
5032 default:
5033 return error(GL_INVALID_ENUM);
5034 }
5035
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005036 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005037
5038 if (context)
5039 {
5040 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5041 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005042 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005043 }
5044
5045 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5046 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005047 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005048 }
5049 }
5050 }
5051 catch(std::bad_alloc&)
5052 {
5053 return error(GL_OUT_OF_MEMORY);
5054 }
5055}
5056
5057void __stdcall glStencilMask(GLuint mask)
5058{
5059 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
5060}
5061
5062void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
5063{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005064 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005065
5066 try
5067 {
5068 switch (face)
5069 {
5070 case GL_FRONT:
5071 case GL_BACK:
5072 case GL_FRONT_AND_BACK:
5073 break;
5074 default:
5075 return error(GL_INVALID_ENUM);
5076 }
5077
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005078 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005079
5080 if (context)
5081 {
5082 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5083 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005084 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005085 }
5086
5087 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5088 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005089 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005090 }
5091 }
5092 }
5093 catch(std::bad_alloc&)
5094 {
5095 return error(GL_OUT_OF_MEMORY);
5096 }
5097}
5098
5099void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
5100{
5101 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
5102}
5103
5104void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
5105{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005106 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 +00005107 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005108
5109 try
5110 {
5111 switch (face)
5112 {
5113 case GL_FRONT:
5114 case GL_BACK:
5115 case GL_FRONT_AND_BACK:
5116 break;
5117 default:
5118 return error(GL_INVALID_ENUM);
5119 }
5120
5121 switch (fail)
5122 {
5123 case GL_ZERO:
5124 case GL_KEEP:
5125 case GL_REPLACE:
5126 case GL_INCR:
5127 case GL_DECR:
5128 case GL_INVERT:
5129 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005130 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005131 break;
5132 default:
5133 return error(GL_INVALID_ENUM);
5134 }
5135
5136 switch (zfail)
5137 {
5138 case GL_ZERO:
5139 case GL_KEEP:
5140 case GL_REPLACE:
5141 case GL_INCR:
5142 case GL_DECR:
5143 case GL_INVERT:
5144 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005145 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005146 break;
5147 default:
5148 return error(GL_INVALID_ENUM);
5149 }
5150
5151 switch (zpass)
5152 {
5153 case GL_ZERO:
5154 case GL_KEEP:
5155 case GL_REPLACE:
5156 case GL_INCR:
5157 case GL_DECR:
5158 case GL_INVERT:
5159 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005160 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005161 break;
5162 default:
5163 return error(GL_INVALID_ENUM);
5164 }
5165
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005166 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005167
5168 if (context)
5169 {
5170 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5171 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005172 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005173 }
5174
5175 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5176 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005177 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005178 }
5179 }
5180 }
5181 catch(std::bad_alloc&)
5182 {
5183 return error(GL_OUT_OF_MEMORY);
5184 }
5185}
5186
daniel@transgaming.comfe208882010-09-01 15:47:57 +00005187GLboolean __stdcall glTestFenceNV(GLuint fence)
5188{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005189 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005190
5191 try
5192 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005193 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005194
5195 if (context)
5196 {
5197 gl::Fence *fenceObject = context->getFence(fence);
5198
5199 if (fenceObject == NULL)
5200 {
5201 return error(GL_INVALID_OPERATION, GL_TRUE);
5202 }
5203
5204 return fenceObject->testFence();
5205 }
5206 }
5207 catch(std::bad_alloc&)
5208 {
5209 error(GL_OUT_OF_MEMORY);
5210 }
5211
5212 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00005213}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005214
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005215void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
5216 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005217{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005218 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 +00005219 "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 +00005220 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005221
5222 try
5223 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00005224 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005225 {
5226 return error(GL_INVALID_VALUE);
5227 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005228
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +00005229 if (internalformat != GLint(format))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005230 {
5231 return error(GL_INVALID_OPERATION);
5232 }
5233
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005234 // validate <type> by itself (used as secondary key below)
5235 switch (type)
5236 {
5237 case GL_UNSIGNED_BYTE:
5238 case GL_UNSIGNED_SHORT_5_6_5:
5239 case GL_UNSIGNED_SHORT_4_4_4_4:
5240 case GL_UNSIGNED_SHORT_5_5_5_1:
5241 case GL_UNSIGNED_SHORT:
5242 case GL_UNSIGNED_INT:
5243 case GL_UNSIGNED_INT_24_8_OES:
5244 case GL_HALF_FLOAT_OES:
5245 case GL_FLOAT:
5246 break;
5247 default:
5248 return error(GL_INVALID_ENUM);
5249 }
5250
5251 // validate <format> + <type> combinations
5252 // - invalid <format> -> sets INVALID_ENUM
5253 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005254 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005255 {
5256 case GL_ALPHA:
5257 case GL_LUMINANCE:
5258 case GL_LUMINANCE_ALPHA:
5259 switch (type)
5260 {
5261 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005262 case GL_FLOAT:
5263 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005264 break;
5265 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005266 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005267 }
5268 break;
5269 case GL_RGB:
5270 switch (type)
5271 {
5272 case GL_UNSIGNED_BYTE:
5273 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005274 case GL_FLOAT:
5275 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005276 break;
5277 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005278 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005279 }
5280 break;
5281 case GL_RGBA:
5282 switch (type)
5283 {
5284 case GL_UNSIGNED_BYTE:
5285 case GL_UNSIGNED_SHORT_4_4_4_4:
5286 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005287 case GL_FLOAT:
5288 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005289 break;
5290 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005291 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005292 }
5293 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005294 case GL_BGRA_EXT:
5295 switch (type)
5296 {
5297 case GL_UNSIGNED_BYTE:
5298 break;
5299 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005300 return error(GL_INVALID_OPERATION);
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005301 }
5302 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005303 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
5304 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00005305 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5306 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00005307 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005308 case GL_DEPTH_COMPONENT:
5309 switch (type)
5310 {
5311 case GL_UNSIGNED_SHORT:
5312 case GL_UNSIGNED_INT:
5313 break;
5314 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005315 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005316 }
5317 break;
5318 case GL_DEPTH_STENCIL_OES:
5319 switch (type)
5320 {
5321 case GL_UNSIGNED_INT_24_8_OES:
5322 break;
5323 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005324 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005325 }
5326 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005327 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005328 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005329 }
5330
5331 if (border != 0)
5332 {
5333 return error(GL_INVALID_VALUE);
5334 }
5335
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005336 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005337
5338 if (context)
5339 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00005340 if (level > context->getMaximumTextureLevel())
5341 {
5342 return error(GL_INVALID_VALUE);
5343 }
5344
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005345 switch (target)
5346 {
5347 case GL_TEXTURE_2D:
5348 if (width > (context->getMaximumTextureDimension() >> level) ||
5349 height > (context->getMaximumTextureDimension() >> level))
5350 {
5351 return error(GL_INVALID_VALUE);
5352 }
5353 break;
5354 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5355 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5356 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5357 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5358 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5359 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5360 if (width != height)
5361 {
5362 return error(GL_INVALID_VALUE);
5363 }
5364
5365 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
5366 height > (context->getMaximumCubeTextureDimension() >> level))
5367 {
5368 return error(GL_INVALID_VALUE);
5369 }
5370 break;
5371 default:
5372 return error(GL_INVALID_ENUM);
5373 }
5374
gman@chromium.org50c526d2011-08-10 05:19:44 +00005375 switch (format) {
5376 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5377 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5378 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00005379 {
5380 return error(GL_INVALID_OPERATION);
5381 }
5382 else
5383 {
5384 return error(GL_INVALID_ENUM);
5385 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00005386 break;
5387 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5388 if (context->supportsDXT3Textures())
5389 {
5390 return error(GL_INVALID_OPERATION);
5391 }
5392 else
5393 {
5394 return error(GL_INVALID_ENUM);
5395 }
5396 break;
5397 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5398 if (context->supportsDXT5Textures())
5399 {
5400 return error(GL_INVALID_OPERATION);
5401 }
5402 else
5403 {
5404 return error(GL_INVALID_ENUM);
5405 }
5406 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005407 case GL_DEPTH_COMPONENT:
5408 case GL_DEPTH_STENCIL_OES:
5409 if (!context->supportsDepthTextures())
5410 {
5411 return error(GL_INVALID_VALUE);
5412 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005413 if (target != GL_TEXTURE_2D)
5414 {
5415 return error(GL_INVALID_OPERATION);
5416 }
daniel@transgaming.com797924b2012-06-05 19:50:01 +00005417 // OES_depth_texture supports loading depth data and multiple levels,
5418 // but ANGLE_depth_texture does not
5419 if (pixels != NULL || level != 0)
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005420 {
5421 return error(GL_INVALID_OPERATION);
5422 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005423 break;
gman@chromium.org50c526d2011-08-10 05:19:44 +00005424 default:
5425 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005426 }
5427
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005428 if (type == GL_FLOAT)
5429 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005430 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005431 {
5432 return error(GL_INVALID_ENUM);
5433 }
5434 }
5435 else if (type == GL_HALF_FLOAT_OES)
5436 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005437 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005438 {
5439 return error(GL_INVALID_ENUM);
5440 }
5441 }
5442
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005443 if (target == GL_TEXTURE_2D)
5444 {
5445 gl::Texture2D *texture = context->getTexture2D();
5446
5447 if (!texture)
5448 {
5449 return error(GL_INVALID_OPERATION);
5450 }
5451
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005452 if (texture->isImmutable())
5453 {
5454 return error(GL_INVALID_OPERATION);
5455 }
5456
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005457 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005458 }
5459 else
5460 {
5461 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5462
5463 if (!texture)
5464 {
5465 return error(GL_INVALID_OPERATION);
5466 }
5467
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005468 if (texture->isImmutable())
5469 {
5470 return error(GL_INVALID_OPERATION);
5471 }
5472
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005473 switch (target)
5474 {
5475 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005476 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005477 break;
5478 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005479 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005480 break;
5481 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005482 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005483 break;
5484 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005485 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005486 break;
5487 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005488 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005489 break;
5490 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005491 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005492 break;
5493 default: UNREACHABLE();
5494 }
5495 }
5496 }
5497 }
5498 catch(std::bad_alloc&)
5499 {
5500 return error(GL_OUT_OF_MEMORY);
5501 }
5502}
5503
5504void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5505{
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00005506 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param);
5507
5508 try
5509 {
5510 gl::Context *context = gl::getNonLostContext();
5511
5512 if (context)
5513 {
5514 gl::Texture *texture;
5515
5516 switch (target)
5517 {
5518 case GL_TEXTURE_2D:
5519 texture = context->getTexture2D();
5520 break;
5521 case GL_TEXTURE_CUBE_MAP:
5522 texture = context->getTextureCubeMap();
5523 break;
5524 default:
5525 return error(GL_INVALID_ENUM);
5526 }
5527
5528 switch (pname)
5529 {
5530 case GL_TEXTURE_WRAP_S:
5531 if (!texture->setWrapS((GLenum)param))
5532 {
5533 return error(GL_INVALID_ENUM);
5534 }
5535 break;
5536 case GL_TEXTURE_WRAP_T:
5537 if (!texture->setWrapT((GLenum)param))
5538 {
5539 return error(GL_INVALID_ENUM);
5540 }
5541 break;
5542 case GL_TEXTURE_MIN_FILTER:
5543 if (!texture->setMinFilter((GLenum)param))
5544 {
5545 return error(GL_INVALID_ENUM);
5546 }
5547 break;
5548 case GL_TEXTURE_MAG_FILTER:
5549 if (!texture->setMagFilter((GLenum)param))
5550 {
5551 return error(GL_INVALID_ENUM);
5552 }
5553 break;
5554 case GL_TEXTURE_USAGE_ANGLE:
5555 if (!texture->setUsage((GLenum)param))
5556 {
5557 return error(GL_INVALID_ENUM);
5558 }
5559 break;
5560 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5561 if (!context->supportsTextureFilterAnisotropy())
5562 {
5563 return error(GL_INVALID_ENUM);
5564 }
5565 if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()))
5566 {
5567 return error(GL_INVALID_VALUE);
5568 }
5569 break;
5570 default:
5571 return error(GL_INVALID_ENUM);
5572 }
5573 }
5574 }
5575 catch(std::bad_alloc&)
5576 {
5577 return error(GL_OUT_OF_MEMORY);
5578 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005579}
5580
5581void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5582{
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00005583 glTexParameterf(target, pname, (GLfloat)*params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005584}
5585
5586void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
5587{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005588 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005589
5590 try
5591 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005592 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005593
5594 if (context)
5595 {
5596 gl::Texture *texture;
5597
5598 switch (target)
5599 {
5600 case GL_TEXTURE_2D:
5601 texture = context->getTexture2D();
5602 break;
5603 case GL_TEXTURE_CUBE_MAP:
5604 texture = context->getTextureCubeMap();
5605 break;
5606 default:
5607 return error(GL_INVALID_ENUM);
5608 }
5609
5610 switch (pname)
5611 {
5612 case GL_TEXTURE_WRAP_S:
5613 if (!texture->setWrapS((GLenum)param))
5614 {
5615 return error(GL_INVALID_ENUM);
5616 }
5617 break;
5618 case GL_TEXTURE_WRAP_T:
5619 if (!texture->setWrapT((GLenum)param))
5620 {
5621 return error(GL_INVALID_ENUM);
5622 }
5623 break;
5624 case GL_TEXTURE_MIN_FILTER:
5625 if (!texture->setMinFilter((GLenum)param))
5626 {
5627 return error(GL_INVALID_ENUM);
5628 }
5629 break;
5630 case GL_TEXTURE_MAG_FILTER:
5631 if (!texture->setMagFilter((GLenum)param))
5632 {
5633 return error(GL_INVALID_ENUM);
5634 }
5635 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00005636 case GL_TEXTURE_USAGE_ANGLE:
5637 if (!texture->setUsage((GLenum)param))
5638 {
5639 return error(GL_INVALID_ENUM);
5640 }
5641 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00005642 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5643 if (!context->supportsTextureFilterAnisotropy())
5644 {
5645 return error(GL_INVALID_ENUM);
5646 }
5647 if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()))
5648 {
5649 return error(GL_INVALID_VALUE);
5650 }
5651 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005652 default:
5653 return error(GL_INVALID_ENUM);
5654 }
5655 }
5656 }
5657 catch(std::bad_alloc&)
5658 {
5659 return error(GL_OUT_OF_MEMORY);
5660 }
5661}
5662
5663void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5664{
5665 glTexParameteri(target, pname, *params);
5666}
5667
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005668void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5669{
5670 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5671 target, levels, internalformat, width, height);
5672
5673 try
5674 {
5675 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5676 {
5677 return error(GL_INVALID_ENUM);
5678 }
5679
5680 if (width < 1 || height < 1 || levels < 1)
5681 {
5682 return error(GL_INVALID_VALUE);
5683 }
5684
5685 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5686 {
5687 return error(GL_INVALID_VALUE);
5688 }
5689
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005690 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005691 {
5692 return error(GL_INVALID_OPERATION);
5693 }
5694
5695 GLenum format = gl::ExtractFormat(internalformat);
5696 GLenum type = gl::ExtractType(internalformat);
5697
5698 if (format == GL_NONE || type == GL_NONE)
5699 {
5700 return error(GL_INVALID_ENUM);
5701 }
5702
5703 gl::Context *context = gl::getNonLostContext();
5704
5705 if (context)
5706 {
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005707 switch (target)
5708 {
5709 case GL_TEXTURE_2D:
5710 if (width > context->getMaximumTextureDimension() ||
5711 height > context->getMaximumTextureDimension())
5712 {
5713 return error(GL_INVALID_VALUE);
5714 }
5715 break;
5716 case GL_TEXTURE_CUBE_MAP:
5717 if (width > context->getMaximumCubeTextureDimension() ||
5718 height > context->getMaximumCubeTextureDimension())
5719 {
5720 return error(GL_INVALID_VALUE);
5721 }
5722 break;
5723 default:
5724 return error(GL_INVALID_ENUM);
5725 }
5726
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005727 if (levels != 1 && !context->supportsNonPower2Texture())
5728 {
5729 if (!gl::isPow2(width) || !gl::isPow2(height))
5730 {
5731 return error(GL_INVALID_OPERATION);
5732 }
5733 }
5734
daniel@transgaming.come1077362011-11-11 04:16:50 +00005735 switch (internalformat)
5736 {
5737 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5738 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5739 if (!context->supportsDXT1Textures())
5740 {
5741 return error(GL_INVALID_ENUM);
5742 }
5743 break;
5744 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5745 if (!context->supportsDXT3Textures())
5746 {
5747 return error(GL_INVALID_ENUM);
5748 }
5749 break;
5750 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5751 if (!context->supportsDXT5Textures())
5752 {
5753 return error(GL_INVALID_ENUM);
5754 }
5755 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005756 case GL_RGBA32F_EXT:
5757 case GL_RGB32F_EXT:
5758 case GL_ALPHA32F_EXT:
5759 case GL_LUMINANCE32F_EXT:
5760 case GL_LUMINANCE_ALPHA32F_EXT:
5761 if (!context->supportsFloat32Textures())
5762 {
5763 return error(GL_INVALID_ENUM);
5764 }
5765 break;
5766 case GL_RGBA16F_EXT:
5767 case GL_RGB16F_EXT:
5768 case GL_ALPHA16F_EXT:
5769 case GL_LUMINANCE16F_EXT:
5770 case GL_LUMINANCE_ALPHA16F_EXT:
5771 if (!context->supportsFloat16Textures())
5772 {
5773 return error(GL_INVALID_ENUM);
5774 }
5775 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005776 case GL_DEPTH_COMPONENT16:
5777 case GL_DEPTH_COMPONENT32_OES:
5778 case GL_DEPTH24_STENCIL8_OES:
5779 if (!context->supportsDepthTextures())
5780 {
5781 return error(GL_INVALID_ENUM);
5782 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005783 if (target != GL_TEXTURE_2D)
5784 {
5785 return error(GL_INVALID_OPERATION);
5786 }
daniel@transgaming.com797924b2012-06-05 19:50:01 +00005787 // ANGLE_depth_texture only supports 1-level textures
5788 if (levels != 1)
5789 {
5790 return error(GL_INVALID_OPERATION);
5791 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005792 break;
5793 default:
5794 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005795 }
5796
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005797 if (target == GL_TEXTURE_2D)
5798 {
5799 gl::Texture2D *texture = context->getTexture2D();
5800
5801 if (!texture || texture->id() == 0)
5802 {
5803 return error(GL_INVALID_OPERATION);
5804 }
5805
5806 if (texture->isImmutable())
5807 {
5808 return error(GL_INVALID_OPERATION);
5809 }
5810
5811 texture->storage(levels, internalformat, width, height);
5812 }
5813 else if (target == GL_TEXTURE_CUBE_MAP)
5814 {
5815 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5816
5817 if (!texture || texture->id() == 0)
5818 {
5819 return error(GL_INVALID_OPERATION);
5820 }
5821
5822 if (texture->isImmutable())
5823 {
5824 return error(GL_INVALID_OPERATION);
5825 }
5826
5827 texture->storage(levels, internalformat, width);
5828 }
5829 else UNREACHABLE();
5830 }
5831 }
5832 catch(std::bad_alloc&)
5833 {
5834 return error(GL_OUT_OF_MEMORY);
5835 }
5836}
5837
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005838void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5839 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005840{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005841 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005842 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005843 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005844 target, level, xoffset, yoffset, width, height, format, type, pixels);
5845
5846 try
5847 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00005848 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005849 {
5850 return error(GL_INVALID_ENUM);
5851 }
5852
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005853 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005854 {
5855 return error(GL_INVALID_VALUE);
5856 }
5857
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005858 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5859 {
5860 return error(GL_INVALID_VALUE);
5861 }
5862
daniel@transgaming.com8833dd22012-06-05 19:49:58 +00005863 if (!checkTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005864 {
daniel@transgaming.com8833dd22012-06-05 19:49:58 +00005865 return; // error is set by helper function
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005866 }
5867
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005868 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005869
5870 if (context)
5871 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005872 if (level > context->getMaximumTextureLevel())
5873 {
5874 return error(GL_INVALID_VALUE);
5875 }
5876
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005877 if (format == GL_FLOAT)
5878 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005879 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005880 {
5881 return error(GL_INVALID_ENUM);
5882 }
5883 }
5884 else if (format == GL_HALF_FLOAT_OES)
5885 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005886 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005887 {
5888 return error(GL_INVALID_ENUM);
5889 }
5890 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005891 else if (gl::IsDepthTexture(format))
5892 {
5893 if (!context->supportsDepthTextures())
5894 {
5895 return error(GL_INVALID_ENUM);
5896 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005897 if (target != GL_TEXTURE_2D)
5898 {
5899 return error(GL_INVALID_OPERATION);
5900 }
5901 // OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not
5902 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005903 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005904
daniel@transgaming.com1d2d3c42012-05-31 01:14:15 +00005905 if (width == 0 || height == 0 || pixels == NULL)
5906 {
5907 return;
5908 }
5909
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005910 if (target == GL_TEXTURE_2D)
5911 {
5912 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00005913 if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005914 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005915 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005916 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005917 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005918 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005919 {
5920 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00005921 if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005922 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005923 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005924 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005925 }
5926 else
5927 {
5928 UNREACHABLE();
5929 }
5930 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005931 }
5932 catch(std::bad_alloc&)
5933 {
5934 return error(GL_OUT_OF_MEMORY);
5935 }
5936}
5937
5938void __stdcall glUniform1f(GLint location, GLfloat x)
5939{
5940 glUniform1fv(location, 1, &x);
5941}
5942
5943void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5944{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005945 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005946
5947 try
5948 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005949 if (count < 0)
5950 {
5951 return error(GL_INVALID_VALUE);
5952 }
5953
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005954 if (location == -1)
5955 {
5956 return;
5957 }
5958
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005959 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005960
5961 if (context)
5962 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00005963 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00005964 if (!programBinary)
5965 {
5966 return error(GL_INVALID_OPERATION);
5967 }
5968
5969 if (!programBinary->setUniform1fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005970 {
5971 return error(GL_INVALID_OPERATION);
5972 }
5973 }
5974 }
5975 catch(std::bad_alloc&)
5976 {
5977 return error(GL_OUT_OF_MEMORY);
5978 }
5979}
5980
5981void __stdcall glUniform1i(GLint location, GLint x)
5982{
5983 glUniform1iv(location, 1, &x);
5984}
5985
5986void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5987{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005988 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005989
5990 try
5991 {
5992 if (count < 0)
5993 {
5994 return error(GL_INVALID_VALUE);
5995 }
5996
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005997 if (location == -1)
5998 {
5999 return;
6000 }
6001
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006002 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006003
6004 if (context)
6005 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006006 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006007 if (!programBinary)
6008 {
6009 return error(GL_INVALID_OPERATION);
6010 }
6011
6012 if (!programBinary->setUniform1iv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006013 {
6014 return error(GL_INVALID_OPERATION);
6015 }
6016 }
6017 }
6018 catch(std::bad_alloc&)
6019 {
6020 return error(GL_OUT_OF_MEMORY);
6021 }
6022}
6023
6024void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
6025{
6026 GLfloat xy[2] = {x, y};
6027
6028 glUniform2fv(location, 1, (GLfloat*)&xy);
6029}
6030
6031void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
6032{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006033 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006034
6035 try
6036 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006037 if (count < 0)
6038 {
6039 return error(GL_INVALID_VALUE);
6040 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006041
6042 if (location == -1)
6043 {
6044 return;
6045 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006046
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006047 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006048
6049 if (context)
6050 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006051 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006052 if (!programBinary)
6053 {
6054 return error(GL_INVALID_OPERATION);
6055 }
6056
6057 if (!programBinary->setUniform2fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006058 {
6059 return error(GL_INVALID_OPERATION);
6060 }
6061 }
6062 }
6063 catch(std::bad_alloc&)
6064 {
6065 return error(GL_OUT_OF_MEMORY);
6066 }
6067}
6068
6069void __stdcall glUniform2i(GLint location, GLint x, GLint y)
6070{
6071 GLint xy[4] = {x, y};
6072
6073 glUniform2iv(location, 1, (GLint*)&xy);
6074}
6075
6076void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
6077{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006078 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006079
6080 try
6081 {
6082 if (count < 0)
6083 {
6084 return error(GL_INVALID_VALUE);
6085 }
6086
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006087 if (location == -1)
6088 {
6089 return;
6090 }
6091
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006092 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006093
6094 if (context)
6095 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006096 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006097 if (!programBinary)
6098 {
6099 return error(GL_INVALID_OPERATION);
6100 }
6101
6102 if (!programBinary->setUniform2iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006103 {
6104 return error(GL_INVALID_OPERATION);
6105 }
6106 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006107 }
6108 catch(std::bad_alloc&)
6109 {
6110 return error(GL_OUT_OF_MEMORY);
6111 }
6112}
6113
6114void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
6115{
6116 GLfloat xyz[3] = {x, y, z};
6117
6118 glUniform3fv(location, 1, (GLfloat*)&xyz);
6119}
6120
6121void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
6122{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006123 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006124
6125 try
6126 {
6127 if (count < 0)
6128 {
6129 return error(GL_INVALID_VALUE);
6130 }
6131
6132 if (location == -1)
6133 {
6134 return;
6135 }
6136
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006137 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006138
6139 if (context)
6140 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006141 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006142 if (!programBinary)
6143 {
6144 return error(GL_INVALID_OPERATION);
6145 }
6146
6147 if (!programBinary->setUniform3fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006148 {
6149 return error(GL_INVALID_OPERATION);
6150 }
6151 }
6152 }
6153 catch(std::bad_alloc&)
6154 {
6155 return error(GL_OUT_OF_MEMORY);
6156 }
6157}
6158
6159void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
6160{
6161 GLint xyz[3] = {x, y, z};
6162
6163 glUniform3iv(location, 1, (GLint*)&xyz);
6164}
6165
6166void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
6167{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006168 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006169
6170 try
6171 {
6172 if (count < 0)
6173 {
6174 return error(GL_INVALID_VALUE);
6175 }
6176
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006177 if (location == -1)
6178 {
6179 return;
6180 }
6181
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006182 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006183
6184 if (context)
6185 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006186 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006187 if (!programBinary)
6188 {
6189 return error(GL_INVALID_OPERATION);
6190 }
6191
6192 if (!programBinary->setUniform3iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006193 {
6194 return error(GL_INVALID_OPERATION);
6195 }
6196 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006197 }
6198 catch(std::bad_alloc&)
6199 {
6200 return error(GL_OUT_OF_MEMORY);
6201 }
6202}
6203
6204void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6205{
6206 GLfloat xyzw[4] = {x, y, z, w};
6207
6208 glUniform4fv(location, 1, (GLfloat*)&xyzw);
6209}
6210
6211void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
6212{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006213 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006214
6215 try
6216 {
6217 if (count < 0)
6218 {
6219 return error(GL_INVALID_VALUE);
6220 }
6221
6222 if (location == -1)
6223 {
6224 return;
6225 }
6226
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006227 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006228
6229 if (context)
6230 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006231 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006232 if (!programBinary)
6233 {
6234 return error(GL_INVALID_OPERATION);
6235 }
6236
6237 if (!programBinary->setUniform4fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006238 {
6239 return error(GL_INVALID_OPERATION);
6240 }
6241 }
6242 }
6243 catch(std::bad_alloc&)
6244 {
6245 return error(GL_OUT_OF_MEMORY);
6246 }
6247}
6248
6249void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
6250{
6251 GLint xyzw[4] = {x, y, z, w};
6252
6253 glUniform4iv(location, 1, (GLint*)&xyzw);
6254}
6255
6256void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
6257{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006258 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006259
6260 try
6261 {
6262 if (count < 0)
6263 {
6264 return error(GL_INVALID_VALUE);
6265 }
6266
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006267 if (location == -1)
6268 {
6269 return;
6270 }
6271
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006272 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006273
6274 if (context)
6275 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006276 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006277 if (!programBinary)
6278 {
6279 return error(GL_INVALID_OPERATION);
6280 }
6281
6282 if (!programBinary->setUniform4iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006283 {
6284 return error(GL_INVALID_OPERATION);
6285 }
6286 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006287 }
6288 catch(std::bad_alloc&)
6289 {
6290 return error(GL_OUT_OF_MEMORY);
6291 }
6292}
6293
6294void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6295{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006296 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006297 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006298
6299 try
6300 {
6301 if (count < 0 || transpose != GL_FALSE)
6302 {
6303 return error(GL_INVALID_VALUE);
6304 }
6305
6306 if (location == -1)
6307 {
6308 return;
6309 }
6310
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006311 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006312
6313 if (context)
6314 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006315 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006316 if (!programBinary)
6317 {
6318 return error(GL_INVALID_OPERATION);
6319 }
6320
6321 if (!programBinary->setUniformMatrix2fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006322 {
6323 return error(GL_INVALID_OPERATION);
6324 }
6325 }
6326 }
6327 catch(std::bad_alloc&)
6328 {
6329 return error(GL_OUT_OF_MEMORY);
6330 }
6331}
6332
6333void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6334{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006335 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006336 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006337
6338 try
6339 {
6340 if (count < 0 || transpose != GL_FALSE)
6341 {
6342 return error(GL_INVALID_VALUE);
6343 }
6344
6345 if (location == -1)
6346 {
6347 return;
6348 }
6349
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006350 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006351
6352 if (context)
6353 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006354 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006355 if (!programBinary)
6356 {
6357 return error(GL_INVALID_OPERATION);
6358 }
6359
6360 if (!programBinary->setUniformMatrix3fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006361 {
6362 return error(GL_INVALID_OPERATION);
6363 }
6364 }
6365 }
6366 catch(std::bad_alloc&)
6367 {
6368 return error(GL_OUT_OF_MEMORY);
6369 }
6370}
6371
6372void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6373{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006374 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006375 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006376
6377 try
6378 {
6379 if (count < 0 || transpose != GL_FALSE)
6380 {
6381 return error(GL_INVALID_VALUE);
6382 }
6383
6384 if (location == -1)
6385 {
6386 return;
6387 }
6388
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006389 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006390
6391 if (context)
6392 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006393 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006394 if (!programBinary)
6395 {
6396 return error(GL_INVALID_OPERATION);
6397 }
6398
6399 if (!programBinary->setUniformMatrix4fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006400 {
6401 return error(GL_INVALID_OPERATION);
6402 }
6403 }
6404 }
6405 catch(std::bad_alloc&)
6406 {
6407 return error(GL_OUT_OF_MEMORY);
6408 }
6409}
6410
6411void __stdcall glUseProgram(GLuint program)
6412{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006413 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006414
6415 try
6416 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006417 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006418
6419 if (context)
6420 {
6421 gl::Program *programObject = context->getProgram(program);
6422
daniel@transgaming.comc8478202010-04-13 19:53:35 +00006423 if (!programObject && program != 0)
6424 {
6425 if (context->getShader(program))
6426 {
6427 return error(GL_INVALID_OPERATION);
6428 }
6429 else
6430 {
6431 return error(GL_INVALID_VALUE);
6432 }
6433 }
6434
daniel@transgaming.com716056c2012-07-24 18:38:59 +00006435 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006436 {
6437 return error(GL_INVALID_OPERATION);
6438 }
6439
6440 context->useProgram(program);
6441 }
6442 }
6443 catch(std::bad_alloc&)
6444 {
6445 return error(GL_OUT_OF_MEMORY);
6446 }
6447}
6448
6449void __stdcall glValidateProgram(GLuint program)
6450{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006451 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006452
6453 try
6454 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006455 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006456
6457 if (context)
6458 {
6459 gl::Program *programObject = context->getProgram(program);
6460
6461 if (!programObject)
6462 {
6463 if (context->getShader(program))
6464 {
6465 return error(GL_INVALID_OPERATION);
6466 }
6467 else
6468 {
6469 return error(GL_INVALID_VALUE);
6470 }
6471 }
6472
apatrick@chromium.org253b8d22012-06-22 19:27:21 +00006473 programObject->validate();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006474 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006475 }
6476 catch(std::bad_alloc&)
6477 {
6478 return error(GL_OUT_OF_MEMORY);
6479 }
6480}
6481
6482void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
6483{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006484 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006485
6486 try
6487 {
6488 if (index >= gl::MAX_VERTEX_ATTRIBS)
6489 {
6490 return error(GL_INVALID_VALUE);
6491 }
6492
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006493 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006494
6495 if (context)
6496 {
6497 GLfloat vals[4] = { x, 0, 0, 1 };
6498 context->setVertexAttrib(index, vals);
6499 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006500 }
6501 catch(std::bad_alloc&)
6502 {
6503 return error(GL_OUT_OF_MEMORY);
6504 }
6505}
6506
6507void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
6508{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006509 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006510
6511 try
6512 {
6513 if (index >= gl::MAX_VERTEX_ATTRIBS)
6514 {
6515 return error(GL_INVALID_VALUE);
6516 }
6517
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006518 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006519
6520 if (context)
6521 {
6522 GLfloat vals[4] = { values[0], 0, 0, 1 };
6523 context->setVertexAttrib(index, vals);
6524 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006525 }
6526 catch(std::bad_alloc&)
6527 {
6528 return error(GL_OUT_OF_MEMORY);
6529 }
6530}
6531
6532void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6533{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006534 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006535
6536 try
6537 {
6538 if (index >= gl::MAX_VERTEX_ATTRIBS)
6539 {
6540 return error(GL_INVALID_VALUE);
6541 }
6542
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006543 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006544
6545 if (context)
6546 {
6547 GLfloat vals[4] = { x, y, 0, 1 };
6548 context->setVertexAttrib(index, vals);
6549 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006550 }
6551 catch(std::bad_alloc&)
6552 {
6553 return error(GL_OUT_OF_MEMORY);
6554 }
6555}
6556
6557void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
6558{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006559 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006560
6561 try
6562 {
6563 if (index >= gl::MAX_VERTEX_ATTRIBS)
6564 {
6565 return error(GL_INVALID_VALUE);
6566 }
6567
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006568 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006569
6570 if (context)
6571 {
6572 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6573 context->setVertexAttrib(index, vals);
6574 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006575 }
6576 catch(std::bad_alloc&)
6577 {
6578 return error(GL_OUT_OF_MEMORY);
6579 }
6580}
6581
6582void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6583{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006584 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 +00006585
6586 try
6587 {
6588 if (index >= gl::MAX_VERTEX_ATTRIBS)
6589 {
6590 return error(GL_INVALID_VALUE);
6591 }
6592
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006593 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006594
6595 if (context)
6596 {
6597 GLfloat vals[4] = { x, y, z, 1 };
6598 context->setVertexAttrib(index, vals);
6599 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006600 }
6601 catch(std::bad_alloc&)
6602 {
6603 return error(GL_OUT_OF_MEMORY);
6604 }
6605}
6606
6607void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
6608{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006609 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006610
6611 try
6612 {
6613 if (index >= gl::MAX_VERTEX_ATTRIBS)
6614 {
6615 return error(GL_INVALID_VALUE);
6616 }
6617
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006618 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006619
6620 if (context)
6621 {
6622 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6623 context->setVertexAttrib(index, vals);
6624 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006625 }
6626 catch(std::bad_alloc&)
6627 {
6628 return error(GL_OUT_OF_MEMORY);
6629 }
6630}
6631
6632void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6633{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006634 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 +00006635
6636 try
6637 {
6638 if (index >= gl::MAX_VERTEX_ATTRIBS)
6639 {
6640 return error(GL_INVALID_VALUE);
6641 }
6642
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006643 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006644
6645 if (context)
6646 {
6647 GLfloat vals[4] = { x, y, z, w };
6648 context->setVertexAttrib(index, vals);
6649 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006650 }
6651 catch(std::bad_alloc&)
6652 {
6653 return error(GL_OUT_OF_MEMORY);
6654 }
6655}
6656
6657void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
6658{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006659 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006660
6661 try
6662 {
6663 if (index >= gl::MAX_VERTEX_ATTRIBS)
6664 {
6665 return error(GL_INVALID_VALUE);
6666 }
6667
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006668 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006669
6670 if (context)
6671 {
6672 context->setVertexAttrib(index, values);
6673 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006674 }
6675 catch(std::bad_alloc&)
6676 {
6677 return error(GL_OUT_OF_MEMORY);
6678 }
6679}
6680
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00006681void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
6682{
6683 EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
6684
6685 try
6686 {
6687 if (index >= gl::MAX_VERTEX_ATTRIBS)
6688 {
6689 return error(GL_INVALID_VALUE);
6690 }
6691
6692 gl::Context *context = gl::getNonLostContext();
6693
6694 if (context)
6695 {
6696 context->setVertexAttribDivisor(index, divisor);
6697 }
6698 }
6699 catch(std::bad_alloc&)
6700 {
6701 return error(GL_OUT_OF_MEMORY);
6702 }
6703}
6704
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006705void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006706{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006707 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006708 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006709 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006710
6711 try
6712 {
6713 if (index >= gl::MAX_VERTEX_ATTRIBS)
6714 {
6715 return error(GL_INVALID_VALUE);
6716 }
6717
6718 if (size < 1 || size > 4)
6719 {
6720 return error(GL_INVALID_VALUE);
6721 }
6722
6723 switch (type)
6724 {
6725 case GL_BYTE:
6726 case GL_UNSIGNED_BYTE:
6727 case GL_SHORT:
6728 case GL_UNSIGNED_SHORT:
6729 case GL_FIXED:
6730 case GL_FLOAT:
6731 break;
6732 default:
6733 return error(GL_INVALID_ENUM);
6734 }
6735
6736 if (stride < 0)
6737 {
6738 return error(GL_INVALID_VALUE);
6739 }
6740
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006741 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006742
6743 if (context)
6744 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006745 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006746 }
6747 }
6748 catch(std::bad_alloc&)
6749 {
6750 return error(GL_OUT_OF_MEMORY);
6751 }
6752}
6753
6754void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6755{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006756 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 +00006757
6758 try
6759 {
6760 if (width < 0 || height < 0)
6761 {
6762 return error(GL_INVALID_VALUE);
6763 }
6764
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006765 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006766
6767 if (context)
6768 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006769 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006770 }
6771 }
6772 catch(std::bad_alloc&)
6773 {
6774 return error(GL_OUT_OF_MEMORY);
6775 }
6776}
6777
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006778void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6779 GLbitfield mask, GLenum filter)
6780{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006781 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006782 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6783 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6784 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6785
6786 try
6787 {
6788 switch (filter)
6789 {
6790 case GL_NEAREST:
6791 break;
6792 default:
6793 return error(GL_INVALID_ENUM);
6794 }
6795
6796 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6797 {
6798 return error(GL_INVALID_VALUE);
6799 }
6800
6801 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6802 {
6803 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6804 return error(GL_INVALID_OPERATION);
6805 }
6806
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006807 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006808
6809 if (context)
6810 {
6811 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6812 {
6813 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6814 return error(GL_INVALID_OPERATION);
6815 }
6816
6817 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6818 }
6819 }
6820 catch(std::bad_alloc&)
6821 {
6822 return error(GL_OUT_OF_MEMORY);
6823 }
6824}
6825
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006826void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6827 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006828{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006829 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006830 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006831 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006832 target, level, internalformat, width, height, depth, border, format, type, pixels);
6833
6834 try
6835 {
6836 UNIMPLEMENTED(); // FIXME
6837 }
6838 catch(std::bad_alloc&)
6839 {
6840 return error(GL_OUT_OF_MEMORY);
6841 }
6842}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006843
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006844void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length,
6845 GLenum *binaryFormat, void *binary)
6846{
apatrick@chromium.org90080e32012-07-09 22:15:33 +00006847 EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)",
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006848 program, bufSize, length, binaryFormat, binary);
6849
6850 try
6851 {
6852 gl::Context *context = gl::getNonLostContext();
6853
6854 if (context)
6855 {
6856 gl::Program *programObject = context->getProgram(program);
6857
daniel@transgaming.com716056c2012-07-24 18:38:59 +00006858 if (!programObject || !programObject->isLinked())
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006859 {
6860 return error(GL_INVALID_OPERATION);
6861 }
6862
6863 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
6864
6865 if (!programBinary)
6866 {
6867 return error(GL_INVALID_OPERATION);
6868 }
6869
apatrick@chromium.org90080e32012-07-09 22:15:33 +00006870 if (!programBinary->save(binary, bufSize, length))
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006871 {
apatrick@chromium.org90080e32012-07-09 22:15:33 +00006872 return error(GL_INVALID_OPERATION);
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006873 }
apatrick@chromium.org90080e32012-07-09 22:15:33 +00006874
6875 *binaryFormat = GL_PROGRAM_BINARY_ANGLE;
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006876 }
6877 }
6878 catch(std::bad_alloc&)
6879 {
6880 return error(GL_OUT_OF_MEMORY);
6881 }
6882}
6883
6884void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat,
6885 const void *binary, GLint length)
6886{
6887 EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)",
6888 program, binaryFormat, binary, length);
6889
6890 try
6891 {
6892 gl::Context *context = gl::getNonLostContext();
6893
6894 if (context)
6895 {
6896 if (binaryFormat != GL_PROGRAM_BINARY_ANGLE)
6897 {
6898 return error(GL_INVALID_ENUM);
6899 }
6900
6901 gl::Program *programObject = context->getProgram(program);
6902
6903 if (!programObject)
6904 {
6905 return error(GL_INVALID_OPERATION);
6906 }
6907
daniel@transgaming.com95d29422012-07-24 18:36:10 +00006908 context->setProgramBinary(program, binary, length);
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006909 }
6910 }
6911 catch(std::bad_alloc&)
6912 {
6913 return error(GL_OUT_OF_MEMORY);
6914 }
6915}
6916
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006917__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6918{
6919 struct Extension
6920 {
6921 const char *name;
6922 __eglMustCastToProperFunctionPointerType address;
6923 };
6924
6925 static const Extension glExtensions[] =
6926 {
6927 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006928 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006929 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006930 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6931 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6932 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6933 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6934 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6935 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6936 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006937 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006938 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006939 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6940 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6941 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6942 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00006943 {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT},
6944 {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT},
6945 {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT},
6946 {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT},
6947 {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
6948 {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
6949 {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
daniel@transgaming.comdce02fd2012-01-27 15:39:51 +00006950 {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE},
6951 {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE},
6952 {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE},
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006953 {"glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glGetProgramBinaryOES},
6954 {"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES}, };
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006955
6956 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6957 {
6958 if (strcmp(procname, glExtensions[ext].name) == 0)
6959 {
6960 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6961 }
6962 }
6963
6964 return NULL;
6965}
6966
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006967// Non-public functions used by EGL
6968
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006969bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006970{
6971 EVENT("(egl::Surface* surface = 0x%0.8p)",
6972 surface);
6973
6974 try
6975 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006976 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006977
6978 if (context)
6979 {
6980 gl::Texture2D *textureObject = context->getTexture2D();
6981
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006982 if (textureObject->isImmutable())
6983 {
6984 return false;
6985 }
6986
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006987 if (textureObject)
6988 {
6989 textureObject->bindTexImage(surface);
6990 }
6991 }
6992 }
6993 catch(std::bad_alloc&)
6994 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006995 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006996 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006997
6998 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006999}
7000
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00007001}