blob: 3e9a7a28ef00020debdc2a5d352233f81d7be92a [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.com6452adf2012-10-17 18:22:35 +0000151
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000152bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000153 GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type,
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000154 gl::Texture2D *texture)
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000155{
156 if (!texture)
157 {
158 return error(GL_INVALID_OPERATION, false);
159 }
160
daniel@transgaming.com92f49922012-05-09 15:49:19 +0000161 if (compressed != texture->isCompressed(level))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000162 {
163 return error(GL_INVALID_OPERATION, false);
164 }
165
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000166 if (format != GL_NONE)
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000167 {
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000168 GLenum internalformat = gl::ConvertSizedInternalFormat(format, type);
169 if (internalformat != texture->getInternalFormat(level))
170 {
171 return error(GL_INVALID_OPERATION, false);
172 }
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000173 }
174
175 if (compressed)
176 {
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000177 if ((width % 4 != 0 && width != texture->getWidth(0)) ||
178 (height % 4 != 0 && height != texture->getHeight(0)))
179 {
180 return error(GL_INVALID_OPERATION, false);
181 }
182 }
183
184 if (xoffset + width > texture->getWidth(level) ||
185 yoffset + height > texture->getHeight(level))
186 {
187 return error(GL_INVALID_VALUE, false);
188 }
189
190 return true;
191}
192
193bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000194 GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type,
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000195 gl::TextureCubeMap *texture)
196{
197 if (!texture)
198 {
199 return error(GL_INVALID_OPERATION, false);
200 }
201
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000202 if (compressed != texture->isCompressed(target, level))
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000203 {
204 return error(GL_INVALID_OPERATION, false);
205 }
206
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000207 if (format != GL_NONE)
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000208 {
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000209 GLenum internalformat = gl::ConvertSizedInternalFormat(format, type);
210 if (internalformat != texture->getInternalFormat(target, level))
211 {
212 return error(GL_INVALID_OPERATION, false);
213 }
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +0000214 }
215
216 if (compressed)
217 {
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000218 if ((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
219 (height % 4 != 0 && height != texture->getHeight(target, 0)))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000220 {
221 return error(GL_INVALID_OPERATION, false);
222 }
223 }
224
daniel@transgaming.com4df88e82012-05-09 15:49:24 +0000225 if (xoffset + width > texture->getWidth(target, level) ||
226 yoffset + height > texture->getHeight(target, level))
daniel@transgaming.com343373a2011-11-29 19:42:32 +0000227 {
228 return error(GL_INVALID_VALUE, false);
229 }
230
231 return true;
232}
233
daniel@transgaming.comb7915a52011-11-12 03:14:20 +0000234// check for combinations of format and type that are valid for ReadPixels
235bool validReadFormatType(GLenum format, GLenum type)
236{
237 switch (format)
238 {
239 case GL_RGBA:
240 switch (type)
241 {
242 case GL_UNSIGNED_BYTE:
243 break;
244 default:
245 return false;
246 }
247 break;
248 case GL_BGRA_EXT:
249 switch (type)
250 {
251 case GL_UNSIGNED_BYTE:
252 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
253 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
254 break;
255 default:
256 return false;
257 }
258 break;
daniel@transgaming.comb7915a52011-11-12 03:14:20 +0000259 default:
260 return false;
261 }
262 return true;
263}
264
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000265extern "C"
266{
267
268void __stdcall glActiveTexture(GLenum texture)
269{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000270 EVENT("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000271
272 try
273 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000274 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000275
276 if (context)
277 {
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +0000278 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
279 {
280 return error(GL_INVALID_ENUM);
281 }
282
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000283 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000284 }
285 }
286 catch(std::bad_alloc&)
287 {
288 return error(GL_OUT_OF_MEMORY);
289 }
290}
291
292void __stdcall glAttachShader(GLuint program, GLuint shader)
293{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000294 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000295
296 try
297 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000298 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000299
300 if (context)
301 {
302 gl::Program *programObject = context->getProgram(program);
303 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000304
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000305 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000306 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000307 if (context->getShader(program))
308 {
309 return error(GL_INVALID_OPERATION);
310 }
311 else
312 {
313 return error(GL_INVALID_VALUE);
314 }
315 }
316
317 if (!shaderObject)
318 {
319 if (context->getProgram(shader))
320 {
321 return error(GL_INVALID_OPERATION);
322 }
323 else
324 {
325 return error(GL_INVALID_VALUE);
326 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000327 }
328
329 if (!programObject->attachShader(shaderObject))
330 {
331 return error(GL_INVALID_OPERATION);
332 }
333 }
334 }
335 catch(std::bad_alloc&)
336 {
337 return error(GL_OUT_OF_MEMORY);
338 }
339}
340
daniel@transgaming.com86bdb822012-01-20 18:24:39 +0000341void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
342{
343 EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
344
345 try
346 {
347 switch (target)
348 {
349 case GL_ANY_SAMPLES_PASSED_EXT:
350 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
351 break;
352 default:
353 return error(GL_INVALID_ENUM);
354 }
355
356 if (id == 0)
357 {
358 return error(GL_INVALID_OPERATION);
359 }
360
361 gl::Context *context = gl::getNonLostContext();
362
363 if (context)
364 {
365 context->beginQuery(target, id);
366 }
367 }
368 catch(std::bad_alloc&)
369 {
370 return error(GL_OUT_OF_MEMORY);
371 }
372}
373
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000374void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000375{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000376 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000377
378 try
379 {
380 if (index >= gl::MAX_VERTEX_ATTRIBS)
381 {
382 return error(GL_INVALID_VALUE);
383 }
384
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000385 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000386
387 if (context)
388 {
389 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000390
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000391 if (!programObject)
392 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000393 if (context->getShader(program))
394 {
395 return error(GL_INVALID_OPERATION);
396 }
397 else
398 {
399 return error(GL_INVALID_VALUE);
400 }
401 }
402
403 if (strncmp(name, "gl_", 3) == 0)
404 {
405 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000406 }
407
408 programObject->bindAttributeLocation(index, name);
409 }
410 }
411 catch(std::bad_alloc&)
412 {
413 return error(GL_OUT_OF_MEMORY);
414 }
415}
416
417void __stdcall glBindBuffer(GLenum target, GLuint buffer)
418{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000419 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000420
421 try
422 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000423 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000424
425 if (context)
426 {
427 switch (target)
428 {
429 case GL_ARRAY_BUFFER:
430 context->bindArrayBuffer(buffer);
431 return;
432 case GL_ELEMENT_ARRAY_BUFFER:
433 context->bindElementArrayBuffer(buffer);
434 return;
435 default:
436 return error(GL_INVALID_ENUM);
437 }
438 }
439 }
440 catch(std::bad_alloc&)
441 {
442 return error(GL_OUT_OF_MEMORY);
443 }
444}
445
446void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
447{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000448 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000449
450 try
451 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000452 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000453 {
454 return error(GL_INVALID_ENUM);
455 }
456
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000457 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000458
459 if (context)
460 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000461 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
462 {
463 context->bindReadFramebuffer(framebuffer);
464 }
465
466 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
467 {
468 context->bindDrawFramebuffer(framebuffer);
469 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000470 }
471 }
472 catch(std::bad_alloc&)
473 {
474 return error(GL_OUT_OF_MEMORY);
475 }
476}
477
478void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
479{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000480 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000481
482 try
483 {
484 if (target != GL_RENDERBUFFER)
485 {
486 return error(GL_INVALID_ENUM);
487 }
488
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000489 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000490
491 if (context)
492 {
493 context->bindRenderbuffer(renderbuffer);
494 }
495 }
496 catch(std::bad_alloc&)
497 {
498 return error(GL_OUT_OF_MEMORY);
499 }
500}
501
502void __stdcall glBindTexture(GLenum target, GLuint texture)
503{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000504 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000505
506 try
507 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000508 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000509
510 if (context)
511 {
512 gl::Texture *textureObject = context->getTexture(texture);
513
514 if (textureObject && textureObject->getTarget() != target && texture != 0)
515 {
516 return error(GL_INVALID_OPERATION);
517 }
518
519 switch (target)
520 {
521 case GL_TEXTURE_2D:
522 context->bindTexture2D(texture);
523 return;
524 case GL_TEXTURE_CUBE_MAP:
525 context->bindTextureCubeMap(texture);
526 return;
527 default:
528 return error(GL_INVALID_ENUM);
529 }
530 }
531 }
532 catch(std::bad_alloc&)
533 {
534 return error(GL_OUT_OF_MEMORY);
535 }
536}
537
538void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
539{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000540 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000541 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000542
543 try
544 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000545 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000546
547 if (context)
548 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000549 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000550 }
551 }
552 catch(std::bad_alloc&)
553 {
554 return error(GL_OUT_OF_MEMORY);
555 }
556}
557
558void __stdcall glBlendEquation(GLenum mode)
559{
560 glBlendEquationSeparate(mode, mode);
561}
562
563void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
564{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000565 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000566
567 try
568 {
569 switch (modeRGB)
570 {
571 case GL_FUNC_ADD:
572 case GL_FUNC_SUBTRACT:
573 case GL_FUNC_REVERSE_SUBTRACT:
574 break;
575 default:
576 return error(GL_INVALID_ENUM);
577 }
578
579 switch (modeAlpha)
580 {
581 case GL_FUNC_ADD:
582 case GL_FUNC_SUBTRACT:
583 case GL_FUNC_REVERSE_SUBTRACT:
584 break;
585 default:
586 return error(GL_INVALID_ENUM);
587 }
588
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000589 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000590
591 if (context)
592 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000593 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000594 }
595 }
596 catch(std::bad_alloc&)
597 {
598 return error(GL_OUT_OF_MEMORY);
599 }
600}
601
602void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
603{
604 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
605}
606
607void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
608{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000609 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 +0000610 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000611
612 try
613 {
614 switch (srcRGB)
615 {
616 case GL_ZERO:
617 case GL_ONE:
618 case GL_SRC_COLOR:
619 case GL_ONE_MINUS_SRC_COLOR:
620 case GL_DST_COLOR:
621 case GL_ONE_MINUS_DST_COLOR:
622 case GL_SRC_ALPHA:
623 case GL_ONE_MINUS_SRC_ALPHA:
624 case GL_DST_ALPHA:
625 case GL_ONE_MINUS_DST_ALPHA:
626 case GL_CONSTANT_COLOR:
627 case GL_ONE_MINUS_CONSTANT_COLOR:
628 case GL_CONSTANT_ALPHA:
629 case GL_ONE_MINUS_CONSTANT_ALPHA:
630 case GL_SRC_ALPHA_SATURATE:
631 break;
632 default:
633 return error(GL_INVALID_ENUM);
634 }
635
636 switch (dstRGB)
637 {
638 case GL_ZERO:
639 case GL_ONE:
640 case GL_SRC_COLOR:
641 case GL_ONE_MINUS_SRC_COLOR:
642 case GL_DST_COLOR:
643 case GL_ONE_MINUS_DST_COLOR:
644 case GL_SRC_ALPHA:
645 case GL_ONE_MINUS_SRC_ALPHA:
646 case GL_DST_ALPHA:
647 case GL_ONE_MINUS_DST_ALPHA:
648 case GL_CONSTANT_COLOR:
649 case GL_ONE_MINUS_CONSTANT_COLOR:
650 case GL_CONSTANT_ALPHA:
651 case GL_ONE_MINUS_CONSTANT_ALPHA:
652 break;
653 default:
654 return error(GL_INVALID_ENUM);
655 }
656
657 switch (srcAlpha)
658 {
659 case GL_ZERO:
660 case GL_ONE:
661 case GL_SRC_COLOR:
662 case GL_ONE_MINUS_SRC_COLOR:
663 case GL_DST_COLOR:
664 case GL_ONE_MINUS_DST_COLOR:
665 case GL_SRC_ALPHA:
666 case GL_ONE_MINUS_SRC_ALPHA:
667 case GL_DST_ALPHA:
668 case GL_ONE_MINUS_DST_ALPHA:
669 case GL_CONSTANT_COLOR:
670 case GL_ONE_MINUS_CONSTANT_COLOR:
671 case GL_CONSTANT_ALPHA:
672 case GL_ONE_MINUS_CONSTANT_ALPHA:
673 case GL_SRC_ALPHA_SATURATE:
674 break;
675 default:
676 return error(GL_INVALID_ENUM);
677 }
678
679 switch (dstAlpha)
680 {
681 case GL_ZERO:
682 case GL_ONE:
683 case GL_SRC_COLOR:
684 case GL_ONE_MINUS_SRC_COLOR:
685 case GL_DST_COLOR:
686 case GL_ONE_MINUS_DST_COLOR:
687 case GL_SRC_ALPHA:
688 case GL_ONE_MINUS_SRC_ALPHA:
689 case GL_DST_ALPHA:
690 case GL_ONE_MINUS_DST_ALPHA:
691 case GL_CONSTANT_COLOR:
692 case GL_ONE_MINUS_CONSTANT_COLOR:
693 case GL_CONSTANT_ALPHA:
694 case GL_ONE_MINUS_CONSTANT_ALPHA:
695 break;
696 default:
697 return error(GL_INVALID_ENUM);
698 }
699
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000700 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
701 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
702
703 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
704 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
705
706 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000707 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000708 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
709 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000710 }
711
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000712 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000713
714 if (context)
715 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000716 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000717 }
718 }
719 catch(std::bad_alloc&)
720 {
721 return error(GL_OUT_OF_MEMORY);
722 }
723}
724
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000725void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000726{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000727 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 +0000728 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000729
730 try
731 {
732 if (size < 0)
733 {
734 return error(GL_INVALID_VALUE);
735 }
736
737 switch (usage)
738 {
739 case GL_STREAM_DRAW:
740 case GL_STATIC_DRAW:
741 case GL_DYNAMIC_DRAW:
742 break;
743 default:
744 return error(GL_INVALID_ENUM);
745 }
746
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000747 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748
749 if (context)
750 {
751 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000752
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000753 switch (target)
754 {
755 case GL_ARRAY_BUFFER:
756 buffer = context->getArrayBuffer();
757 break;
758 case GL_ELEMENT_ARRAY_BUFFER:
759 buffer = context->getElementArrayBuffer();
760 break;
761 default:
762 return error(GL_INVALID_ENUM);
763 }
764
765 if (!buffer)
766 {
767 return error(GL_INVALID_OPERATION);
768 }
769
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000770 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000771 }
772 }
773 catch(std::bad_alloc&)
774 {
775 return error(GL_OUT_OF_MEMORY);
776 }
777}
778
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000779void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000780{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000781 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 +0000782 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000783
784 try
785 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000786 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000787 {
788 return error(GL_INVALID_VALUE);
789 }
790
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000791 if (data == NULL)
792 {
793 return;
794 }
795
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000796 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000797
798 if (context)
799 {
800 gl::Buffer *buffer;
801
802 switch (target)
803 {
804 case GL_ARRAY_BUFFER:
805 buffer = context->getArrayBuffer();
806 break;
807 case GL_ELEMENT_ARRAY_BUFFER:
808 buffer = context->getElementArrayBuffer();
809 break;
810 default:
811 return error(GL_INVALID_ENUM);
812 }
813
814 if (!buffer)
815 {
816 return error(GL_INVALID_OPERATION);
817 }
818
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000819 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000820 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000821 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000822 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000823
824 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000825 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000826 }
827 catch(std::bad_alloc&)
828 {
829 return error(GL_OUT_OF_MEMORY);
830 }
831}
832
833GLenum __stdcall glCheckFramebufferStatus(GLenum target)
834{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000835 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000836
837 try
838 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000839 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000840 {
841 return error(GL_INVALID_ENUM, 0);
842 }
843
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000844 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000845
846 if (context)
847 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000848 gl::Framebuffer *framebuffer = NULL;
849 if (target == GL_READ_FRAMEBUFFER_ANGLE)
850 {
851 framebuffer = context->getReadFramebuffer();
852 }
853 else
854 {
855 framebuffer = context->getDrawFramebuffer();
856 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000857
858 return framebuffer->completeness();
859 }
860 }
861 catch(std::bad_alloc&)
862 {
863 return error(GL_OUT_OF_MEMORY, 0);
864 }
865
866 return 0;
867}
868
869void __stdcall glClear(GLbitfield mask)
870{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000871 EVENT("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000872
873 try
874 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000875 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000876
877 if (context)
878 {
879 context->clear(mask);
880 }
881 }
882 catch(std::bad_alloc&)
883 {
884 return error(GL_OUT_OF_MEMORY);
885 }
886}
887
888void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
889{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000890 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000891 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000892
893 try
894 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000895 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000896
897 if (context)
898 {
899 context->setClearColor(red, green, blue, alpha);
900 }
901 }
902 catch(std::bad_alloc&)
903 {
904 return error(GL_OUT_OF_MEMORY);
905 }
906}
907
908void __stdcall glClearDepthf(GLclampf depth)
909{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000910 EVENT("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000911
912 try
913 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000914 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000915
916 if (context)
917 {
918 context->setClearDepth(depth);
919 }
920 }
921 catch(std::bad_alloc&)
922 {
923 return error(GL_OUT_OF_MEMORY);
924 }
925}
926
927void __stdcall glClearStencil(GLint s)
928{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000929 EVENT("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000930
931 try
932 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000933 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000934
935 if (context)
936 {
937 context->setClearStencil(s);
938 }
939 }
940 catch(std::bad_alloc&)
941 {
942 return error(GL_OUT_OF_MEMORY);
943 }
944}
945
946void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
947{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000948 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000949 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000950
951 try
952 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000953 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000954
955 if (context)
956 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000957 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000958 }
959 }
960 catch(std::bad_alloc&)
961 {
962 return error(GL_OUT_OF_MEMORY);
963 }
964}
965
966void __stdcall glCompileShader(GLuint shader)
967{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000968 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000969
970 try
971 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000972 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000973
974 if (context)
975 {
976 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000977
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000978 if (!shaderObject)
979 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000980 if (context->getProgram(shader))
981 {
982 return error(GL_INVALID_OPERATION);
983 }
984 else
985 {
986 return error(GL_INVALID_VALUE);
987 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000988 }
989
990 shaderObject->compile();
991 }
992 }
993 catch(std::bad_alloc&)
994 {
995 return error(GL_OUT_OF_MEMORY);
996 }
997}
998
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000999void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
1000 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001001{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001002 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001003 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001004 target, level, internalformat, width, height, border, imageSize, data);
1005
1006 try
1007 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001008 if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001009 {
1010 return error(GL_INVALID_VALUE);
1011 }
1012
daniel@transgaming.com01868132010-08-24 19:21:17 +00001013 switch (internalformat)
1014 {
1015 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1016 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001017 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1018 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001019 break;
1020 default:
1021 return error(GL_INVALID_ENUM);
1022 }
1023
1024 if (border != 0)
1025 {
1026 return error(GL_INVALID_VALUE);
1027 }
1028
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001029 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001030
1031 if (context)
1032 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001033 if (level > context->getMaximumTextureLevel())
1034 {
1035 return error(GL_INVALID_VALUE);
1036 }
1037
1038 switch (target)
1039 {
1040 case GL_TEXTURE_2D:
1041 if (width > (context->getMaximumTextureDimension() >> level) ||
1042 height > (context->getMaximumTextureDimension() >> level))
1043 {
1044 return error(GL_INVALID_VALUE);
1045 }
1046 break;
1047 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1048 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1049 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1050 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1051 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1052 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1053 if (width != height)
1054 {
1055 return error(GL_INVALID_VALUE);
1056 }
1057
1058 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1059 height > (context->getMaximumCubeTextureDimension() >> level))
1060 {
1061 return error(GL_INVALID_VALUE);
1062 }
1063 break;
1064 default:
1065 return error(GL_INVALID_ENUM);
1066 }
1067
gman@chromium.org50c526d2011-08-10 05:19:44 +00001068 switch (internalformat) {
1069 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1070 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1071 if (!context->supportsDXT1Textures())
1072 {
1073 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1074 }
1075 break;
1076 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1077 if (!context->supportsDXT3Textures())
1078 {
1079 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1080 }
1081 break;
1082 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1083 if (!context->supportsDXT5Textures())
1084 {
1085 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1086 }
1087 break;
1088 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001089 }
1090
1091 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
1092 {
1093 return error(GL_INVALID_VALUE);
1094 }
1095
1096 if (target == GL_TEXTURE_2D)
1097 {
1098 gl::Texture2D *texture = context->getTexture2D();
1099
1100 if (!texture)
1101 {
1102 return error(GL_INVALID_OPERATION);
1103 }
1104
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001105 if (texture->isImmutable())
1106 {
1107 return error(GL_INVALID_OPERATION);
1108 }
1109
daniel@transgaming.com01868132010-08-24 19:21:17 +00001110 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
1111 }
1112 else
1113 {
1114 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1115
1116 if (!texture)
1117 {
1118 return error(GL_INVALID_OPERATION);
1119 }
1120
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001121 if (texture->isImmutable())
1122 {
1123 return error(GL_INVALID_OPERATION);
1124 }
1125
daniel@transgaming.com01868132010-08-24 19:21:17 +00001126 switch (target)
1127 {
1128 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1129 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1130 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1131 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1132 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1133 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1134 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
1135 break;
1136 default: UNREACHABLE();
1137 }
1138 }
1139 }
1140
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001141 }
1142 catch(std::bad_alloc&)
1143 {
1144 return error(GL_OUT_OF_MEMORY);
1145 }
1146}
1147
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001148void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
1149 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001150{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001151 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001152 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001153 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001154 target, level, xoffset, yoffset, width, height, format, imageSize, data);
1155
1156 try
1157 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00001158 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +00001159 {
1160 return error(GL_INVALID_ENUM);
1161 }
1162
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001163 if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001164 {
1165 return error(GL_INVALID_VALUE);
1166 }
1167
daniel@transgaming.com01868132010-08-24 19:21:17 +00001168 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +00001169 {
daniel@transgaming.com01868132010-08-24 19:21:17 +00001170 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1171 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001172 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1173 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001174 break;
1175 default:
1176 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +00001177 }
1178
daniel@transgaming.com01868132010-08-24 19:21:17 +00001179 if (width == 0 || height == 0 || data == NULL)
1180 {
1181 return;
1182 }
1183
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001184 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001185
1186 if (context)
1187 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001188 if (level > context->getMaximumTextureLevel())
1189 {
1190 return error(GL_INVALID_VALUE);
1191 }
1192
gman@chromium.org50c526d2011-08-10 05:19:44 +00001193 switch (format) {
1194 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1195 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1196 if (!context->supportsDXT1Textures())
1197 {
1198 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1199 }
1200 break;
1201 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1202 if (!context->supportsDXT3Textures())
1203 {
1204 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1205 }
1206 break;
1207 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1208 if (!context->supportsDXT5Textures())
1209 {
1210 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1211 }
1212 break;
1213 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001214 }
1215
1216 if (imageSize != gl::ComputeCompressedSize(width, height, format))
1217 {
1218 return error(GL_INVALID_VALUE);
1219 }
1220
1221 if (xoffset % 4 != 0 || yoffset % 4 != 0)
1222 {
1223 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 +00001224 // does not exist unless DXT textures are supported.
daniel@transgaming.com01868132010-08-24 19:21:17 +00001225 }
1226
1227 if (target == GL_TEXTURE_2D)
1228 {
1229 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001230 if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, GL_NONE, texture))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001231 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001232 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
daniel@transgaming.com01868132010-08-24 19:21:17 +00001233 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001234 }
1235 else if (gl::IsCubemapTextureTarget(target))
1236 {
1237 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001238 if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, GL_NONE, texture))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001239 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00001240 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
daniel@transgaming.com01868132010-08-24 19:21:17 +00001241 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001242 }
1243 else
1244 {
1245 UNREACHABLE();
1246 }
1247 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001248 }
1249 catch(std::bad_alloc&)
1250 {
1251 return error(GL_OUT_OF_MEMORY);
1252 }
1253}
1254
1255void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1256{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001257 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001258 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001259 target, level, internalformat, x, y, width, height, border);
1260
1261 try
1262 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001263 if (!validImageSize(level, width, height))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001264 {
1265 return error(GL_INVALID_VALUE);
1266 }
1267
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001268 if (border != 0)
1269 {
1270 return error(GL_INVALID_VALUE);
1271 }
1272
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001273 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001274
1275 if (context)
1276 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00001277 if (level > context->getMaximumTextureLevel())
1278 {
1279 return error(GL_INVALID_VALUE);
1280 }
1281
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001282 switch (target)
1283 {
1284 case GL_TEXTURE_2D:
1285 if (width > (context->getMaximumTextureDimension() >> level) ||
1286 height > (context->getMaximumTextureDimension() >> level))
1287 {
1288 return error(GL_INVALID_VALUE);
1289 }
1290 break;
1291 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1292 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1293 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1294 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1295 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1296 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1297 if (width != height)
1298 {
1299 return error(GL_INVALID_VALUE);
1300 }
1301
1302 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1303 height > (context->getMaximumCubeTextureDimension() >> level))
1304 {
1305 return error(GL_INVALID_VALUE);
1306 }
1307 break;
1308 default:
1309 return error(GL_INVALID_ENUM);
1310 }
1311
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001312 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001313
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001314 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1315 {
1316 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1317 }
1318
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001319 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1320 {
1321 return error(GL_INVALID_OPERATION);
1322 }
1323
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001324 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001325 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001326
1327 // [OpenGL ES 2.0.24] table 3.9
1328 switch (internalformat)
1329 {
1330 case GL_ALPHA:
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001331 if (colorbufferFormat != GL_ALPHA8_EXT &&
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001332 colorbufferFormat != GL_RGBA4 &&
1333 colorbufferFormat != GL_RGB5_A1 &&
1334 colorbufferFormat != GL_RGBA8_OES)
1335 {
1336 return error(GL_INVALID_OPERATION);
1337 }
1338 break;
1339 case GL_LUMINANCE:
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001340 if (colorbufferFormat != GL_RGB565 &&
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001341 colorbufferFormat != GL_RGB8_OES &&
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001342 colorbufferFormat != GL_RGBA4 &&
1343 colorbufferFormat != GL_RGB5_A1 &&
1344 colorbufferFormat != GL_RGBA8_OES)
1345 {
1346 return error(GL_INVALID_OPERATION);
1347 }
1348 case GL_RGB:
1349 if (colorbufferFormat != GL_RGB565 &&
1350 colorbufferFormat != GL_RGB8_OES &&
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001351 colorbufferFormat != GL_RGBA4 &&
1352 colorbufferFormat != GL_RGB5_A1 &&
1353 colorbufferFormat != GL_RGBA8_OES)
1354 {
1355 return error(GL_INVALID_OPERATION);
1356 }
1357 break;
1358 case GL_LUMINANCE_ALPHA:
1359 case GL_RGBA:
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001360 if (colorbufferFormat != GL_RGBA4 &&
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001361 colorbufferFormat != GL_RGB5_A1 &&
1362 colorbufferFormat != GL_RGBA8_OES)
1363 {
1364 return error(GL_INVALID_OPERATION);
1365 }
1366 break;
1367 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1368 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001369 if (context->supportsDXT1Textures())
1370 {
1371 return error(GL_INVALID_OPERATION);
1372 }
1373 else
1374 {
1375 return error(GL_INVALID_ENUM);
1376 }
1377 break;
1378 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1379 if (context->supportsDXT3Textures())
1380 {
1381 return error(GL_INVALID_OPERATION);
1382 }
1383 else
1384 {
1385 return error(GL_INVALID_ENUM);
1386 }
1387 break;
1388 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1389 if (context->supportsDXT5Textures())
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001390 {
1391 return error(GL_INVALID_OPERATION);
1392 }
1393 else
1394 {
1395 return error(GL_INVALID_ENUM);
1396 }
1397 break;
daniel@transgaming.com0c854682012-05-31 01:14:11 +00001398 case GL_DEPTH_COMPONENT:
1399 case GL_DEPTH_COMPONENT16:
1400 case GL_DEPTH_COMPONENT32_OES:
1401 case GL_DEPTH_STENCIL_OES:
1402 case GL_DEPTH24_STENCIL8_OES:
1403 if (context->supportsDepthTextures())
1404 {
1405 return error(GL_INVALID_OPERATION);
1406 }
1407 else
1408 {
1409 return error(GL_INVALID_ENUM);
1410 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001411 default:
1412 return error(GL_INVALID_ENUM);
1413 }
1414
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001415 if (target == GL_TEXTURE_2D)
1416 {
1417 gl::Texture2D *texture = context->getTexture2D();
1418
1419 if (!texture)
1420 {
1421 return error(GL_INVALID_OPERATION);
1422 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001423
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001424 if (texture->isImmutable())
1425 {
1426 return error(GL_INVALID_OPERATION);
1427 }
1428
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001429 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001430 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001431 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001432 {
1433 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1434
1435 if (!texture)
1436 {
1437 return error(GL_INVALID_OPERATION);
1438 }
1439
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001440 if (texture->isImmutable())
1441 {
1442 return error(GL_INVALID_OPERATION);
1443 }
1444
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001445 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001446 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001447 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001448 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001449 }
1450 catch(std::bad_alloc&)
1451 {
1452 return error(GL_OUT_OF_MEMORY);
1453 }
1454}
1455
1456void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1457{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001458 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001459 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001460 target, level, xoffset, yoffset, x, y, width, height);
1461
1462 try
1463 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00001464 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001465 {
1466 return error(GL_INVALID_ENUM);
1467 }
1468
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001469 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001470 {
1471 return error(GL_INVALID_VALUE);
1472 }
1473
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001474 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1475 {
1476 return error(GL_INVALID_VALUE);
1477 }
1478
1479 if (width == 0 || height == 0)
1480 {
1481 return;
1482 }
1483
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001484 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001485
1486 if (context)
1487 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001488 if (level > context->getMaximumTextureLevel())
1489 {
1490 return error(GL_INVALID_VALUE);
1491 }
1492
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001493 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001494
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001495 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1496 {
1497 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1498 }
1499
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001500 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1501 {
1502 return error(GL_INVALID_OPERATION);
1503 }
1504
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001505 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001506 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001507 gl::Texture *texture = NULL;
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001508 GLenum textureFormat = GL_RGBA;
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001509
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001510 if (target == GL_TEXTURE_2D)
1511 {
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001512 gl::Texture2D *tex2d = context->getTexture2D();
1513
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001514 if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, GL_NONE, tex2d))
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001515 {
1516 return; // error already registered by validateSubImageParams
1517 }
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001518 textureFormat = gl::ExtractFormat(tex2d->getInternalFormat(level));
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001519 texture = tex2d;
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001520 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001521 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001522 {
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001523 gl::TextureCubeMap *texcube = context->getTextureCubeMap();
1524
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001525 if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, GL_NONE, texcube))
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001526 {
1527 return; // error already registered by validateSubImageParams
1528 }
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001529 textureFormat = gl::ExtractFormat(texcube->getInternalFormat(target, level));
daniel@transgaming.com2ccbbef2012-05-09 15:49:00 +00001530 texture = texcube;
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001531 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001532 else UNREACHABLE();
1533
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001534 // [OpenGL ES 2.0.24] table 3.9
1535 switch (textureFormat)
1536 {
1537 case GL_ALPHA:
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001538 if (colorbufferFormat != GL_ALPHA8_EXT &&
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001539 colorbufferFormat != GL_RGBA4 &&
1540 colorbufferFormat != GL_RGB5_A1 &&
1541 colorbufferFormat != GL_RGBA8_OES)
1542 {
1543 return error(GL_INVALID_OPERATION);
1544 }
1545 break;
1546 case GL_LUMINANCE:
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001547 if (colorbufferFormat != GL_RGB565 &&
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001548 colorbufferFormat != GL_RGB8_OES &&
1549 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;
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001557 case GL_RGB:
1558 if (colorbufferFormat != GL_RGB565 &&
1559 colorbufferFormat != GL_RGB8_OES &&
1560 colorbufferFormat != GL_RGBA4 &&
1561 colorbufferFormat != GL_RGB5_A1 &&
1562 colorbufferFormat != GL_RGBA8_OES)
1563 {
1564 return error(GL_INVALID_OPERATION);
1565 }
1566 break;
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001567 case GL_LUMINANCE_ALPHA:
1568 case GL_RGBA:
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00001569 if (colorbufferFormat != GL_RGBA4 &&
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001570 colorbufferFormat != GL_RGB5_A1 &&
1571 colorbufferFormat != GL_RGBA8_OES)
1572 {
1573 return error(GL_INVALID_OPERATION);
1574 }
1575 break;
1576 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1577 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001578 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1579 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001580 return error(GL_INVALID_OPERATION);
daniel@transgaming.com0c854682012-05-31 01:14:11 +00001581 case GL_DEPTH_COMPONENT:
1582 case GL_DEPTH_STENCIL_OES:
1583 return error(GL_INVALID_OPERATION);
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001584 default:
1585 return error(GL_INVALID_OPERATION);
1586 }
1587
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001588 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001589 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001590 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001591
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001592 catch(std::bad_alloc&)
1593 {
1594 return error(GL_OUT_OF_MEMORY);
1595 }
1596}
1597
1598GLuint __stdcall glCreateProgram(void)
1599{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001600 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001601
1602 try
1603 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001604 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001605
1606 if (context)
1607 {
1608 return context->createProgram();
1609 }
1610 }
1611 catch(std::bad_alloc&)
1612 {
1613 return error(GL_OUT_OF_MEMORY, 0);
1614 }
1615
1616 return 0;
1617}
1618
1619GLuint __stdcall glCreateShader(GLenum type)
1620{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001621 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001622
1623 try
1624 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001625 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001626
1627 if (context)
1628 {
1629 switch (type)
1630 {
1631 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001632 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001633 return context->createShader(type);
1634 default:
1635 return error(GL_INVALID_ENUM, 0);
1636 }
1637 }
1638 }
1639 catch(std::bad_alloc&)
1640 {
1641 return error(GL_OUT_OF_MEMORY, 0);
1642 }
1643
1644 return 0;
1645}
1646
1647void __stdcall glCullFace(GLenum mode)
1648{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001649 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001650
1651 try
1652 {
1653 switch (mode)
1654 {
1655 case GL_FRONT:
1656 case GL_BACK:
1657 case GL_FRONT_AND_BACK:
1658 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001659 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001660
1661 if (context)
1662 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001663 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001664 }
1665 }
1666 break;
1667 default:
1668 return error(GL_INVALID_ENUM);
1669 }
1670 }
1671 catch(std::bad_alloc&)
1672 {
1673 return error(GL_OUT_OF_MEMORY);
1674 }
1675}
1676
1677void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1678{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001679 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001680
1681 try
1682 {
1683 if (n < 0)
1684 {
1685 return error(GL_INVALID_VALUE);
1686 }
1687
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001688 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001689
1690 if (context)
1691 {
1692 for (int i = 0; i < n; i++)
1693 {
1694 context->deleteBuffer(buffers[i]);
1695 }
1696 }
1697 }
1698 catch(std::bad_alloc&)
1699 {
1700 return error(GL_OUT_OF_MEMORY);
1701 }
1702}
1703
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001704void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1705{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001706 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001707
1708 try
1709 {
1710 if (n < 0)
1711 {
1712 return error(GL_INVALID_VALUE);
1713 }
1714
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001715 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001716
1717 if (context)
1718 {
1719 for (int i = 0; i < n; i++)
1720 {
1721 context->deleteFence(fences[i]);
1722 }
1723 }
1724 }
1725 catch(std::bad_alloc&)
1726 {
1727 return error(GL_OUT_OF_MEMORY);
1728 }
1729}
1730
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001731void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1732{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001733 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001734
1735 try
1736 {
1737 if (n < 0)
1738 {
1739 return error(GL_INVALID_VALUE);
1740 }
1741
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001742 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001743
1744 if (context)
1745 {
1746 for (int i = 0; i < n; i++)
1747 {
1748 if (framebuffers[i] != 0)
1749 {
1750 context->deleteFramebuffer(framebuffers[i]);
1751 }
1752 }
1753 }
1754 }
1755 catch(std::bad_alloc&)
1756 {
1757 return error(GL_OUT_OF_MEMORY);
1758 }
1759}
1760
1761void __stdcall glDeleteProgram(GLuint program)
1762{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001763 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001764
1765 try
1766 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001767 if (program == 0)
1768 {
1769 return;
1770 }
1771
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001772 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001773
1774 if (context)
1775 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001776 if (!context->getProgram(program))
1777 {
1778 if(context->getShader(program))
1779 {
1780 return error(GL_INVALID_OPERATION);
1781 }
1782 else
1783 {
1784 return error(GL_INVALID_VALUE);
1785 }
1786 }
1787
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001788 context->deleteProgram(program);
1789 }
1790 }
1791 catch(std::bad_alloc&)
1792 {
1793 return error(GL_OUT_OF_MEMORY);
1794 }
1795}
1796
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00001797void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
1798{
1799 EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
1800
1801 try
1802 {
1803 if (n < 0)
1804 {
1805 return error(GL_INVALID_VALUE);
1806 }
1807
1808 gl::Context *context = gl::getNonLostContext();
1809
1810 if (context)
1811 {
1812 for (int i = 0; i < n; i++)
1813 {
1814 context->deleteQuery(ids[i]);
1815 }
1816 }
1817 }
1818 catch(std::bad_alloc&)
1819 {
1820 return error(GL_OUT_OF_MEMORY);
1821 }
1822}
1823
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001824void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1825{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001826 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001827
1828 try
1829 {
1830 if (n < 0)
1831 {
1832 return error(GL_INVALID_VALUE);
1833 }
1834
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001835 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001836
1837 if (context)
1838 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001839 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001840 {
1841 context->deleteRenderbuffer(renderbuffers[i]);
1842 }
1843 }
1844 }
1845 catch(std::bad_alloc&)
1846 {
1847 return error(GL_OUT_OF_MEMORY);
1848 }
1849}
1850
1851void __stdcall glDeleteShader(GLuint shader)
1852{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001853 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001854
1855 try
1856 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001857 if (shader == 0)
1858 {
1859 return;
1860 }
1861
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001862 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001863
1864 if (context)
1865 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001866 if (!context->getShader(shader))
1867 {
1868 if(context->getProgram(shader))
1869 {
1870 return error(GL_INVALID_OPERATION);
1871 }
1872 else
1873 {
1874 return error(GL_INVALID_VALUE);
1875 }
1876 }
1877
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001878 context->deleteShader(shader);
1879 }
1880 }
1881 catch(std::bad_alloc&)
1882 {
1883 return error(GL_OUT_OF_MEMORY);
1884 }
1885}
1886
1887void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1888{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001889 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001890
1891 try
1892 {
1893 if (n < 0)
1894 {
1895 return error(GL_INVALID_VALUE);
1896 }
1897
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001898 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001899
1900 if (context)
1901 {
1902 for (int i = 0; i < n; i++)
1903 {
1904 if (textures[i] != 0)
1905 {
1906 context->deleteTexture(textures[i]);
1907 }
1908 }
1909 }
1910 }
1911 catch(std::bad_alloc&)
1912 {
1913 return error(GL_OUT_OF_MEMORY);
1914 }
1915}
1916
1917void __stdcall glDepthFunc(GLenum func)
1918{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001919 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001920
1921 try
1922 {
1923 switch (func)
1924 {
1925 case GL_NEVER:
1926 case GL_ALWAYS:
1927 case GL_LESS:
1928 case GL_LEQUAL:
1929 case GL_EQUAL:
1930 case GL_GREATER:
1931 case GL_GEQUAL:
1932 case GL_NOTEQUAL:
1933 break;
1934 default:
1935 return error(GL_INVALID_ENUM);
1936 }
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->setDepthFunc(func);
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 glDepthMask(GLboolean flag)
1952{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001953 EVENT("(GLboolean flag = %d)", flag);
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->setDepthMask(flag != GL_FALSE);
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 glDepthRangef(GLclampf zNear, GLclampf zFar)
1971{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001972 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
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.com428d1582010-05-04 03:35:25 +00001980 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001981 }
1982 }
1983 catch(std::bad_alloc&)
1984 {
1985 return error(GL_OUT_OF_MEMORY);
1986 }
1987}
1988
1989void __stdcall glDetachShader(GLuint program, GLuint shader)
1990{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001991 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001992
1993 try
1994 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001995 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001996
1997 if (context)
1998 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001999
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002000 gl::Program *programObject = context->getProgram(program);
2001 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00002002
2003 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002004 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00002005 gl::Shader *shaderByProgramHandle;
2006 shaderByProgramHandle = context->getShader(program);
2007 if (!shaderByProgramHandle)
2008 {
2009 return error(GL_INVALID_VALUE);
2010 }
2011 else
2012 {
2013 return error(GL_INVALID_OPERATION);
2014 }
2015 }
2016
2017 if (!shaderObject)
2018 {
2019 gl::Program *programByShaderHandle = context->getProgram(shader);
2020 if (!programByShaderHandle)
2021 {
2022 return error(GL_INVALID_VALUE);
2023 }
2024 else
2025 {
2026 return error(GL_INVALID_OPERATION);
2027 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002028 }
2029
2030 if (!programObject->detachShader(shaderObject))
2031 {
2032 return error(GL_INVALID_OPERATION);
2033 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002034 }
2035 }
2036 catch(std::bad_alloc&)
2037 {
2038 return error(GL_OUT_OF_MEMORY);
2039 }
2040}
2041
2042void __stdcall glDisable(GLenum cap)
2043{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002044 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002045
2046 try
2047 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002048 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002049
2050 if (context)
2051 {
2052 switch (cap)
2053 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002054 case GL_CULL_FACE: context->setCullFace(false); break;
2055 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
2056 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
2057 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
2058 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
2059 case GL_STENCIL_TEST: context->setStencilTest(false); break;
2060 case GL_DEPTH_TEST: context->setDepthTest(false); break;
2061 case GL_BLEND: context->setBlend(false); break;
2062 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002063 default:
2064 return error(GL_INVALID_ENUM);
2065 }
2066 }
2067 }
2068 catch(std::bad_alloc&)
2069 {
2070 return error(GL_OUT_OF_MEMORY);
2071 }
2072}
2073
2074void __stdcall glDisableVertexAttribArray(GLuint index)
2075{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002076 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002077
2078 try
2079 {
2080 if (index >= gl::MAX_VERTEX_ATTRIBS)
2081 {
2082 return error(GL_INVALID_VALUE);
2083 }
2084
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002085 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002086
2087 if (context)
2088 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002089 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002090 }
2091 }
2092 catch(std::bad_alloc&)
2093 {
2094 return error(GL_OUT_OF_MEMORY);
2095 }
2096}
2097
2098void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
2099{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002100 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002101
2102 try
2103 {
2104 if (count < 0 || first < 0)
2105 {
2106 return error(GL_INVALID_VALUE);
2107 }
2108
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002109 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002110
2111 if (context)
2112 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002113 context->drawArrays(mode, first, count, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002114 }
2115 }
2116 catch(std::bad_alloc&)
2117 {
2118 return error(GL_OUT_OF_MEMORY);
2119 }
2120}
2121
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002122void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
2123{
2124 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
2125
2126 try
2127 {
2128 if (count < 0 || first < 0 || primcount < 0)
2129 {
2130 return error(GL_INVALID_VALUE);
2131 }
2132
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002133 if (primcount > 0)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002134 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002135 gl::Context *context = gl::getNonLostContext();
2136
2137 if (context)
2138 {
2139 context->drawArrays(mode, first, count, primcount);
2140 }
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002141 }
2142 }
2143 catch(std::bad_alloc&)
2144 {
2145 return error(GL_OUT_OF_MEMORY);
2146 }
2147}
2148
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002149void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002150{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002151 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 +00002152 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002153
2154 try
2155 {
2156 if (count < 0)
2157 {
2158 return error(GL_INVALID_VALUE);
2159 }
2160
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002161 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002162
2163 if (context)
2164 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002165 switch (type)
2166 {
2167 case GL_UNSIGNED_BYTE:
2168 case GL_UNSIGNED_SHORT:
2169 break;
2170 case GL_UNSIGNED_INT:
2171 if (!context->supports32bitIndices())
2172 {
2173 return error(GL_INVALID_ENUM);
2174 }
2175 break;
2176 default:
2177 return error(GL_INVALID_ENUM);
2178 }
2179
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002180 context->drawElements(mode, count, type, indices, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002181 }
2182 }
2183 catch(std::bad_alloc&)
2184 {
2185 return error(GL_OUT_OF_MEMORY);
2186 }
2187}
2188
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002189void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)
2190{
2191 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)",
2192 mode, count, type, indices, primcount);
2193
2194 try
2195 {
2196 if (count < 0 || primcount < 0)
2197 {
2198 return error(GL_INVALID_VALUE);
2199 }
2200
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002201 if (primcount > 0)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002202 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002203 gl::Context *context = gl::getNonLostContext();
2204
2205 if (context)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002206 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002207 switch (type)
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002208 {
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002209 case GL_UNSIGNED_BYTE:
2210 case GL_UNSIGNED_SHORT:
2211 break;
2212 case GL_UNSIGNED_INT:
2213 if (!context->supports32bitIndices())
2214 {
2215 return error(GL_INVALID_ENUM);
2216 }
2217 break;
2218 default:
2219 return error(GL_INVALID_ENUM);
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002220 }
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002221
2222 context->drawElements(mode, count, type, indices, primcount);
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002223 }
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00002224 }
2225 }
2226 catch(std::bad_alloc&)
2227 {
2228 return error(GL_OUT_OF_MEMORY);
2229 }
2230}
2231
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002232void __stdcall glEnable(GLenum cap)
2233{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002234 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002235
2236 try
2237 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002238 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002239
2240 if (context)
2241 {
2242 switch (cap)
2243 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002244 case GL_CULL_FACE: context->setCullFace(true); break;
2245 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
2246 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
2247 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
2248 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
2249 case GL_STENCIL_TEST: context->setStencilTest(true); break;
2250 case GL_DEPTH_TEST: context->setDepthTest(true); break;
2251 case GL_BLEND: context->setBlend(true); break;
2252 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002253 default:
2254 return error(GL_INVALID_ENUM);
2255 }
2256 }
2257 }
2258 catch(std::bad_alloc&)
2259 {
2260 return error(GL_OUT_OF_MEMORY);
2261 }
2262}
2263
2264void __stdcall glEnableVertexAttribArray(GLuint index)
2265{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002266 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002267
2268 try
2269 {
2270 if (index >= gl::MAX_VERTEX_ATTRIBS)
2271 {
2272 return error(GL_INVALID_VALUE);
2273 }
2274
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002275 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002276
2277 if (context)
2278 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00002279 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002280 }
2281 }
2282 catch(std::bad_alloc&)
2283 {
2284 return error(GL_OUT_OF_MEMORY);
2285 }
2286}
2287
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00002288void __stdcall glEndQueryEXT(GLenum target)
2289{
2290 EVENT("GLenum target = 0x%X)", target);
2291
2292 try
2293 {
2294 switch (target)
2295 {
2296 case GL_ANY_SAMPLES_PASSED_EXT:
2297 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
2298 break;
2299 default:
2300 return error(GL_INVALID_ENUM);
2301 }
2302
2303 gl::Context *context = gl::getNonLostContext();
2304
2305 if (context)
2306 {
2307 context->endQuery(target);
2308 }
2309 }
2310 catch(std::bad_alloc&)
2311 {
2312 return error(GL_OUT_OF_MEMORY);
2313 }
2314}
2315
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002316void __stdcall glFinishFenceNV(GLuint fence)
2317{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002318 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002319
2320 try
2321 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002322 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002323
2324 if (context)
2325 {
2326 gl::Fence* fenceObject = context->getFence(fence);
2327
2328 if (fenceObject == NULL)
2329 {
2330 return error(GL_INVALID_OPERATION);
2331 }
2332
2333 fenceObject->finishFence();
2334 }
2335 }
2336 catch(std::bad_alloc&)
2337 {
2338 return error(GL_OUT_OF_MEMORY);
2339 }
2340}
2341
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002342void __stdcall glFinish(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(true);
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 glFlush(void)
2362{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002363 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002364
2365 try
2366 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002367 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002368
2369 if (context)
2370 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002371 context->sync(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002372 }
2373 }
2374 catch(std::bad_alloc&)
2375 {
2376 return error(GL_OUT_OF_MEMORY);
2377 }
2378}
2379
2380void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2381{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002382 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002383 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002384
2385 try
2386 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002387 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002388 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002389 {
2390 return error(GL_INVALID_ENUM);
2391 }
2392
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002393 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002394
2395 if (context)
2396 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002397 gl::Framebuffer *framebuffer = NULL;
2398 GLuint framebufferHandle = 0;
2399 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2400 {
2401 framebuffer = context->getReadFramebuffer();
2402 framebufferHandle = context->getReadFramebufferHandle();
2403 }
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002404 else
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002405 {
2406 framebuffer = context->getDrawFramebuffer();
2407 framebufferHandle = context->getDrawFramebufferHandle();
2408 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002409
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002410 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002411 {
2412 return error(GL_INVALID_OPERATION);
2413 }
2414
2415 switch (attachment)
2416 {
2417 case GL_COLOR_ATTACHMENT0:
2418 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2419 break;
2420 case GL_DEPTH_ATTACHMENT:
2421 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2422 break;
2423 case GL_STENCIL_ATTACHMENT:
2424 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2425 break;
2426 default:
2427 return error(GL_INVALID_ENUM);
2428 }
2429 }
2430 }
2431 catch(std::bad_alloc&)
2432 {
2433 return error(GL_OUT_OF_MEMORY);
2434 }
2435}
2436
2437void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2438{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002439 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002440 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002441
2442 try
2443 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002444 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002445 {
2446 return error(GL_INVALID_ENUM);
2447 }
2448
2449 switch (attachment)
2450 {
2451 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002452 case GL_DEPTH_ATTACHMENT:
2453 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002454 break;
2455 default:
2456 return error(GL_INVALID_ENUM);
2457 }
2458
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002459 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002460
2461 if (context)
2462 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002463 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002464 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002465 textarget = GL_NONE;
2466 }
2467 else
2468 {
2469 gl::Texture *tex = context->getTexture(texture);
2470
2471 if (tex == NULL)
2472 {
2473 return error(GL_INVALID_OPERATION);
2474 }
2475
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002476 switch (textarget)
2477 {
2478 case GL_TEXTURE_2D:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002479 {
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002480 if (tex->getTarget() != GL_TEXTURE_2D)
2481 {
2482 return error(GL_INVALID_OPERATION);
2483 }
2484 gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
daniel@transgaming.com92f49922012-05-09 15:49:19 +00002485 if (tex2d->isCompressed(0))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002486 {
2487 return error(GL_INVALID_OPERATION);
2488 }
2489 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002490 }
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002491
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002492 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002493 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002494 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002495 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002496 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002497 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002498 {
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002499 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2500 {
2501 return error(GL_INVALID_OPERATION);
2502 }
2503 gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00002504 if (texcube->isCompressed(textarget, level))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002505 {
2506 return error(GL_INVALID_OPERATION);
2507 }
2508 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002509 }
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002510
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002511 default:
2512 return error(GL_INVALID_ENUM);
2513 }
2514
2515 if (level != 0)
2516 {
2517 return error(GL_INVALID_VALUE);
2518 }
2519 }
2520
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002521 gl::Framebuffer *framebuffer = NULL;
2522 GLuint framebufferHandle = 0;
2523 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2524 {
2525 framebuffer = context->getReadFramebuffer();
2526 framebufferHandle = context->getReadFramebufferHandle();
2527 }
2528 else
2529 {
2530 framebuffer = context->getDrawFramebuffer();
2531 framebufferHandle = context->getDrawFramebufferHandle();
2532 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002533
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002534 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002535 {
2536 return error(GL_INVALID_OPERATION);
2537 }
2538
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002539 switch (attachment)
2540 {
2541 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2542 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2543 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2544 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002545 }
2546 }
2547 catch(std::bad_alloc&)
2548 {
2549 return error(GL_OUT_OF_MEMORY);
2550 }
2551}
2552
2553void __stdcall glFrontFace(GLenum mode)
2554{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002555 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002556
2557 try
2558 {
2559 switch (mode)
2560 {
2561 case GL_CW:
2562 case GL_CCW:
2563 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002564 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002565
2566 if (context)
2567 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002568 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002569 }
2570 }
2571 break;
2572 default:
2573 return error(GL_INVALID_ENUM);
2574 }
2575 }
2576 catch(std::bad_alloc&)
2577 {
2578 return error(GL_OUT_OF_MEMORY);
2579 }
2580}
2581
2582void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2583{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002584 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002585
2586 try
2587 {
2588 if (n < 0)
2589 {
2590 return error(GL_INVALID_VALUE);
2591 }
2592
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002593 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002594
2595 if (context)
2596 {
2597 for (int i = 0; i < n; i++)
2598 {
2599 buffers[i] = context->createBuffer();
2600 }
2601 }
2602 }
2603 catch(std::bad_alloc&)
2604 {
2605 return error(GL_OUT_OF_MEMORY);
2606 }
2607}
2608
2609void __stdcall glGenerateMipmap(GLenum target)
2610{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002611 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002612
2613 try
2614 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002615 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002616
2617 if (context)
2618 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002619 switch (target)
2620 {
2621 case GL_TEXTURE_2D:
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002622 {
2623 gl::Texture2D *tex2d = context->getTexture2D();
2624
daniel@transgaming.com92f49922012-05-09 15:49:19 +00002625 if (tex2d->isCompressed(0))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002626 {
2627 return error(GL_INVALID_OPERATION);
2628 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00002629 if (tex2d->isDepth(0))
2630 {
2631 return error(GL_INVALID_OPERATION);
2632 }
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002633
2634 tex2d->generateMipmaps();
2635 break;
2636 }
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002637
2638 case GL_TEXTURE_CUBE_MAP:
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002639 {
2640 gl::TextureCubeMap *texcube = context->getTextureCubeMap();
2641
daniel@transgaming.com4df88e82012-05-09 15:49:24 +00002642 if (texcube->isCompressed(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0))
daniel@transgaming.comeb3c01a2012-05-09 15:49:12 +00002643 {
2644 return error(GL_INVALID_OPERATION);
2645 }
2646
2647 texcube->generateMipmaps();
2648 break;
2649 }
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002650
2651 default:
2652 return error(GL_INVALID_ENUM);
2653 }
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002654 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002655 }
2656 catch(std::bad_alloc&)
2657 {
2658 return error(GL_OUT_OF_MEMORY);
2659 }
2660}
2661
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002662void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2663{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002664 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002665
2666 try
2667 {
2668 if (n < 0)
2669 {
2670 return error(GL_INVALID_VALUE);
2671 }
2672
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002673 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002674
2675 if (context)
2676 {
2677 for (int i = 0; i < n; i++)
2678 {
2679 fences[i] = context->createFence();
2680 }
2681 }
2682 }
2683 catch(std::bad_alloc&)
2684 {
2685 return error(GL_OUT_OF_MEMORY);
2686 }
2687}
2688
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002689void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2690{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002691 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002692
2693 try
2694 {
2695 if (n < 0)
2696 {
2697 return error(GL_INVALID_VALUE);
2698 }
2699
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002700 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002701
2702 if (context)
2703 {
2704 for (int i = 0; i < n; i++)
2705 {
2706 framebuffers[i] = context->createFramebuffer();
2707 }
2708 }
2709 }
2710 catch(std::bad_alloc&)
2711 {
2712 return error(GL_OUT_OF_MEMORY);
2713 }
2714}
2715
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00002716void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
2717{
2718 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
2719
2720 try
2721 {
2722 if (n < 0)
2723 {
2724 return error(GL_INVALID_VALUE);
2725 }
2726
2727 gl::Context *context = gl::getNonLostContext();
2728
2729 if (context)
2730 {
2731 for (int i = 0; i < n; i++)
2732 {
2733 ids[i] = context->createQuery();
2734 }
2735 }
2736 }
2737 catch(std::bad_alloc&)
2738 {
2739 return error(GL_OUT_OF_MEMORY);
2740 }
2741}
2742
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002743void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2744{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002745 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002746
2747 try
2748 {
2749 if (n < 0)
2750 {
2751 return error(GL_INVALID_VALUE);
2752 }
2753
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002754 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002755
2756 if (context)
2757 {
2758 for (int i = 0; i < n; i++)
2759 {
2760 renderbuffers[i] = context->createRenderbuffer();
2761 }
2762 }
2763 }
2764 catch(std::bad_alloc&)
2765 {
2766 return error(GL_OUT_OF_MEMORY);
2767 }
2768}
2769
2770void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2771{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002772 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002773
2774 try
2775 {
2776 if (n < 0)
2777 {
2778 return error(GL_INVALID_VALUE);
2779 }
2780
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002781 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002782
2783 if (context)
2784 {
2785 for (int i = 0; i < n; i++)
2786 {
2787 textures[i] = context->createTexture();
2788 }
2789 }
2790 }
2791 catch(std::bad_alloc&)
2792 {
2793 return error(GL_OUT_OF_MEMORY);
2794 }
2795}
2796
daniel@transgaming.com85423182010-04-22 13:35:27 +00002797void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002798{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002799 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002800 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002801 program, index, bufsize, length, size, type, name);
2802
2803 try
2804 {
2805 if (bufsize < 0)
2806 {
2807 return error(GL_INVALID_VALUE);
2808 }
2809
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002810 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com85423182010-04-22 13:35:27 +00002811
2812 if (context)
2813 {
2814 gl::Program *programObject = context->getProgram(program);
2815
2816 if (!programObject)
2817 {
2818 if (context->getShader(program))
2819 {
2820 return error(GL_INVALID_OPERATION);
2821 }
2822 else
2823 {
2824 return error(GL_INVALID_VALUE);
2825 }
2826 }
2827
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002828 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002829 {
2830 return error(GL_INVALID_VALUE);
2831 }
2832
2833 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2834 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002835 }
2836 catch(std::bad_alloc&)
2837 {
2838 return error(GL_OUT_OF_MEMORY);
2839 }
2840}
2841
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002842void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002843{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002844 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002845 "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 +00002846 program, index, bufsize, length, size, type, name);
2847
2848 try
2849 {
2850 if (bufsize < 0)
2851 {
2852 return error(GL_INVALID_VALUE);
2853 }
2854
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002855 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002856
2857 if (context)
2858 {
2859 gl::Program *programObject = context->getProgram(program);
2860
2861 if (!programObject)
2862 {
2863 if (context->getShader(program))
2864 {
2865 return error(GL_INVALID_OPERATION);
2866 }
2867 else
2868 {
2869 return error(GL_INVALID_VALUE);
2870 }
2871 }
2872
2873 if (index >= (GLuint)programObject->getActiveUniformCount())
2874 {
2875 return error(GL_INVALID_VALUE);
2876 }
2877
2878 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2879 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002880 }
2881 catch(std::bad_alloc&)
2882 {
2883 return error(GL_OUT_OF_MEMORY);
2884 }
2885}
2886
2887void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2888{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002889 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 +00002890 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002891
2892 try
2893 {
2894 if (maxcount < 0)
2895 {
2896 return error(GL_INVALID_VALUE);
2897 }
2898
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002899 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002900
2901 if (context)
2902 {
2903 gl::Program *programObject = context->getProgram(program);
2904
2905 if (!programObject)
2906 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002907 if (context->getShader(program))
2908 {
2909 return error(GL_INVALID_OPERATION);
2910 }
2911 else
2912 {
2913 return error(GL_INVALID_VALUE);
2914 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002915 }
2916
2917 return programObject->getAttachedShaders(maxcount, count, shaders);
2918 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002919 }
2920 catch(std::bad_alloc&)
2921 {
2922 return error(GL_OUT_OF_MEMORY);
2923 }
2924}
2925
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002926int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002927{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002928 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002929
2930 try
2931 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002932 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002933
2934 if (context)
2935 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002936
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002937 gl::Program *programObject = context->getProgram(program);
2938
2939 if (!programObject)
2940 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002941 if (context->getShader(program))
2942 {
2943 return error(GL_INVALID_OPERATION, -1);
2944 }
2945 else
2946 {
2947 return error(GL_INVALID_VALUE, -1);
2948 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002949 }
2950
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00002951 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
daniel@transgaming.com716056c2012-07-24 18:38:59 +00002952 if (!programObject->isLinked() || !programBinary)
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002953 {
2954 return error(GL_INVALID_OPERATION, -1);
2955 }
2956
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00002957 return programBinary->getAttributeLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002958 }
2959 }
2960 catch(std::bad_alloc&)
2961 {
2962 return error(GL_OUT_OF_MEMORY, -1);
2963 }
2964
2965 return -1;
2966}
2967
2968void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2969{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002970 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002971
2972 try
2973 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002974 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002975
2976 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002977 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002978 if (!(context->getBooleanv(pname, params)))
2979 {
2980 GLenum nativeType;
2981 unsigned int numParams = 0;
2982 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2983 return error(GL_INVALID_ENUM);
2984
2985 if (numParams == 0)
2986 return; // it is known that the pname is valid, but there are no parameters to return
2987
2988 if (nativeType == GL_FLOAT)
2989 {
2990 GLfloat *floatParams = NULL;
2991 floatParams = new GLfloat[numParams];
2992
2993 context->getFloatv(pname, floatParams);
2994
2995 for (unsigned int i = 0; i < numParams; ++i)
2996 {
2997 if (floatParams[i] == 0.0f)
2998 params[i] = GL_FALSE;
2999 else
3000 params[i] = GL_TRUE;
3001 }
3002
3003 delete [] floatParams;
3004 }
3005 else if (nativeType == GL_INT)
3006 {
3007 GLint *intParams = NULL;
3008 intParams = new GLint[numParams];
3009
3010 context->getIntegerv(pname, intParams);
3011
3012 for (unsigned int i = 0; i < numParams; ++i)
3013 {
3014 if (intParams[i] == 0)
3015 params[i] = GL_FALSE;
3016 else
3017 params[i] = GL_TRUE;
3018 }
3019
3020 delete [] intParams;
3021 }
3022 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003023 }
3024 }
3025 catch(std::bad_alloc&)
3026 {
3027 return error(GL_OUT_OF_MEMORY);
3028 }
3029}
3030
3031void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
3032{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003033 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 +00003034
3035 try
3036 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003037 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00003038
3039 if (context)
3040 {
3041 gl::Buffer *buffer;
3042
3043 switch (target)
3044 {
3045 case GL_ARRAY_BUFFER:
3046 buffer = context->getArrayBuffer();
3047 break;
3048 case GL_ELEMENT_ARRAY_BUFFER:
3049 buffer = context->getElementArrayBuffer();
3050 break;
3051 default: return error(GL_INVALID_ENUM);
3052 }
3053
3054 if (!buffer)
3055 {
3056 // A null buffer means that "0" is bound to the requested buffer target
3057 return error(GL_INVALID_OPERATION);
3058 }
3059
3060 switch (pname)
3061 {
3062 case GL_BUFFER_USAGE:
3063 *params = buffer->usage();
3064 break;
3065 case GL_BUFFER_SIZE:
3066 *params = buffer->size();
3067 break;
3068 default: return error(GL_INVALID_ENUM);
3069 }
3070 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003071 }
3072 catch(std::bad_alloc&)
3073 {
3074 return error(GL_OUT_OF_MEMORY);
3075 }
3076}
3077
3078GLenum __stdcall glGetError(void)
3079{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003080 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003081
3082 gl::Context *context = gl::getContext();
3083
3084 if (context)
3085 {
daniel@transgaming.com82b28912011-12-12 21:01:35 +00003086 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003087 }
3088
3089 return GL_NO_ERROR;
3090}
3091
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003092void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
3093{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003094 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003095
3096 try
3097 {
3098
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003099 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003100
3101 if (context)
3102 {
3103 gl::Fence *fenceObject = context->getFence(fence);
3104
3105 if (fenceObject == NULL)
3106 {
3107 return error(GL_INVALID_OPERATION);
3108 }
3109
3110 fenceObject->getFenceiv(pname, params);
3111 }
3112 }
3113 catch(std::bad_alloc&)
3114 {
3115 return error(GL_OUT_OF_MEMORY);
3116 }
3117}
3118
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003119void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
3120{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003121 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003122
3123 try
3124 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003125 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003126
3127 if (context)
3128 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003129 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003130 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003131 GLenum nativeType;
3132 unsigned int numParams = 0;
3133 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3134 return error(GL_INVALID_ENUM);
3135
3136 if (numParams == 0)
3137 return; // it is known that the pname is valid, but that there are no parameters to return.
3138
3139 if (nativeType == GL_BOOL)
3140 {
3141 GLboolean *boolParams = NULL;
3142 boolParams = new GLboolean[numParams];
3143
3144 context->getBooleanv(pname, boolParams);
3145
3146 for (unsigned int i = 0; i < numParams; ++i)
3147 {
3148 if (boolParams[i] == GL_FALSE)
3149 params[i] = 0.0f;
3150 else
3151 params[i] = 1.0f;
3152 }
3153
3154 delete [] boolParams;
3155 }
3156 else if (nativeType == GL_INT)
3157 {
3158 GLint *intParams = NULL;
3159 intParams = new GLint[numParams];
3160
3161 context->getIntegerv(pname, intParams);
3162
3163 for (unsigned int i = 0; i < numParams; ++i)
3164 {
3165 params[i] = (GLfloat)intParams[i];
3166 }
3167
3168 delete [] intParams;
3169 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003170 }
3171 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003172 }
3173 catch(std::bad_alloc&)
3174 {
3175 return error(GL_OUT_OF_MEMORY);
3176 }
3177}
3178
3179void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
3180{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003181 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 +00003182 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003183
3184 try
3185 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003186 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003187
3188 if (context)
3189 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003190 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003191 {
3192 return error(GL_INVALID_ENUM);
3193 }
3194
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003195 gl::Framebuffer *framebuffer = NULL;
3196 if (target == GL_READ_FRAMEBUFFER_ANGLE)
3197 {
3198 if(context->getReadFramebufferHandle() == 0)
3199 {
3200 return error(GL_INVALID_OPERATION);
3201 }
3202
3203 framebuffer = context->getReadFramebuffer();
3204 }
3205 else
3206 {
3207 if (context->getDrawFramebufferHandle() == 0)
3208 {
3209 return error(GL_INVALID_OPERATION);
3210 }
3211
3212 framebuffer = context->getDrawFramebuffer();
3213 }
3214
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003215 GLenum attachmentType;
3216 GLuint attachmentHandle;
3217 switch (attachment)
3218 {
3219 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003220 attachmentType = framebuffer->getColorbufferType();
3221 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003222 break;
3223 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003224 attachmentType = framebuffer->getDepthbufferType();
3225 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003226 break;
3227 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00003228 attachmentType = framebuffer->getStencilbufferType();
3229 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003230 break;
3231 default: return error(GL_INVALID_ENUM);
3232 }
3233
3234 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00003235 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003236 {
3237 attachmentObjectType = attachmentType;
3238 }
apatrick@chromium.org551022e2012-01-23 19:56:54 +00003239 else if (gl::IsInternalTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003240 {
3241 attachmentObjectType = GL_TEXTURE;
3242 }
apatrick@chromium.orga1d80592012-01-25 21:52:10 +00003243 else
3244 {
3245 UNREACHABLE();
3246 return;
3247 }
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003248
3249 switch (pname)
3250 {
3251 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3252 *params = attachmentObjectType;
3253 break;
3254 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3255 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
3256 {
3257 *params = attachmentHandle;
3258 }
3259 else
3260 {
3261 return error(GL_INVALID_ENUM);
3262 }
3263 break;
3264 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3265 if (attachmentObjectType == GL_TEXTURE)
3266 {
3267 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
3268 }
3269 else
3270 {
3271 return error(GL_INVALID_ENUM);
3272 }
3273 break;
3274 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3275 if (attachmentObjectType == GL_TEXTURE)
3276 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00003277 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00003278 {
3279 *params = attachmentType;
3280 }
3281 else
3282 {
3283 *params = 0;
3284 }
3285 }
3286 else
3287 {
3288 return error(GL_INVALID_ENUM);
3289 }
3290 break;
3291 default:
3292 return error(GL_INVALID_ENUM);
3293 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003294 }
3295 }
3296 catch(std::bad_alloc&)
3297 {
3298 return error(GL_OUT_OF_MEMORY);
3299 }
3300}
3301
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00003302GLenum __stdcall glGetGraphicsResetStatusEXT(void)
3303{
3304 EVENT("()");
3305
3306 try
3307 {
3308 gl::Context *context = gl::getContext();
3309
3310 if (context)
3311 {
3312 return context->getResetStatus();
3313 }
3314
3315 return GL_NO_ERROR;
3316 }
3317 catch(std::bad_alloc&)
3318 {
3319 return GL_OUT_OF_MEMORY;
3320 }
3321}
3322
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003323void __stdcall glGetIntegerv(GLenum pname, GLint* params)
3324{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003325 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003326
3327 try
3328 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003329 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003330
3331 if (context)
3332 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003333 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003334 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003335 GLenum nativeType;
3336 unsigned int numParams = 0;
3337 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3338 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003339
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003340 if (numParams == 0)
3341 return; // it is known that pname is valid, but there are no parameters to return
3342
3343 if (nativeType == GL_BOOL)
3344 {
3345 GLboolean *boolParams = NULL;
3346 boolParams = new GLboolean[numParams];
3347
3348 context->getBooleanv(pname, boolParams);
3349
3350 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003351 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003352 if (boolParams[i] == GL_FALSE)
3353 params[i] = 0;
3354 else
3355 params[i] = 1;
3356 }
3357
3358 delete [] boolParams;
3359 }
3360 else if (nativeType == GL_FLOAT)
3361 {
3362 GLfloat *floatParams = NULL;
3363 floatParams = new GLfloat[numParams];
3364
3365 context->getFloatv(pname, floatParams);
3366
3367 for (unsigned int i = 0; i < numParams; ++i)
3368 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00003369 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 +00003370 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003371 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003372 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003373 else
3374 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 +00003375 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003376
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003377 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003378 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003379 }
3380 }
3381 }
3382 catch(std::bad_alloc&)
3383 {
3384 return error(GL_OUT_OF_MEMORY);
3385 }
3386}
3387
3388void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3389{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003390 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003391
3392 try
3393 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003394 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003395
3396 if (context)
3397 {
3398 gl::Program *programObject = context->getProgram(program);
3399
3400 if (!programObject)
3401 {
3402 return error(GL_INVALID_VALUE);
3403 }
3404
3405 switch (pname)
3406 {
3407 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003408 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003409 return;
3410 case GL_LINK_STATUS:
daniel@transgaming.com716056c2012-07-24 18:38:59 +00003411 *params = programObject->isLinked();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003412 return;
3413 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003414 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003415 return;
3416 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003417 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003418 return;
3419 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003420 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003421 return;
3422 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003423 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003424 return;
3425 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003426 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003427 return;
3428 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003429 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003430 return;
3431 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003432 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003433 return;
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00003434 case GL_PROGRAM_BINARY_LENGTH_OES:
apatrick@chromium.org90080e32012-07-09 22:15:33 +00003435 *params = programObject->getProgramBinaryLength();
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00003436 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003437 default:
3438 return error(GL_INVALID_ENUM);
3439 }
3440 }
3441 }
3442 catch(std::bad_alloc&)
3443 {
3444 return error(GL_OUT_OF_MEMORY);
3445 }
3446}
3447
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003448void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003449{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003450 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 +00003451 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003452
3453 try
3454 {
3455 if (bufsize < 0)
3456 {
3457 return error(GL_INVALID_VALUE);
3458 }
3459
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003460 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003461
3462 if (context)
3463 {
3464 gl::Program *programObject = context->getProgram(program);
3465
3466 if (!programObject)
3467 {
3468 return error(GL_INVALID_VALUE);
3469 }
3470
3471 programObject->getInfoLog(bufsize, length, infolog);
3472 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003473 }
3474 catch(std::bad_alloc&)
3475 {
3476 return error(GL_OUT_OF_MEMORY);
3477 }
3478}
3479
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003480void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3481{
3482 EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
3483
3484 try
3485 {
3486 switch (pname)
3487 {
3488 case GL_CURRENT_QUERY_EXT:
3489 break;
3490 default:
3491 return error(GL_INVALID_ENUM);
3492 }
3493
3494 gl::Context *context = gl::getNonLostContext();
3495
3496 if (context)
3497 {
3498 params[0] = context->getActiveQuery(target);
3499 }
3500 }
3501 catch(std::bad_alloc&)
3502 {
3503 return error(GL_OUT_OF_MEMORY);
3504 }
3505}
3506
3507void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
3508{
3509 EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
3510
3511 try
3512 {
3513 switch (pname)
3514 {
3515 case GL_QUERY_RESULT_EXT:
3516 case GL_QUERY_RESULT_AVAILABLE_EXT:
3517 break;
3518 default:
3519 return error(GL_INVALID_ENUM);
3520 }
3521 gl::Context *context = gl::getNonLostContext();
3522
3523 if (context)
3524 {
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00003525 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
3526
3527 if (!queryObject)
3528 {
3529 return error(GL_INVALID_OPERATION);
3530 }
3531
3532 if (context->getActiveQuery(queryObject->getType()) == id)
3533 {
3534 return error(GL_INVALID_OPERATION);
3535 }
3536
3537 switch(pname)
3538 {
3539 case GL_QUERY_RESULT_EXT:
3540 params[0] = queryObject->getResult();
3541 break;
3542 case GL_QUERY_RESULT_AVAILABLE_EXT:
3543 params[0] = queryObject->isResultAvailable();
3544 break;
3545 default:
3546 ASSERT(false);
3547 }
3548 }
3549 }
3550 catch(std::bad_alloc&)
3551 {
3552 return error(GL_OUT_OF_MEMORY);
3553 }
3554}
3555
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003556void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3557{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003558 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 +00003559
3560 try
3561 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003562 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003563
3564 if (context)
3565 {
3566 if (target != GL_RENDERBUFFER)
3567 {
3568 return error(GL_INVALID_ENUM);
3569 }
3570
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003571 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003572 {
3573 return error(GL_INVALID_OPERATION);
3574 }
3575
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003576 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003577
3578 switch (pname)
3579 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003580 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3581 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3582 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3583 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3584 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3585 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3586 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3587 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3588 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003589 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003590 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003591 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003592 *params = renderbuffer->getSamples();
3593 }
3594 else
3595 {
3596 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003597 }
3598 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003599 default:
3600 return error(GL_INVALID_ENUM);
3601 }
3602 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003603 }
3604 catch(std::bad_alloc&)
3605 {
3606 return error(GL_OUT_OF_MEMORY);
3607 }
3608}
3609
3610void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3611{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003612 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003613
3614 try
3615 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003616 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003617
3618 if (context)
3619 {
3620 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003621
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003622 if (!shaderObject)
3623 {
3624 return error(GL_INVALID_VALUE);
3625 }
3626
3627 switch (pname)
3628 {
3629 case GL_SHADER_TYPE:
3630 *params = shaderObject->getType();
3631 return;
3632 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003633 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003634 return;
3635 case GL_COMPILE_STATUS:
3636 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3637 return;
3638 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003639 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003640 return;
3641 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003642 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003643 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003644 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3645 *params = shaderObject->getTranslatedSourceLength();
3646 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003647 default:
3648 return error(GL_INVALID_ENUM);
3649 }
3650 }
3651 }
3652 catch(std::bad_alloc&)
3653 {
3654 return error(GL_OUT_OF_MEMORY);
3655 }
3656}
3657
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003658void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003659{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003660 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 +00003661 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003662
3663 try
3664 {
3665 if (bufsize < 0)
3666 {
3667 return error(GL_INVALID_VALUE);
3668 }
3669
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003670 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003671
3672 if (context)
3673 {
3674 gl::Shader *shaderObject = context->getShader(shader);
3675
3676 if (!shaderObject)
3677 {
3678 return error(GL_INVALID_VALUE);
3679 }
3680
3681 shaderObject->getInfoLog(bufsize, length, infolog);
3682 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003683 }
3684 catch(std::bad_alloc&)
3685 {
3686 return error(GL_OUT_OF_MEMORY);
3687 }
3688}
3689
3690void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3691{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003692 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 +00003693 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003694
3695 try
3696 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003697 switch (shadertype)
3698 {
3699 case GL_VERTEX_SHADER:
3700 case GL_FRAGMENT_SHADER:
3701 break;
3702 default:
3703 return error(GL_INVALID_ENUM);
3704 }
3705
3706 switch (precisiontype)
3707 {
3708 case GL_LOW_FLOAT:
3709 case GL_MEDIUM_FLOAT:
3710 case GL_HIGH_FLOAT:
3711 // Assume IEEE 754 precision
3712 range[0] = 127;
3713 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003714 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003715 break;
3716 case GL_LOW_INT:
3717 case GL_MEDIUM_INT:
3718 case GL_HIGH_INT:
3719 // Some (most) hardware only supports single-precision floating-point numbers,
3720 // which can accurately represent integers up to +/-16777216
3721 range[0] = 24;
3722 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003723 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003724 break;
3725 default:
3726 return error(GL_INVALID_ENUM);
3727 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003728 }
3729 catch(std::bad_alloc&)
3730 {
3731 return error(GL_OUT_OF_MEMORY);
3732 }
3733}
3734
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003735void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003736{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003737 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 +00003738 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003739
3740 try
3741 {
3742 if (bufsize < 0)
3743 {
3744 return error(GL_INVALID_VALUE);
3745 }
3746
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003747 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003748
3749 if (context)
3750 {
3751 gl::Shader *shaderObject = context->getShader(shader);
3752
3753 if (!shaderObject)
3754 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003755 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003756 }
3757
3758 shaderObject->getSource(bufsize, length, source);
3759 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003760 }
3761 catch(std::bad_alloc&)
3762 {
3763 return error(GL_OUT_OF_MEMORY);
3764 }
3765}
3766
zmo@google.coma574f782011-10-03 21:45:23 +00003767void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3768{
3769 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3770 shader, bufsize, length, source);
3771
3772 try
3773 {
3774 if (bufsize < 0)
3775 {
3776 return error(GL_INVALID_VALUE);
3777 }
3778
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003779 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003780
3781 if (context)
3782 {
3783 gl::Shader *shaderObject = context->getShader(shader);
3784
3785 if (!shaderObject)
3786 {
3787 return error(GL_INVALID_OPERATION);
3788 }
3789
3790 shaderObject->getTranslatedSource(bufsize, length, source);
3791 }
3792 }
3793 catch(std::bad_alloc&)
3794 {
3795 return error(GL_OUT_OF_MEMORY);
3796 }
3797}
3798
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003799const GLubyte* __stdcall glGetString(GLenum name)
3800{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003801 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003802
3803 try
3804 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003805 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003806
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003807 switch (name)
3808 {
3809 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003810 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003811 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003812 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003813 case GL_VERSION:
daniel@transgaming.com1825d8e2012-08-27 16:25:29 +00003814 return (GLubyte*)"OpenGL ES 2.0 (ANGLE " VERSION_STRING ")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003815 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.com1825d8e2012-08-27 16:25:29 +00003816 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " VERSION_STRING ")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003817 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003818 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003819 default:
3820 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3821 }
3822 }
3823 catch(std::bad_alloc&)
3824 {
3825 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3826 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003827}
3828
3829void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3830{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003831 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 +00003832
3833 try
3834 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003835 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003836
3837 if (context)
3838 {
3839 gl::Texture *texture;
3840
3841 switch (target)
3842 {
3843 case GL_TEXTURE_2D:
3844 texture = context->getTexture2D();
3845 break;
3846 case GL_TEXTURE_CUBE_MAP:
3847 texture = context->getTextureCubeMap();
3848 break;
3849 default:
3850 return error(GL_INVALID_ENUM);
3851 }
3852
3853 switch (pname)
3854 {
3855 case GL_TEXTURE_MAG_FILTER:
3856 *params = (GLfloat)texture->getMagFilter();
3857 break;
3858 case GL_TEXTURE_MIN_FILTER:
3859 *params = (GLfloat)texture->getMinFilter();
3860 break;
3861 case GL_TEXTURE_WRAP_S:
3862 *params = (GLfloat)texture->getWrapS();
3863 break;
3864 case GL_TEXTURE_WRAP_T:
3865 *params = (GLfloat)texture->getWrapT();
3866 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003867 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3868 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3869 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003870 case GL_TEXTURE_USAGE_ANGLE:
3871 *params = (GLfloat)texture->getUsage();
3872 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00003873 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3874 if (!context->supportsTextureFilterAnisotropy())
3875 {
3876 return error(GL_INVALID_ENUM);
3877 }
3878 *params = (GLfloat)texture->getMaxAnisotropy();
3879 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003880 default:
3881 return error(GL_INVALID_ENUM);
3882 }
3883 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003884 }
3885 catch(std::bad_alloc&)
3886 {
3887 return error(GL_OUT_OF_MEMORY);
3888 }
3889}
3890
3891void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3892{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003893 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 +00003894
3895 try
3896 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003897 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003898
3899 if (context)
3900 {
3901 gl::Texture *texture;
3902
3903 switch (target)
3904 {
3905 case GL_TEXTURE_2D:
3906 texture = context->getTexture2D();
3907 break;
3908 case GL_TEXTURE_CUBE_MAP:
3909 texture = context->getTextureCubeMap();
3910 break;
3911 default:
3912 return error(GL_INVALID_ENUM);
3913 }
3914
3915 switch (pname)
3916 {
3917 case GL_TEXTURE_MAG_FILTER:
3918 *params = texture->getMagFilter();
3919 break;
3920 case GL_TEXTURE_MIN_FILTER:
3921 *params = texture->getMinFilter();
3922 break;
3923 case GL_TEXTURE_WRAP_S:
3924 *params = texture->getWrapS();
3925 break;
3926 case GL_TEXTURE_WRAP_T:
3927 *params = texture->getWrapT();
3928 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003929 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3930 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3931 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003932 case GL_TEXTURE_USAGE_ANGLE:
3933 *params = texture->getUsage();
3934 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00003935 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3936 if (!context->supportsTextureFilterAnisotropy())
3937 {
3938 return error(GL_INVALID_ENUM);
3939 }
3940 *params = (GLint)texture->getMaxAnisotropy();
3941 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003942 default:
3943 return error(GL_INVALID_ENUM);
3944 }
3945 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003946 }
3947 catch(std::bad_alloc&)
3948 {
3949 return error(GL_OUT_OF_MEMORY);
3950 }
3951}
3952
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003953void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3954{
3955 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3956 program, location, bufSize, params);
3957
3958 try
3959 {
3960 if (bufSize < 0)
3961 {
3962 return error(GL_INVALID_VALUE);
3963 }
3964
3965 gl::Context *context = gl::getNonLostContext();
3966
3967 if (context)
3968 {
3969 if (program == 0)
3970 {
3971 return error(GL_INVALID_VALUE);
3972 }
3973
3974 gl::Program *programObject = context->getProgram(program);
3975
daniel@transgaming.com716056c2012-07-24 18:38:59 +00003976 if (!programObject || !programObject->isLinked())
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003977 {
3978 return error(GL_INVALID_OPERATION);
3979 }
3980
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00003981 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
3982 if (!programBinary)
3983 {
3984 return error(GL_INVALID_OPERATION);
3985 }
3986
3987 if (!programBinary->getUniformfv(location, &bufSize, params))
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003988 {
3989 return error(GL_INVALID_OPERATION);
3990 }
3991 }
3992 }
3993 catch(std::bad_alloc&)
3994 {
3995 return error(GL_OUT_OF_MEMORY);
3996 }
3997}
3998
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003999void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
4000{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004001 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004002
4003 try
4004 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004005 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004006
4007 if (context)
4008 {
4009 if (program == 0)
4010 {
4011 return error(GL_INVALID_VALUE);
4012 }
4013
4014 gl::Program *programObject = context->getProgram(program);
4015
daniel@transgaming.com716056c2012-07-24 18:38:59 +00004016 if (!programObject || !programObject->isLinked())
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004017 {
4018 return error(GL_INVALID_OPERATION);
4019 }
4020
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004021 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4022 if (!programBinary)
4023 {
4024 return error(GL_INVALID_OPERATION);
4025 }
4026
4027 if (!programBinary->getUniformfv(location, NULL, params))
daniel@transgaming.com9a849122011-11-12 03:18:00 +00004028 {
4029 return error(GL_INVALID_OPERATION);
4030 }
4031 }
4032 }
4033 catch(std::bad_alloc&)
4034 {
4035 return error(GL_OUT_OF_MEMORY);
4036 }
4037}
4038
4039void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
4040{
4041 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
4042 program, location, bufSize, params);
4043
4044 try
4045 {
4046 if (bufSize < 0)
4047 {
4048 return error(GL_INVALID_VALUE);
4049 }
4050
4051 gl::Context *context = gl::getNonLostContext();
4052
4053 if (context)
4054 {
4055 if (program == 0)
4056 {
4057 return error(GL_INVALID_VALUE);
4058 }
4059
4060 gl::Program *programObject = context->getProgram(program);
4061
daniel@transgaming.com716056c2012-07-24 18:38:59 +00004062 if (!programObject || !programObject->isLinked())
daniel@transgaming.com9a849122011-11-12 03:18:00 +00004063 {
4064 return error(GL_INVALID_OPERATION);
4065 }
4066
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004067 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4068 if (!programBinary)
4069 {
4070 return error(GL_INVALID_OPERATION);
4071 }
4072
4073 if (!programBinary->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004074 {
4075 return error(GL_INVALID_OPERATION);
4076 }
4077 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004078 }
4079 catch(std::bad_alloc&)
4080 {
4081 return error(GL_OUT_OF_MEMORY);
4082 }
4083}
4084
4085void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
4086{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004087 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004088
4089 try
4090 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004091 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004092
4093 if (context)
4094 {
4095 if (program == 0)
4096 {
4097 return error(GL_INVALID_VALUE);
4098 }
4099
4100 gl::Program *programObject = context->getProgram(program);
4101
daniel@transgaming.com716056c2012-07-24 18:38:59 +00004102 if (!programObject || !programObject->isLinked())
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004103 {
4104 return error(GL_INVALID_OPERATION);
4105 }
4106
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004107 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
4108 if (!programBinary)
4109 {
4110 return error(GL_INVALID_OPERATION);
4111 }
4112
4113 if (!programBinary->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00004114 {
4115 return error(GL_INVALID_OPERATION);
4116 }
4117 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004118 }
4119 catch(std::bad_alloc&)
4120 {
4121 return error(GL_OUT_OF_MEMORY);
4122 }
4123}
4124
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004125int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004126{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004127 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004128
4129 try
4130 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004131 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004132
4133 if (strstr(name, "gl_") == name)
4134 {
4135 return -1;
4136 }
4137
4138 if (context)
4139 {
4140 gl::Program *programObject = context->getProgram(program);
4141
4142 if (!programObject)
4143 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00004144 if (context->getShader(program))
4145 {
4146 return error(GL_INVALID_OPERATION, -1);
4147 }
4148 else
4149 {
4150 return error(GL_INVALID_VALUE, -1);
4151 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004152 }
4153
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004154 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
daniel@transgaming.com716056c2012-07-24 18:38:59 +00004155 if (!programObject->isLinked() || !programBinary)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004156 {
4157 return error(GL_INVALID_OPERATION, -1);
4158 }
4159
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00004160 return programBinary->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004161 }
4162 }
4163 catch(std::bad_alloc&)
4164 {
4165 return error(GL_OUT_OF_MEMORY, -1);
4166 }
4167
4168 return -1;
4169}
4170
4171void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
4172{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004173 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004174
4175 try
4176 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004177 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004178
daniel@transgaming.come0078962010-04-15 20:45:08 +00004179 if (context)
4180 {
4181 if (index >= gl::MAX_VERTEX_ATTRIBS)
4182 {
4183 return error(GL_INVALID_VALUE);
4184 }
4185
daniel@transgaming.com83921382011-01-08 05:46:00 +00004186 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004187
daniel@transgaming.come0078962010-04-15 20:45:08 +00004188 switch (pname)
4189 {
4190 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004191 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004192 break;
4193 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004194 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004195 break;
4196 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004197 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004198 break;
4199 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004200 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004201 break;
4202 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004203 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004204 break;
4205 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004206 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004207 break;
4208 case GL_CURRENT_VERTEX_ATTRIB:
4209 for (int i = 0; i < 4; ++i)
4210 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004211 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004212 }
4213 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004214 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4215 *params = (GLfloat)attribState.mDivisor;
4216 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004217 default: return error(GL_INVALID_ENUM);
4218 }
4219 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004220 }
4221 catch(std::bad_alloc&)
4222 {
4223 return error(GL_OUT_OF_MEMORY);
4224 }
4225}
4226
4227void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
4228{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004229 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004230
4231 try
4232 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004233 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004234
daniel@transgaming.come0078962010-04-15 20:45:08 +00004235 if (context)
4236 {
4237 if (index >= gl::MAX_VERTEX_ATTRIBS)
4238 {
4239 return error(GL_INVALID_VALUE);
4240 }
4241
daniel@transgaming.com83921382011-01-08 05:46:00 +00004242 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004243
daniel@transgaming.come0078962010-04-15 20:45:08 +00004244 switch (pname)
4245 {
4246 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00004247 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004248 break;
4249 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004250 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004251 break;
4252 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004253 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004254 break;
4255 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004256 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004257 break;
4258 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004259 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00004260 break;
4261 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004262 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00004263 break;
4264 case GL_CURRENT_VERTEX_ATTRIB:
4265 for (int i = 0; i < 4; ++i)
4266 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004267 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00004268 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4269 }
4270 break;
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00004271 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
4272 *params = (GLint)attribState.mDivisor;
4273 break;
daniel@transgaming.come0078962010-04-15 20:45:08 +00004274 default: return error(GL_INVALID_ENUM);
4275 }
4276 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004277 }
4278 catch(std::bad_alloc&)
4279 {
4280 return error(GL_OUT_OF_MEMORY);
4281 }
4282}
4283
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004284void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004285{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004286 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004287
4288 try
4289 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004290 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004291
daniel@transgaming.come0078962010-04-15 20:45:08 +00004292 if (context)
4293 {
4294 if (index >= gl::MAX_VERTEX_ATTRIBS)
4295 {
4296 return error(GL_INVALID_VALUE);
4297 }
4298
4299 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4300 {
4301 return error(GL_INVALID_ENUM);
4302 }
4303
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004304 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00004305 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004306 }
4307 catch(std::bad_alloc&)
4308 {
4309 return error(GL_OUT_OF_MEMORY);
4310 }
4311}
4312
4313void __stdcall glHint(GLenum target, GLenum mode)
4314{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004315 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004316
4317 try
4318 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004319 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004320 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004321 case GL_FASTEST:
4322 case GL_NICEST:
4323 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004324 break;
4325 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004326 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004327 }
4328
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004329 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004330 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004331 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00004332 case GL_GENERATE_MIPMAP_HINT:
4333 if (context) context->setGenerateMipmapHint(mode);
4334 break;
4335 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4336 if (context) context->setFragmentShaderDerivativeHint(mode);
4337 break;
4338 default:
4339 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00004340 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004341 }
4342 catch(std::bad_alloc&)
4343 {
4344 return error(GL_OUT_OF_MEMORY);
4345 }
4346}
4347
4348GLboolean __stdcall glIsBuffer(GLuint buffer)
4349{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004350 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004351
4352 try
4353 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004354 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004355
4356 if (context && buffer)
4357 {
4358 gl::Buffer *bufferObject = context->getBuffer(buffer);
4359
4360 if (bufferObject)
4361 {
4362 return GL_TRUE;
4363 }
4364 }
4365 }
4366 catch(std::bad_alloc&)
4367 {
4368 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4369 }
4370
4371 return GL_FALSE;
4372}
4373
4374GLboolean __stdcall glIsEnabled(GLenum cap)
4375{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004376 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004377
4378 try
4379 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004380 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004381
4382 if (context)
4383 {
4384 switch (cap)
4385 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004386 case GL_CULL_FACE: return context->isCullFaceEnabled();
4387 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
4388 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4389 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
4390 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
4391 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
4392 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
4393 case GL_BLEND: return context->isBlendEnabled();
4394 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004395 default:
4396 return error(GL_INVALID_ENUM, false);
4397 }
4398 }
4399 }
4400 catch(std::bad_alloc&)
4401 {
4402 return error(GL_OUT_OF_MEMORY, false);
4403 }
4404
4405 return false;
4406}
4407
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004408GLboolean __stdcall glIsFenceNV(GLuint fence)
4409{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004410 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004411
4412 try
4413 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004414 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004415
4416 if (context)
4417 {
4418 gl::Fence *fenceObject = context->getFence(fence);
4419
4420 if (fenceObject == NULL)
4421 {
4422 return GL_FALSE;
4423 }
4424
4425 return fenceObject->isFence();
4426 }
4427 }
4428 catch(std::bad_alloc&)
4429 {
4430 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4431 }
4432
4433 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004434}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004435
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004436GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
4437{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004438 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004439
4440 try
4441 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004442 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004443
4444 if (context && framebuffer)
4445 {
4446 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4447
4448 if (framebufferObject)
4449 {
4450 return GL_TRUE;
4451 }
4452 }
4453 }
4454 catch(std::bad_alloc&)
4455 {
4456 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4457 }
4458
4459 return GL_FALSE;
4460}
4461
4462GLboolean __stdcall glIsProgram(GLuint program)
4463{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004464 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004465
4466 try
4467 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004468 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004469
4470 if (context && program)
4471 {
4472 gl::Program *programObject = context->getProgram(program);
4473
4474 if (programObject)
4475 {
4476 return GL_TRUE;
4477 }
4478 }
4479 }
4480 catch(std::bad_alloc&)
4481 {
4482 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4483 }
4484
4485 return GL_FALSE;
4486}
4487
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00004488GLboolean __stdcall glIsQueryEXT(GLuint id)
4489{
4490 EVENT("(GLuint id = %d)", id);
4491
4492 try
4493 {
4494 if (id == 0)
4495 {
4496 return GL_FALSE;
4497 }
4498
4499 gl::Context *context = gl::getNonLostContext();
4500
4501 if (context)
4502 {
4503 gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
4504
4505 if (queryObject)
4506 {
4507 return GL_TRUE;
4508 }
4509 }
4510 }
4511 catch(std::bad_alloc&)
4512 {
4513 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4514 }
4515
4516 return GL_FALSE;
4517}
4518
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004519GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
4520{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004521 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004522
4523 try
4524 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004525 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004526
4527 if (context && renderbuffer)
4528 {
4529 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4530
4531 if (renderbufferObject)
4532 {
4533 return GL_TRUE;
4534 }
4535 }
4536 }
4537 catch(std::bad_alloc&)
4538 {
4539 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4540 }
4541
4542 return GL_FALSE;
4543}
4544
4545GLboolean __stdcall glIsShader(GLuint shader)
4546{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004547 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004548
4549 try
4550 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004551 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004552
4553 if (context && shader)
4554 {
4555 gl::Shader *shaderObject = context->getShader(shader);
4556
4557 if (shaderObject)
4558 {
4559 return GL_TRUE;
4560 }
4561 }
4562 }
4563 catch(std::bad_alloc&)
4564 {
4565 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4566 }
4567
4568 return GL_FALSE;
4569}
4570
4571GLboolean __stdcall glIsTexture(GLuint texture)
4572{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004573 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004574
4575 try
4576 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004577 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004578
4579 if (context && texture)
4580 {
4581 gl::Texture *textureObject = context->getTexture(texture);
4582
4583 if (textureObject)
4584 {
4585 return GL_TRUE;
4586 }
4587 }
4588 }
4589 catch(std::bad_alloc&)
4590 {
4591 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4592 }
4593
4594 return GL_FALSE;
4595}
4596
4597void __stdcall glLineWidth(GLfloat width)
4598{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004599 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004600
4601 try
4602 {
4603 if (width <= 0.0f)
4604 {
4605 return error(GL_INVALID_VALUE);
4606 }
4607
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004608 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004609
4610 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004611 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004612 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004613 }
4614 }
4615 catch(std::bad_alloc&)
4616 {
4617 return error(GL_OUT_OF_MEMORY);
4618 }
4619}
4620
4621void __stdcall glLinkProgram(GLuint program)
4622{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004623 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004624
4625 try
4626 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004627 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004628
4629 if (context)
4630 {
4631 gl::Program *programObject = context->getProgram(program);
4632
4633 if (!programObject)
4634 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004635 if (context->getShader(program))
4636 {
4637 return error(GL_INVALID_OPERATION);
4638 }
4639 else
4640 {
4641 return error(GL_INVALID_VALUE);
4642 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004643 }
4644
daniel@transgaming.com95d29422012-07-24 18:36:10 +00004645 context->linkProgram(program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004646 }
4647 }
4648 catch(std::bad_alloc&)
4649 {
4650 return error(GL_OUT_OF_MEMORY);
4651 }
4652}
4653
4654void __stdcall glPixelStorei(GLenum pname, GLint param)
4655{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004656 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004657
4658 try
4659 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004660 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004661
4662 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004663 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004664 switch (pname)
4665 {
4666 case GL_UNPACK_ALIGNMENT:
4667 if (param != 1 && param != 2 && param != 4 && param != 8)
4668 {
4669 return error(GL_INVALID_VALUE);
4670 }
4671
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004672 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004673 break;
4674
4675 case GL_PACK_ALIGNMENT:
4676 if (param != 1 && param != 2 && param != 4 && param != 8)
4677 {
4678 return error(GL_INVALID_VALUE);
4679 }
4680
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004681 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004682 break;
4683
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004684 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4685 context->setPackReverseRowOrder(param != 0);
4686 break;
4687
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004688 default:
4689 return error(GL_INVALID_ENUM);
4690 }
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
4699void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4700{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004701 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004702
4703 try
4704 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004705 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004706
4707 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004708 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004709 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004710 }
4711 }
4712 catch(std::bad_alloc&)
4713 {
4714 return error(GL_OUT_OF_MEMORY);
4715 }
4716}
4717
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004718void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4719 GLenum format, GLenum type, GLsizei bufSize,
4720 GLvoid *data)
4721{
4722 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4723 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4724 x, y, width, height, format, type, bufSize, data);
4725
4726 try
4727 {
4728 if (width < 0 || height < 0 || bufSize < 0)
4729 {
4730 return error(GL_INVALID_VALUE);
4731 }
4732
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004733 gl::Context *context = gl::getNonLostContext();
4734
4735 if (context)
4736 {
daniel@transgaming.com42944b02012-09-27 17:45:57 +00004737 GLenum currentFormat, currentType;
4738
4739 // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound,
4740 // and attempting to read back if that's the case is an error. The error will be registered
4741 // by getCurrentReadFormat.
4742 if (!context->getCurrentReadFormatType(&currentFormat, &currentType))
4743 return;
4744
4745 if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type))
4746 {
4747 return error(GL_INVALID_OPERATION);
4748 }
4749
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004750 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4751 }
4752 }
4753 catch(std::bad_alloc&)
4754 {
4755 return error(GL_OUT_OF_MEMORY);
4756 }
4757}
4758
4759void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4760 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004761{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004762 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004763 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004764 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004765
4766 try
4767 {
4768 if (width < 0 || height < 0)
4769 {
4770 return error(GL_INVALID_VALUE);
4771 }
4772
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004773 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004774
4775 if (context)
4776 {
daniel@transgaming.com42944b02012-09-27 17:45:57 +00004777 GLenum currentFormat, currentType;
4778
4779 // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound,
4780 // and attempting to read back if that's the case is an error. The error will be registered
4781 // by getCurrentReadFormat.
4782 if (!context->getCurrentReadFormatType(&currentFormat, &currentType))
4783 return;
4784
4785 if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type))
4786 {
4787 return error(GL_INVALID_OPERATION);
4788 }
4789
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004790 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004791 }
4792 }
4793 catch(std::bad_alloc&)
4794 {
4795 return error(GL_OUT_OF_MEMORY);
4796 }
4797}
4798
4799void __stdcall glReleaseShaderCompiler(void)
4800{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004801 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004802
4803 try
4804 {
4805 gl::Shader::releaseCompiler();
4806 }
4807 catch(std::bad_alloc&)
4808 {
4809 return error(GL_OUT_OF_MEMORY);
4810 }
4811}
4812
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004813void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004814{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004815 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 +00004816 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004817
4818 try
4819 {
4820 switch (target)
4821 {
4822 case GL_RENDERBUFFER:
4823 break;
4824 default:
4825 return error(GL_INVALID_ENUM);
4826 }
4827
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004828 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004829 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004830 return error(GL_INVALID_ENUM);
4831 }
4832
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004833 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004834 {
4835 return error(GL_INVALID_VALUE);
4836 }
4837
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004838 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004839
4840 if (context)
4841 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004842 if (width > context->getMaximumRenderbufferDimension() ||
4843 height > context->getMaximumRenderbufferDimension() ||
4844 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004845 {
4846 return error(GL_INVALID_VALUE);
4847 }
4848
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004849 GLuint handle = context->getRenderbufferHandle();
4850 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004851 {
4852 return error(GL_INVALID_OPERATION);
4853 }
4854
4855 switch (internalformat)
4856 {
4857 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004858 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004859 break;
4860 case GL_RGBA4:
4861 case GL_RGB5_A1:
4862 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004863 case GL_RGB8_OES:
4864 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004865 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004866 break;
4867 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004868 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004869 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004870 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004871 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004872 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004873 default:
4874 return error(GL_INVALID_ENUM);
4875 }
4876 }
4877 }
4878 catch(std::bad_alloc&)
4879 {
4880 return error(GL_OUT_OF_MEMORY);
4881 }
4882}
4883
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004884void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4885{
4886 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4887}
4888
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004889void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4890{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004891 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004892
4893 try
4894 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004895 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004896
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004897 if (context)
4898 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004899 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004900 }
4901 }
4902 catch(std::bad_alloc&)
4903 {
4904 return error(GL_OUT_OF_MEMORY);
4905 }
4906}
4907
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004908void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4909{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004910 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004911
4912 try
4913 {
4914 if (condition != GL_ALL_COMPLETED_NV)
4915 {
4916 return error(GL_INVALID_ENUM);
4917 }
4918
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004919 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004920
4921 if (context)
4922 {
4923 gl::Fence *fenceObject = context->getFence(fence);
4924
4925 if (fenceObject == NULL)
4926 {
4927 return error(GL_INVALID_OPERATION);
4928 }
4929
4930 fenceObject->setFence(condition);
4931 }
4932 }
4933 catch(std::bad_alloc&)
4934 {
4935 return error(GL_OUT_OF_MEMORY);
4936 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004937}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004938
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004939void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4940{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004941 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 +00004942
4943 try
4944 {
4945 if (width < 0 || height < 0)
4946 {
4947 return error(GL_INVALID_VALUE);
4948 }
4949
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004950 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004951
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004952 if (context)
4953 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004954 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004955 }
4956 }
4957 catch(std::bad_alloc&)
4958 {
4959 return error(GL_OUT_OF_MEMORY);
4960 }
4961}
4962
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004963void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004964{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004965 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004966 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004967 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004968
4969 try
4970 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004971 // No binary shader formats are supported.
4972 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004973 }
4974 catch(std::bad_alloc&)
4975 {
4976 return error(GL_OUT_OF_MEMORY);
4977 }
4978}
4979
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004980void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004981{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004982 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 +00004983 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004984
4985 try
4986 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004987 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004988 {
4989 return error(GL_INVALID_VALUE);
4990 }
4991
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004992 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004993
4994 if (context)
4995 {
4996 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004997
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004998 if (!shaderObject)
4999 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00005000 if (context->getProgram(shader))
5001 {
5002 return error(GL_INVALID_OPERATION);
5003 }
5004 else
5005 {
5006 return error(GL_INVALID_VALUE);
5007 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005008 }
5009
5010 shaderObject->setSource(count, string, length);
5011 }
5012 }
5013 catch(std::bad_alloc&)
5014 {
5015 return error(GL_OUT_OF_MEMORY);
5016 }
5017}
5018
5019void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
5020{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005021 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005022}
5023
5024void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
5025{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005026 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 +00005027
5028 try
5029 {
5030 switch (face)
5031 {
5032 case GL_FRONT:
5033 case GL_BACK:
5034 case GL_FRONT_AND_BACK:
5035 break;
5036 default:
5037 return error(GL_INVALID_ENUM);
5038 }
5039
5040 switch (func)
5041 {
5042 case GL_NEVER:
5043 case GL_ALWAYS:
5044 case GL_LESS:
5045 case GL_LEQUAL:
5046 case GL_EQUAL:
5047 case GL_GEQUAL:
5048 case GL_GREATER:
5049 case GL_NOTEQUAL:
5050 break;
5051 default:
5052 return error(GL_INVALID_ENUM);
5053 }
5054
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005055 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005056
5057 if (context)
5058 {
5059 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5060 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005061 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005062 }
5063
5064 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5065 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005066 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005067 }
5068 }
5069 }
5070 catch(std::bad_alloc&)
5071 {
5072 return error(GL_OUT_OF_MEMORY);
5073 }
5074}
5075
5076void __stdcall glStencilMask(GLuint mask)
5077{
5078 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
5079}
5080
5081void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
5082{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005083 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005084
5085 try
5086 {
5087 switch (face)
5088 {
5089 case GL_FRONT:
5090 case GL_BACK:
5091 case GL_FRONT_AND_BACK:
5092 break;
5093 default:
5094 return error(GL_INVALID_ENUM);
5095 }
5096
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005097 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005098
5099 if (context)
5100 {
5101 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5102 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005103 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005104 }
5105
5106 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5107 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005108 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005109 }
5110 }
5111 }
5112 catch(std::bad_alloc&)
5113 {
5114 return error(GL_OUT_OF_MEMORY);
5115 }
5116}
5117
5118void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
5119{
5120 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
5121}
5122
5123void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
5124{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005125 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 +00005126 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005127
5128 try
5129 {
5130 switch (face)
5131 {
5132 case GL_FRONT:
5133 case GL_BACK:
5134 case GL_FRONT_AND_BACK:
5135 break;
5136 default:
5137 return error(GL_INVALID_ENUM);
5138 }
5139
5140 switch (fail)
5141 {
5142 case GL_ZERO:
5143 case GL_KEEP:
5144 case GL_REPLACE:
5145 case GL_INCR:
5146 case GL_DECR:
5147 case GL_INVERT:
5148 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005149 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005150 break;
5151 default:
5152 return error(GL_INVALID_ENUM);
5153 }
5154
5155 switch (zfail)
5156 {
5157 case GL_ZERO:
5158 case GL_KEEP:
5159 case GL_REPLACE:
5160 case GL_INCR:
5161 case GL_DECR:
5162 case GL_INVERT:
5163 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005164 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005165 break;
5166 default:
5167 return error(GL_INVALID_ENUM);
5168 }
5169
5170 switch (zpass)
5171 {
5172 case GL_ZERO:
5173 case GL_KEEP:
5174 case GL_REPLACE:
5175 case GL_INCR:
5176 case GL_DECR:
5177 case GL_INVERT:
5178 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005179 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005180 break;
5181 default:
5182 return error(GL_INVALID_ENUM);
5183 }
5184
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005185 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005186
5187 if (context)
5188 {
5189 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
5190 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005191 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005192 }
5193
5194 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
5195 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005196 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005197 }
5198 }
5199 }
5200 catch(std::bad_alloc&)
5201 {
5202 return error(GL_OUT_OF_MEMORY);
5203 }
5204}
5205
daniel@transgaming.comfe208882010-09-01 15:47:57 +00005206GLboolean __stdcall glTestFenceNV(GLuint fence)
5207{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005208 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005209
5210 try
5211 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005212 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005213
5214 if (context)
5215 {
5216 gl::Fence *fenceObject = context->getFence(fence);
5217
5218 if (fenceObject == NULL)
5219 {
5220 return error(GL_INVALID_OPERATION, GL_TRUE);
5221 }
5222
5223 return fenceObject->testFence();
5224 }
5225 }
5226 catch(std::bad_alloc&)
5227 {
5228 error(GL_OUT_OF_MEMORY);
5229 }
5230
5231 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00005232}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005233
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005234void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
5235 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005236{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005237 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 +00005238 "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 +00005239 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005240
5241 try
5242 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00005243 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005244 {
5245 return error(GL_INVALID_VALUE);
5246 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00005247
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +00005248 if (internalformat != GLint(format))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005249 {
5250 return error(GL_INVALID_OPERATION);
5251 }
5252
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005253 // validate <type> by itself (used as secondary key below)
5254 switch (type)
5255 {
5256 case GL_UNSIGNED_BYTE:
5257 case GL_UNSIGNED_SHORT_5_6_5:
5258 case GL_UNSIGNED_SHORT_4_4_4_4:
5259 case GL_UNSIGNED_SHORT_5_5_5_1:
5260 case GL_UNSIGNED_SHORT:
5261 case GL_UNSIGNED_INT:
5262 case GL_UNSIGNED_INT_24_8_OES:
5263 case GL_HALF_FLOAT_OES:
5264 case GL_FLOAT:
5265 break;
5266 default:
5267 return error(GL_INVALID_ENUM);
5268 }
5269
5270 // validate <format> + <type> combinations
5271 // - invalid <format> -> sets INVALID_ENUM
5272 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005273 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005274 {
5275 case GL_ALPHA:
5276 case GL_LUMINANCE:
5277 case GL_LUMINANCE_ALPHA:
5278 switch (type)
5279 {
5280 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005281 case GL_FLOAT:
5282 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005283 break;
5284 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005285 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005286 }
5287 break;
5288 case GL_RGB:
5289 switch (type)
5290 {
5291 case GL_UNSIGNED_BYTE:
5292 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005293 case GL_FLOAT:
5294 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005295 break;
5296 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005297 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005298 }
5299 break;
5300 case GL_RGBA:
5301 switch (type)
5302 {
5303 case GL_UNSIGNED_BYTE:
5304 case GL_UNSIGNED_SHORT_4_4_4_4:
5305 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005306 case GL_FLOAT:
5307 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005308 break;
5309 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005310 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005311 }
5312 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005313 case GL_BGRA_EXT:
5314 switch (type)
5315 {
5316 case GL_UNSIGNED_BYTE:
5317 break;
5318 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005319 return error(GL_INVALID_OPERATION);
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00005320 }
5321 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005322 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
5323 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00005324 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5325 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00005326 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005327 case GL_DEPTH_COMPONENT:
5328 switch (type)
5329 {
5330 case GL_UNSIGNED_SHORT:
5331 case GL_UNSIGNED_INT:
5332 break;
5333 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005334 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005335 }
5336 break;
5337 case GL_DEPTH_STENCIL_OES:
5338 switch (type)
5339 {
5340 case GL_UNSIGNED_INT_24_8_OES:
5341 break;
5342 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005343 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005344 }
5345 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005346 default:
daniel@transgaming.com6377e362012-06-05 19:49:55 +00005347 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005348 }
5349
5350 if (border != 0)
5351 {
5352 return error(GL_INVALID_VALUE);
5353 }
5354
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005355 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005356
5357 if (context)
5358 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00005359 if (level > context->getMaximumTextureLevel())
5360 {
5361 return error(GL_INVALID_VALUE);
5362 }
5363
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005364 switch (target)
5365 {
5366 case GL_TEXTURE_2D:
5367 if (width > (context->getMaximumTextureDimension() >> level) ||
5368 height > (context->getMaximumTextureDimension() >> level))
5369 {
5370 return error(GL_INVALID_VALUE);
5371 }
5372 break;
5373 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5374 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5375 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5376 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5377 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5378 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5379 if (width != height)
5380 {
5381 return error(GL_INVALID_VALUE);
5382 }
5383
5384 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
5385 height > (context->getMaximumCubeTextureDimension() >> level))
5386 {
5387 return error(GL_INVALID_VALUE);
5388 }
5389 break;
5390 default:
5391 return error(GL_INVALID_ENUM);
5392 }
5393
gman@chromium.org50c526d2011-08-10 05:19:44 +00005394 switch (format) {
5395 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5396 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5397 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00005398 {
5399 return error(GL_INVALID_OPERATION);
5400 }
5401 else
5402 {
5403 return error(GL_INVALID_ENUM);
5404 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00005405 break;
5406 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5407 if (context->supportsDXT3Textures())
5408 {
5409 return error(GL_INVALID_OPERATION);
5410 }
5411 else
5412 {
5413 return error(GL_INVALID_ENUM);
5414 }
5415 break;
5416 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5417 if (context->supportsDXT5Textures())
5418 {
5419 return error(GL_INVALID_OPERATION);
5420 }
5421 else
5422 {
5423 return error(GL_INVALID_ENUM);
5424 }
5425 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005426 case GL_DEPTH_COMPONENT:
5427 case GL_DEPTH_STENCIL_OES:
5428 if (!context->supportsDepthTextures())
5429 {
5430 return error(GL_INVALID_VALUE);
5431 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005432 if (target != GL_TEXTURE_2D)
5433 {
5434 return error(GL_INVALID_OPERATION);
5435 }
daniel@transgaming.com797924b2012-06-05 19:50:01 +00005436 // OES_depth_texture supports loading depth data and multiple levels,
5437 // but ANGLE_depth_texture does not
5438 if (pixels != NULL || level != 0)
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005439 {
5440 return error(GL_INVALID_OPERATION);
5441 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005442 break;
gman@chromium.org50c526d2011-08-10 05:19:44 +00005443 default:
5444 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00005445 }
5446
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005447 if (type == GL_FLOAT)
5448 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005449 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005450 {
5451 return error(GL_INVALID_ENUM);
5452 }
5453 }
5454 else if (type == GL_HALF_FLOAT_OES)
5455 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005456 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005457 {
5458 return error(GL_INVALID_ENUM);
5459 }
5460 }
5461
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005462 if (target == GL_TEXTURE_2D)
5463 {
5464 gl::Texture2D *texture = context->getTexture2D();
5465
5466 if (!texture)
5467 {
5468 return error(GL_INVALID_OPERATION);
5469 }
5470
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005471 if (texture->isImmutable())
5472 {
5473 return error(GL_INVALID_OPERATION);
5474 }
5475
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005476 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005477 }
5478 else
5479 {
5480 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5481
5482 if (!texture)
5483 {
5484 return error(GL_INVALID_OPERATION);
5485 }
5486
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005487 if (texture->isImmutable())
5488 {
5489 return error(GL_INVALID_OPERATION);
5490 }
5491
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005492 switch (target)
5493 {
5494 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005495 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005496 break;
5497 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005498 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005499 break;
5500 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005501 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005502 break;
5503 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005504 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005505 break;
5506 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005507 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005508 break;
5509 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00005510 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005511 break;
5512 default: UNREACHABLE();
5513 }
5514 }
5515 }
5516 }
5517 catch(std::bad_alloc&)
5518 {
5519 return error(GL_OUT_OF_MEMORY);
5520 }
5521}
5522
5523void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
5524{
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00005525 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param);
5526
5527 try
5528 {
5529 gl::Context *context = gl::getNonLostContext();
5530
5531 if (context)
5532 {
5533 gl::Texture *texture;
5534
5535 switch (target)
5536 {
5537 case GL_TEXTURE_2D:
5538 texture = context->getTexture2D();
5539 break;
5540 case GL_TEXTURE_CUBE_MAP:
5541 texture = context->getTextureCubeMap();
5542 break;
5543 default:
5544 return error(GL_INVALID_ENUM);
5545 }
5546
5547 switch (pname)
5548 {
5549 case GL_TEXTURE_WRAP_S:
5550 if (!texture->setWrapS((GLenum)param))
5551 {
5552 return error(GL_INVALID_ENUM);
5553 }
5554 break;
5555 case GL_TEXTURE_WRAP_T:
5556 if (!texture->setWrapT((GLenum)param))
5557 {
5558 return error(GL_INVALID_ENUM);
5559 }
5560 break;
5561 case GL_TEXTURE_MIN_FILTER:
5562 if (!texture->setMinFilter((GLenum)param))
5563 {
5564 return error(GL_INVALID_ENUM);
5565 }
5566 break;
5567 case GL_TEXTURE_MAG_FILTER:
5568 if (!texture->setMagFilter((GLenum)param))
5569 {
5570 return error(GL_INVALID_ENUM);
5571 }
5572 break;
5573 case GL_TEXTURE_USAGE_ANGLE:
5574 if (!texture->setUsage((GLenum)param))
5575 {
5576 return error(GL_INVALID_ENUM);
5577 }
5578 break;
5579 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5580 if (!context->supportsTextureFilterAnisotropy())
5581 {
5582 return error(GL_INVALID_ENUM);
5583 }
5584 if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()))
5585 {
5586 return error(GL_INVALID_VALUE);
5587 }
5588 break;
5589 default:
5590 return error(GL_INVALID_ENUM);
5591 }
5592 }
5593 }
5594 catch(std::bad_alloc&)
5595 {
5596 return error(GL_OUT_OF_MEMORY);
5597 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005598}
5599
5600void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5601{
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00005602 glTexParameterf(target, pname, (GLfloat)*params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005603}
5604
5605void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
5606{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005607 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005608
5609 try
5610 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005611 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005612
5613 if (context)
5614 {
5615 gl::Texture *texture;
5616
5617 switch (target)
5618 {
5619 case GL_TEXTURE_2D:
5620 texture = context->getTexture2D();
5621 break;
5622 case GL_TEXTURE_CUBE_MAP:
5623 texture = context->getTextureCubeMap();
5624 break;
5625 default:
5626 return error(GL_INVALID_ENUM);
5627 }
5628
5629 switch (pname)
5630 {
5631 case GL_TEXTURE_WRAP_S:
5632 if (!texture->setWrapS((GLenum)param))
5633 {
5634 return error(GL_INVALID_ENUM);
5635 }
5636 break;
5637 case GL_TEXTURE_WRAP_T:
5638 if (!texture->setWrapT((GLenum)param))
5639 {
5640 return error(GL_INVALID_ENUM);
5641 }
5642 break;
5643 case GL_TEXTURE_MIN_FILTER:
5644 if (!texture->setMinFilter((GLenum)param))
5645 {
5646 return error(GL_INVALID_ENUM);
5647 }
5648 break;
5649 case GL_TEXTURE_MAG_FILTER:
5650 if (!texture->setMagFilter((GLenum)param))
5651 {
5652 return error(GL_INVALID_ENUM);
5653 }
5654 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00005655 case GL_TEXTURE_USAGE_ANGLE:
5656 if (!texture->setUsage((GLenum)param))
5657 {
5658 return error(GL_INVALID_ENUM);
5659 }
5660 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00005661 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5662 if (!context->supportsTextureFilterAnisotropy())
5663 {
5664 return error(GL_INVALID_ENUM);
5665 }
5666 if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()))
5667 {
5668 return error(GL_INVALID_VALUE);
5669 }
5670 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005671 default:
5672 return error(GL_INVALID_ENUM);
5673 }
5674 }
5675 }
5676 catch(std::bad_alloc&)
5677 {
5678 return error(GL_OUT_OF_MEMORY);
5679 }
5680}
5681
5682void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5683{
5684 glTexParameteri(target, pname, *params);
5685}
5686
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005687void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5688{
5689 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5690 target, levels, internalformat, width, height);
5691
5692 try
5693 {
5694 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5695 {
5696 return error(GL_INVALID_ENUM);
5697 }
5698
5699 if (width < 1 || height < 1 || levels < 1)
5700 {
5701 return error(GL_INVALID_VALUE);
5702 }
5703
5704 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5705 {
5706 return error(GL_INVALID_VALUE);
5707 }
5708
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005709 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005710 {
5711 return error(GL_INVALID_OPERATION);
5712 }
5713
5714 GLenum format = gl::ExtractFormat(internalformat);
5715 GLenum type = gl::ExtractType(internalformat);
5716
5717 if (format == GL_NONE || type == GL_NONE)
5718 {
5719 return error(GL_INVALID_ENUM);
5720 }
5721
5722 gl::Context *context = gl::getNonLostContext();
5723
5724 if (context)
5725 {
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005726 switch (target)
5727 {
5728 case GL_TEXTURE_2D:
5729 if (width > context->getMaximumTextureDimension() ||
5730 height > context->getMaximumTextureDimension())
5731 {
5732 return error(GL_INVALID_VALUE);
5733 }
5734 break;
5735 case GL_TEXTURE_CUBE_MAP:
5736 if (width > context->getMaximumCubeTextureDimension() ||
5737 height > context->getMaximumCubeTextureDimension())
5738 {
5739 return error(GL_INVALID_VALUE);
5740 }
5741 break;
5742 default:
5743 return error(GL_INVALID_ENUM);
5744 }
5745
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005746 if (levels != 1 && !context->supportsNonPower2Texture())
5747 {
5748 if (!gl::isPow2(width) || !gl::isPow2(height))
5749 {
5750 return error(GL_INVALID_OPERATION);
5751 }
5752 }
5753
daniel@transgaming.come1077362011-11-11 04:16:50 +00005754 switch (internalformat)
5755 {
5756 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5757 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5758 if (!context->supportsDXT1Textures())
5759 {
5760 return error(GL_INVALID_ENUM);
5761 }
5762 break;
5763 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5764 if (!context->supportsDXT3Textures())
5765 {
5766 return error(GL_INVALID_ENUM);
5767 }
5768 break;
5769 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5770 if (!context->supportsDXT5Textures())
5771 {
5772 return error(GL_INVALID_ENUM);
5773 }
5774 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005775 case GL_RGBA32F_EXT:
5776 case GL_RGB32F_EXT:
5777 case GL_ALPHA32F_EXT:
5778 case GL_LUMINANCE32F_EXT:
5779 case GL_LUMINANCE_ALPHA32F_EXT:
5780 if (!context->supportsFloat32Textures())
5781 {
5782 return error(GL_INVALID_ENUM);
5783 }
5784 break;
5785 case GL_RGBA16F_EXT:
5786 case GL_RGB16F_EXT:
5787 case GL_ALPHA16F_EXT:
5788 case GL_LUMINANCE16F_EXT:
5789 case GL_LUMINANCE_ALPHA16F_EXT:
5790 if (!context->supportsFloat16Textures())
5791 {
5792 return error(GL_INVALID_ENUM);
5793 }
5794 break;
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005795 case GL_DEPTH_COMPONENT16:
5796 case GL_DEPTH_COMPONENT32_OES:
5797 case GL_DEPTH24_STENCIL8_OES:
5798 if (!context->supportsDepthTextures())
5799 {
5800 return error(GL_INVALID_ENUM);
5801 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005802 if (target != GL_TEXTURE_2D)
5803 {
5804 return error(GL_INVALID_OPERATION);
5805 }
daniel@transgaming.com797924b2012-06-05 19:50:01 +00005806 // ANGLE_depth_texture only supports 1-level textures
5807 if (levels != 1)
5808 {
5809 return error(GL_INVALID_OPERATION);
5810 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005811 break;
5812 default:
5813 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005814 }
5815
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005816 if (target == GL_TEXTURE_2D)
5817 {
5818 gl::Texture2D *texture = context->getTexture2D();
5819
5820 if (!texture || texture->id() == 0)
5821 {
5822 return error(GL_INVALID_OPERATION);
5823 }
5824
5825 if (texture->isImmutable())
5826 {
5827 return error(GL_INVALID_OPERATION);
5828 }
5829
5830 texture->storage(levels, internalformat, width, height);
5831 }
5832 else if (target == GL_TEXTURE_CUBE_MAP)
5833 {
5834 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5835
5836 if (!texture || texture->id() == 0)
5837 {
5838 return error(GL_INVALID_OPERATION);
5839 }
5840
5841 if (texture->isImmutable())
5842 {
5843 return error(GL_INVALID_OPERATION);
5844 }
5845
5846 texture->storage(levels, internalformat, width);
5847 }
5848 else UNREACHABLE();
5849 }
5850 }
5851 catch(std::bad_alloc&)
5852 {
5853 return error(GL_OUT_OF_MEMORY);
5854 }
5855}
5856
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005857void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5858 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005859{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005860 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005861 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005862 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005863 target, level, xoffset, yoffset, width, height, format, type, pixels);
5864
5865 try
5866 {
apatrick@chromium.org551022e2012-01-23 19:56:54 +00005867 if (!gl::IsInternalTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005868 {
5869 return error(GL_INVALID_ENUM);
5870 }
5871
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005872 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005873 {
5874 return error(GL_INVALID_VALUE);
5875 }
5876
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005877 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5878 {
5879 return error(GL_INVALID_VALUE);
5880 }
5881
daniel@transgaming.com8833dd22012-06-05 19:49:58 +00005882 if (!checkTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005883 {
daniel@transgaming.com8833dd22012-06-05 19:49:58 +00005884 return; // error is set by helper function
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005885 }
5886
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005887 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005888
5889 if (context)
5890 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005891 if (level > context->getMaximumTextureLevel())
5892 {
5893 return error(GL_INVALID_VALUE);
5894 }
5895
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005896 if (format == GL_FLOAT)
5897 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005898 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005899 {
5900 return error(GL_INVALID_ENUM);
5901 }
5902 }
5903 else if (format == GL_HALF_FLOAT_OES)
5904 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005905 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005906 {
5907 return error(GL_INVALID_ENUM);
5908 }
5909 }
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005910 else if (gl::IsDepthTexture(format))
5911 {
5912 if (!context->supportsDepthTextures())
5913 {
5914 return error(GL_INVALID_ENUM);
5915 }
daniel@transgaming.com0c854682012-05-31 01:14:11 +00005916 if (target != GL_TEXTURE_2D)
5917 {
5918 return error(GL_INVALID_OPERATION);
5919 }
5920 // OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not
5921 return error(GL_INVALID_OPERATION);
daniel@transgaming.com835a95a2012-05-31 01:14:07 +00005922 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005923
daniel@transgaming.com1d2d3c42012-05-31 01:14:15 +00005924 if (width == 0 || height == 0 || pixels == NULL)
5925 {
5926 return;
5927 }
5928
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005929 if (target == GL_TEXTURE_2D)
5930 {
5931 gl::Texture2D *texture = context->getTexture2D();
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00005932 if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, type, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005933 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005934 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005935 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005936 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005937 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005938 {
5939 gl::TextureCubeMap *texture = context->getTextureCubeMap();
daniel@transgaming.com6452adf2012-10-17 18:22:35 +00005940 if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, type, texture))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005941 {
daniel@transgaming.com343373a2011-11-29 19:42:32 +00005942 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005943 }
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005944 }
5945 else
5946 {
5947 UNREACHABLE();
5948 }
5949 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005950 }
5951 catch(std::bad_alloc&)
5952 {
5953 return error(GL_OUT_OF_MEMORY);
5954 }
5955}
5956
5957void __stdcall glUniform1f(GLint location, GLfloat x)
5958{
5959 glUniform1fv(location, 1, &x);
5960}
5961
5962void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5963{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005964 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005965
5966 try
5967 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005968 if (count < 0)
5969 {
5970 return error(GL_INVALID_VALUE);
5971 }
5972
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005973 if (location == -1)
5974 {
5975 return;
5976 }
5977
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005978 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005979
5980 if (context)
5981 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00005982 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00005983 if (!programBinary)
5984 {
5985 return error(GL_INVALID_OPERATION);
5986 }
5987
5988 if (!programBinary->setUniform1fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005989 {
5990 return error(GL_INVALID_OPERATION);
5991 }
5992 }
5993 }
5994 catch(std::bad_alloc&)
5995 {
5996 return error(GL_OUT_OF_MEMORY);
5997 }
5998}
5999
6000void __stdcall glUniform1i(GLint location, GLint x)
6001{
6002 glUniform1iv(location, 1, &x);
6003}
6004
6005void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
6006{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006007 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006008
6009 try
6010 {
6011 if (count < 0)
6012 {
6013 return error(GL_INVALID_VALUE);
6014 }
6015
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006016 if (location == -1)
6017 {
6018 return;
6019 }
6020
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006021 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006022
6023 if (context)
6024 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006025 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006026 if (!programBinary)
6027 {
6028 return error(GL_INVALID_OPERATION);
6029 }
6030
6031 if (!programBinary->setUniform1iv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006032 {
6033 return error(GL_INVALID_OPERATION);
6034 }
6035 }
6036 }
6037 catch(std::bad_alloc&)
6038 {
6039 return error(GL_OUT_OF_MEMORY);
6040 }
6041}
6042
6043void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
6044{
6045 GLfloat xy[2] = {x, y};
6046
6047 glUniform2fv(location, 1, (GLfloat*)&xy);
6048}
6049
6050void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
6051{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006052 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006053
6054 try
6055 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006056 if (count < 0)
6057 {
6058 return error(GL_INVALID_VALUE);
6059 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006060
6061 if (location == -1)
6062 {
6063 return;
6064 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006065
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006066 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006067
6068 if (context)
6069 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006070 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006071 if (!programBinary)
6072 {
6073 return error(GL_INVALID_OPERATION);
6074 }
6075
6076 if (!programBinary->setUniform2fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006077 {
6078 return error(GL_INVALID_OPERATION);
6079 }
6080 }
6081 }
6082 catch(std::bad_alloc&)
6083 {
6084 return error(GL_OUT_OF_MEMORY);
6085 }
6086}
6087
6088void __stdcall glUniform2i(GLint location, GLint x, GLint y)
6089{
6090 GLint xy[4] = {x, y};
6091
6092 glUniform2iv(location, 1, (GLint*)&xy);
6093}
6094
6095void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
6096{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006097 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006098
6099 try
6100 {
6101 if (count < 0)
6102 {
6103 return error(GL_INVALID_VALUE);
6104 }
6105
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006106 if (location == -1)
6107 {
6108 return;
6109 }
6110
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006111 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006112
6113 if (context)
6114 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006115 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006116 if (!programBinary)
6117 {
6118 return error(GL_INVALID_OPERATION);
6119 }
6120
6121 if (!programBinary->setUniform2iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006122 {
6123 return error(GL_INVALID_OPERATION);
6124 }
6125 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006126 }
6127 catch(std::bad_alloc&)
6128 {
6129 return error(GL_OUT_OF_MEMORY);
6130 }
6131}
6132
6133void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
6134{
6135 GLfloat xyz[3] = {x, y, z};
6136
6137 glUniform3fv(location, 1, (GLfloat*)&xyz);
6138}
6139
6140void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
6141{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006142 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006143
6144 try
6145 {
6146 if (count < 0)
6147 {
6148 return error(GL_INVALID_VALUE);
6149 }
6150
6151 if (location == -1)
6152 {
6153 return;
6154 }
6155
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006156 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006157
6158 if (context)
6159 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006160 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006161 if (!programBinary)
6162 {
6163 return error(GL_INVALID_OPERATION);
6164 }
6165
6166 if (!programBinary->setUniform3fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006167 {
6168 return error(GL_INVALID_OPERATION);
6169 }
6170 }
6171 }
6172 catch(std::bad_alloc&)
6173 {
6174 return error(GL_OUT_OF_MEMORY);
6175 }
6176}
6177
6178void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
6179{
6180 GLint xyz[3] = {x, y, z};
6181
6182 glUniform3iv(location, 1, (GLint*)&xyz);
6183}
6184
6185void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
6186{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006187 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006188
6189 try
6190 {
6191 if (count < 0)
6192 {
6193 return error(GL_INVALID_VALUE);
6194 }
6195
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006196 if (location == -1)
6197 {
6198 return;
6199 }
6200
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006201 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006202
6203 if (context)
6204 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006205 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006206 if (!programBinary)
6207 {
6208 return error(GL_INVALID_OPERATION);
6209 }
6210
6211 if (!programBinary->setUniform3iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006212 {
6213 return error(GL_INVALID_OPERATION);
6214 }
6215 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006216 }
6217 catch(std::bad_alloc&)
6218 {
6219 return error(GL_OUT_OF_MEMORY);
6220 }
6221}
6222
6223void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6224{
6225 GLfloat xyzw[4] = {x, y, z, w};
6226
6227 glUniform4fv(location, 1, (GLfloat*)&xyzw);
6228}
6229
6230void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
6231{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006232 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006233
6234 try
6235 {
6236 if (count < 0)
6237 {
6238 return error(GL_INVALID_VALUE);
6239 }
6240
6241 if (location == -1)
6242 {
6243 return;
6244 }
6245
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006246 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006247
6248 if (context)
6249 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006250 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006251 if (!programBinary)
6252 {
6253 return error(GL_INVALID_OPERATION);
6254 }
6255
6256 if (!programBinary->setUniform4fv(location, count, v))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006257 {
6258 return error(GL_INVALID_OPERATION);
6259 }
6260 }
6261 }
6262 catch(std::bad_alloc&)
6263 {
6264 return error(GL_OUT_OF_MEMORY);
6265 }
6266}
6267
6268void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
6269{
6270 GLint xyzw[4] = {x, y, z, w};
6271
6272 glUniform4iv(location, 1, (GLint*)&xyzw);
6273}
6274
6275void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
6276{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006277 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006278
6279 try
6280 {
6281 if (count < 0)
6282 {
6283 return error(GL_INVALID_VALUE);
6284 }
6285
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006286 if (location == -1)
6287 {
6288 return;
6289 }
6290
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006291 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006292
6293 if (context)
6294 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006295 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006296 if (!programBinary)
6297 {
6298 return error(GL_INVALID_OPERATION);
6299 }
6300
6301 if (!programBinary->setUniform4iv(location, count, v))
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00006302 {
6303 return error(GL_INVALID_OPERATION);
6304 }
6305 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006306 }
6307 catch(std::bad_alloc&)
6308 {
6309 return error(GL_OUT_OF_MEMORY);
6310 }
6311}
6312
6313void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6314{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006315 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006316 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006317
6318 try
6319 {
6320 if (count < 0 || transpose != GL_FALSE)
6321 {
6322 return error(GL_INVALID_VALUE);
6323 }
6324
6325 if (location == -1)
6326 {
6327 return;
6328 }
6329
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006330 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006331
6332 if (context)
6333 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006334 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006335 if (!programBinary)
6336 {
6337 return error(GL_INVALID_OPERATION);
6338 }
6339
6340 if (!programBinary->setUniformMatrix2fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006341 {
6342 return error(GL_INVALID_OPERATION);
6343 }
6344 }
6345 }
6346 catch(std::bad_alloc&)
6347 {
6348 return error(GL_OUT_OF_MEMORY);
6349 }
6350}
6351
6352void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6353{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006354 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006355 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006356
6357 try
6358 {
6359 if (count < 0 || transpose != GL_FALSE)
6360 {
6361 return error(GL_INVALID_VALUE);
6362 }
6363
6364 if (location == -1)
6365 {
6366 return;
6367 }
6368
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006369 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006370
6371 if (context)
6372 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006373 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006374 if (!programBinary)
6375 {
6376 return error(GL_INVALID_OPERATION);
6377 }
6378
6379 if (!programBinary->setUniformMatrix3fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006380 {
6381 return error(GL_INVALID_OPERATION);
6382 }
6383 }
6384 }
6385 catch(std::bad_alloc&)
6386 {
6387 return error(GL_OUT_OF_MEMORY);
6388 }
6389}
6390
6391void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
6392{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006393 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006394 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006395
6396 try
6397 {
6398 if (count < 0 || transpose != GL_FALSE)
6399 {
6400 return error(GL_INVALID_VALUE);
6401 }
6402
6403 if (location == -1)
6404 {
6405 return;
6406 }
6407
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006408 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006409
6410 if (context)
6411 {
daniel@transgaming.com62a28462012-07-24 18:33:59 +00006412 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +00006413 if (!programBinary)
6414 {
6415 return error(GL_INVALID_OPERATION);
6416 }
6417
6418 if (!programBinary->setUniformMatrix4fv(location, count, value))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006419 {
6420 return error(GL_INVALID_OPERATION);
6421 }
6422 }
6423 }
6424 catch(std::bad_alloc&)
6425 {
6426 return error(GL_OUT_OF_MEMORY);
6427 }
6428}
6429
6430void __stdcall glUseProgram(GLuint program)
6431{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006432 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006433
6434 try
6435 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006436 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006437
6438 if (context)
6439 {
6440 gl::Program *programObject = context->getProgram(program);
6441
daniel@transgaming.comc8478202010-04-13 19:53:35 +00006442 if (!programObject && program != 0)
6443 {
6444 if (context->getShader(program))
6445 {
6446 return error(GL_INVALID_OPERATION);
6447 }
6448 else
6449 {
6450 return error(GL_INVALID_VALUE);
6451 }
6452 }
6453
daniel@transgaming.com716056c2012-07-24 18:38:59 +00006454 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006455 {
6456 return error(GL_INVALID_OPERATION);
6457 }
6458
6459 context->useProgram(program);
6460 }
6461 }
6462 catch(std::bad_alloc&)
6463 {
6464 return error(GL_OUT_OF_MEMORY);
6465 }
6466}
6467
6468void __stdcall glValidateProgram(GLuint program)
6469{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006470 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006471
6472 try
6473 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006474 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006475
6476 if (context)
6477 {
6478 gl::Program *programObject = context->getProgram(program);
6479
6480 if (!programObject)
6481 {
6482 if (context->getShader(program))
6483 {
6484 return error(GL_INVALID_OPERATION);
6485 }
6486 else
6487 {
6488 return error(GL_INVALID_VALUE);
6489 }
6490 }
6491
apatrick@chromium.org253b8d22012-06-22 19:27:21 +00006492 programObject->validate();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00006493 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006494 }
6495 catch(std::bad_alloc&)
6496 {
6497 return error(GL_OUT_OF_MEMORY);
6498 }
6499}
6500
6501void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
6502{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006503 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006504
6505 try
6506 {
6507 if (index >= gl::MAX_VERTEX_ATTRIBS)
6508 {
6509 return error(GL_INVALID_VALUE);
6510 }
6511
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006512 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006513
6514 if (context)
6515 {
6516 GLfloat vals[4] = { x, 0, 0, 1 };
6517 context->setVertexAttrib(index, vals);
6518 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006519 }
6520 catch(std::bad_alloc&)
6521 {
6522 return error(GL_OUT_OF_MEMORY);
6523 }
6524}
6525
6526void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
6527{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006528 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006529
6530 try
6531 {
6532 if (index >= gl::MAX_VERTEX_ATTRIBS)
6533 {
6534 return error(GL_INVALID_VALUE);
6535 }
6536
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006537 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006538
6539 if (context)
6540 {
6541 GLfloat vals[4] = { values[0], 0, 0, 1 };
6542 context->setVertexAttrib(index, vals);
6543 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006544 }
6545 catch(std::bad_alloc&)
6546 {
6547 return error(GL_OUT_OF_MEMORY);
6548 }
6549}
6550
6551void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6552{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006553 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006554
6555 try
6556 {
6557 if (index >= gl::MAX_VERTEX_ATTRIBS)
6558 {
6559 return error(GL_INVALID_VALUE);
6560 }
6561
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006562 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006563
6564 if (context)
6565 {
6566 GLfloat vals[4] = { x, y, 0, 1 };
6567 context->setVertexAttrib(index, vals);
6568 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006569 }
6570 catch(std::bad_alloc&)
6571 {
6572 return error(GL_OUT_OF_MEMORY);
6573 }
6574}
6575
6576void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
6577{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006578 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006579
6580 try
6581 {
6582 if (index >= gl::MAX_VERTEX_ATTRIBS)
6583 {
6584 return error(GL_INVALID_VALUE);
6585 }
6586
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006587 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006588
6589 if (context)
6590 {
6591 GLfloat vals[4] = { values[0], values[1], 0, 1 };
6592 context->setVertexAttrib(index, vals);
6593 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006594 }
6595 catch(std::bad_alloc&)
6596 {
6597 return error(GL_OUT_OF_MEMORY);
6598 }
6599}
6600
6601void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6602{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006603 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 +00006604
6605 try
6606 {
6607 if (index >= gl::MAX_VERTEX_ATTRIBS)
6608 {
6609 return error(GL_INVALID_VALUE);
6610 }
6611
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006612 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006613
6614 if (context)
6615 {
6616 GLfloat vals[4] = { x, y, z, 1 };
6617 context->setVertexAttrib(index, vals);
6618 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006619 }
6620 catch(std::bad_alloc&)
6621 {
6622 return error(GL_OUT_OF_MEMORY);
6623 }
6624}
6625
6626void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
6627{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006628 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006629
6630 try
6631 {
6632 if (index >= gl::MAX_VERTEX_ATTRIBS)
6633 {
6634 return error(GL_INVALID_VALUE);
6635 }
6636
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006637 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006638
6639 if (context)
6640 {
6641 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6642 context->setVertexAttrib(index, vals);
6643 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006644 }
6645 catch(std::bad_alloc&)
6646 {
6647 return error(GL_OUT_OF_MEMORY);
6648 }
6649}
6650
6651void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6652{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006653 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 +00006654
6655 try
6656 {
6657 if (index >= gl::MAX_VERTEX_ATTRIBS)
6658 {
6659 return error(GL_INVALID_VALUE);
6660 }
6661
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006662 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006663
6664 if (context)
6665 {
6666 GLfloat vals[4] = { x, y, z, w };
6667 context->setVertexAttrib(index, vals);
6668 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006669 }
6670 catch(std::bad_alloc&)
6671 {
6672 return error(GL_OUT_OF_MEMORY);
6673 }
6674}
6675
6676void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
6677{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006678 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006679
6680 try
6681 {
6682 if (index >= gl::MAX_VERTEX_ATTRIBS)
6683 {
6684 return error(GL_INVALID_VALUE);
6685 }
6686
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006687 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006688
6689 if (context)
6690 {
6691 context->setVertexAttrib(index, values);
6692 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006693 }
6694 catch(std::bad_alloc&)
6695 {
6696 return error(GL_OUT_OF_MEMORY);
6697 }
6698}
6699
daniel@transgaming.comd2820bf2012-01-27 15:38:48 +00006700void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
6701{
6702 EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
6703
6704 try
6705 {
6706 if (index >= gl::MAX_VERTEX_ATTRIBS)
6707 {
6708 return error(GL_INVALID_VALUE);
6709 }
6710
6711 gl::Context *context = gl::getNonLostContext();
6712
6713 if (context)
6714 {
6715 context->setVertexAttribDivisor(index, divisor);
6716 }
6717 }
6718 catch(std::bad_alloc&)
6719 {
6720 return error(GL_OUT_OF_MEMORY);
6721 }
6722}
6723
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006724void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006725{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006726 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006727 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006728 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006729
6730 try
6731 {
6732 if (index >= gl::MAX_VERTEX_ATTRIBS)
6733 {
6734 return error(GL_INVALID_VALUE);
6735 }
6736
6737 if (size < 1 || size > 4)
6738 {
6739 return error(GL_INVALID_VALUE);
6740 }
6741
6742 switch (type)
6743 {
6744 case GL_BYTE:
6745 case GL_UNSIGNED_BYTE:
6746 case GL_SHORT:
6747 case GL_UNSIGNED_SHORT:
6748 case GL_FIXED:
6749 case GL_FLOAT:
6750 break;
6751 default:
6752 return error(GL_INVALID_ENUM);
6753 }
6754
6755 if (stride < 0)
6756 {
6757 return error(GL_INVALID_VALUE);
6758 }
6759
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006760 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006761
6762 if (context)
6763 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006764 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006765 }
6766 }
6767 catch(std::bad_alloc&)
6768 {
6769 return error(GL_OUT_OF_MEMORY);
6770 }
6771}
6772
6773void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6774{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006775 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 +00006776
6777 try
6778 {
6779 if (width < 0 || height < 0)
6780 {
6781 return error(GL_INVALID_VALUE);
6782 }
6783
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006784 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006785
6786 if (context)
6787 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006788 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006789 }
6790 }
6791 catch(std::bad_alloc&)
6792 {
6793 return error(GL_OUT_OF_MEMORY);
6794 }
6795}
6796
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006797void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6798 GLbitfield mask, GLenum filter)
6799{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006800 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006801 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6802 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6803 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6804
6805 try
6806 {
6807 switch (filter)
6808 {
6809 case GL_NEAREST:
6810 break;
6811 default:
6812 return error(GL_INVALID_ENUM);
6813 }
6814
6815 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6816 {
6817 return error(GL_INVALID_VALUE);
6818 }
6819
6820 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6821 {
6822 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6823 return error(GL_INVALID_OPERATION);
6824 }
6825
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006826 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006827
6828 if (context)
6829 {
6830 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6831 {
6832 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6833 return error(GL_INVALID_OPERATION);
6834 }
6835
6836 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6837 }
6838 }
6839 catch(std::bad_alloc&)
6840 {
6841 return error(GL_OUT_OF_MEMORY);
6842 }
6843}
6844
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006845void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6846 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006847{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006848 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006849 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006850 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006851 target, level, internalformat, width, height, depth, border, format, type, pixels);
6852
6853 try
6854 {
6855 UNIMPLEMENTED(); // FIXME
6856 }
6857 catch(std::bad_alloc&)
6858 {
6859 return error(GL_OUT_OF_MEMORY);
6860 }
6861}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006862
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006863void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length,
6864 GLenum *binaryFormat, void *binary)
6865{
apatrick@chromium.org90080e32012-07-09 22:15:33 +00006866 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 +00006867 program, bufSize, length, binaryFormat, binary);
6868
6869 try
6870 {
6871 gl::Context *context = gl::getNonLostContext();
6872
6873 if (context)
6874 {
6875 gl::Program *programObject = context->getProgram(program);
6876
daniel@transgaming.com716056c2012-07-24 18:38:59 +00006877 if (!programObject || !programObject->isLinked())
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006878 {
6879 return error(GL_INVALID_OPERATION);
6880 }
6881
6882 gl::ProgramBinary *programBinary = programObject->getProgramBinary();
6883
6884 if (!programBinary)
6885 {
6886 return error(GL_INVALID_OPERATION);
6887 }
6888
apatrick@chromium.org90080e32012-07-09 22:15:33 +00006889 if (!programBinary->save(binary, bufSize, length))
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006890 {
apatrick@chromium.org90080e32012-07-09 22:15:33 +00006891 return error(GL_INVALID_OPERATION);
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006892 }
apatrick@chromium.org90080e32012-07-09 22:15:33 +00006893
6894 *binaryFormat = GL_PROGRAM_BINARY_ANGLE;
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006895 }
6896 }
6897 catch(std::bad_alloc&)
6898 {
6899 return error(GL_OUT_OF_MEMORY);
6900 }
6901}
6902
6903void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat,
6904 const void *binary, GLint length)
6905{
6906 EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)",
6907 program, binaryFormat, binary, length);
6908
6909 try
6910 {
6911 gl::Context *context = gl::getNonLostContext();
6912
6913 if (context)
6914 {
6915 if (binaryFormat != GL_PROGRAM_BINARY_ANGLE)
6916 {
6917 return error(GL_INVALID_ENUM);
6918 }
6919
6920 gl::Program *programObject = context->getProgram(program);
6921
6922 if (!programObject)
6923 {
6924 return error(GL_INVALID_OPERATION);
6925 }
6926
daniel@transgaming.com95d29422012-07-24 18:36:10 +00006927 context->setProgramBinary(program, binary, length);
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006928 }
6929 }
6930 catch(std::bad_alloc&)
6931 {
6932 return error(GL_OUT_OF_MEMORY);
6933 }
6934}
6935
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006936__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6937{
6938 struct Extension
6939 {
6940 const char *name;
6941 __eglMustCastToProperFunctionPointerType address;
6942 };
6943
6944 static const Extension glExtensions[] =
6945 {
6946 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006947 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006948 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006949 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6950 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6951 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6952 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6953 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6954 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6955 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006956 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006957 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006958 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6959 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6960 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6961 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.com86bdb822012-01-20 18:24:39 +00006962 {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT},
6963 {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT},
6964 {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT},
6965 {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT},
6966 {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
6967 {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
6968 {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
daniel@transgaming.comdce02fd2012-01-27 15:39:51 +00006969 {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE},
6970 {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE},
6971 {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE},
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +00006972 {"glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glGetProgramBinaryOES},
6973 {"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES}, };
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006974
6975 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6976 {
6977 if (strcmp(procname, glExtensions[ext].name) == 0)
6978 {
6979 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6980 }
6981 }
6982
6983 return NULL;
6984}
6985
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006986// Non-public functions used by EGL
6987
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006988bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006989{
6990 EVENT("(egl::Surface* surface = 0x%0.8p)",
6991 surface);
6992
6993 try
6994 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006995 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006996
6997 if (context)
6998 {
6999 gl::Texture2D *textureObject = context->getTexture2D();
7000
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00007001 if (textureObject->isImmutable())
7002 {
7003 return false;
7004 }
7005
jbauman@chromium.orgae345802011-03-30 22:04:25 +00007006 if (textureObject)
7007 {
7008 textureObject->bindTexImage(surface);
7009 }
7010 }
7011 }
7012 catch(std::bad_alloc&)
7013 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00007014 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00007015 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00007016
7017 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00007018}
7019
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00007020}