blob: 5d8ec4560139dfcf754e3a49782416392f0b9ddf [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +00002// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +000017#include "common/version.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000018
19#include "libGLESv2/main.h"
20#include "libGLESv2/mathutil.h"
21#include "libGLESv2/utilities.h"
22#include "libGLESv2/Buffer.h"
23#include "libGLESv2/Context.h"
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000024#include "libGLESv2/Fence.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000025#include "libGLESv2/Framebuffer.h"
26#include "libGLESv2/Program.h"
27#include "libGLESv2/Renderbuffer.h"
28#include "libGLESv2/Shader.h"
29#include "libGLESv2/Texture.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000030
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +000031bool validImageSize(GLint level, GLsizei width, GLsizei height)
32{
33 if (level < 0 || width < 0 || height < 0)
34 {
35 return false;
36 }
37
38 if (gl::getContext() && gl::getContext()->supportsNonPower2Texture())
39 {
40 return true;
41 }
42
43 if (level == 0)
44 {
45 return true;
46 }
47
48 if (gl::isPow2(width) && gl::isPow2(height))
49 {
50 return true;
51 }
52
53 return false;
54}
55
daniel@transgaming.comb7915a52011-11-12 03:14:20 +000056// check for combinations of format and type that are valid for ReadPixels
57bool validReadFormatType(GLenum format, GLenum type)
58{
59 switch (format)
60 {
61 case GL_RGBA:
62 switch (type)
63 {
64 case GL_UNSIGNED_BYTE:
65 break;
66 default:
67 return false;
68 }
69 break;
70 case GL_BGRA_EXT:
71 switch (type)
72 {
73 case GL_UNSIGNED_BYTE:
74 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
75 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
76 break;
77 default:
78 return false;
79 }
80 break;
81 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
82 switch (type)
83 {
84 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
85 break;
86 default:
87 return false;
88 }
89 break;
90 default:
91 return false;
92 }
93 return true;
94}
95
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000096extern "C"
97{
98
99void __stdcall glActiveTexture(GLenum texture)
100{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000101 EVENT("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000102
103 try
104 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000105 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000106
107 if (context)
108 {
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +0000109 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
110 {
111 return error(GL_INVALID_ENUM);
112 }
113
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000114 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000115 }
116 }
117 catch(std::bad_alloc&)
118 {
119 return error(GL_OUT_OF_MEMORY);
120 }
121}
122
123void __stdcall glAttachShader(GLuint program, GLuint shader)
124{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000125 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000126
127 try
128 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000129 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000130
131 if (context)
132 {
133 gl::Program *programObject = context->getProgram(program);
134 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000135
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000136 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000138 if (context->getShader(program))
139 {
140 return error(GL_INVALID_OPERATION);
141 }
142 else
143 {
144 return error(GL_INVALID_VALUE);
145 }
146 }
147
148 if (!shaderObject)
149 {
150 if (context->getProgram(shader))
151 {
152 return error(GL_INVALID_OPERATION);
153 }
154 else
155 {
156 return error(GL_INVALID_VALUE);
157 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000158 }
159
160 if (!programObject->attachShader(shaderObject))
161 {
162 return error(GL_INVALID_OPERATION);
163 }
164 }
165 }
166 catch(std::bad_alloc&)
167 {
168 return error(GL_OUT_OF_MEMORY);
169 }
170}
171
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000172void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000173{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000174 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000175
176 try
177 {
178 if (index >= gl::MAX_VERTEX_ATTRIBS)
179 {
180 return error(GL_INVALID_VALUE);
181 }
182
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000183 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000184
185 if (context)
186 {
187 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000188
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000189 if (!programObject)
190 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000191 if (context->getShader(program))
192 {
193 return error(GL_INVALID_OPERATION);
194 }
195 else
196 {
197 return error(GL_INVALID_VALUE);
198 }
199 }
200
201 if (strncmp(name, "gl_", 3) == 0)
202 {
203 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000204 }
205
206 programObject->bindAttributeLocation(index, name);
207 }
208 }
209 catch(std::bad_alloc&)
210 {
211 return error(GL_OUT_OF_MEMORY);
212 }
213}
214
215void __stdcall glBindBuffer(GLenum target, GLuint buffer)
216{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000217 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000218
219 try
220 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000221 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000222
223 if (context)
224 {
225 switch (target)
226 {
227 case GL_ARRAY_BUFFER:
228 context->bindArrayBuffer(buffer);
229 return;
230 case GL_ELEMENT_ARRAY_BUFFER:
231 context->bindElementArrayBuffer(buffer);
232 return;
233 default:
234 return error(GL_INVALID_ENUM);
235 }
236 }
237 }
238 catch(std::bad_alloc&)
239 {
240 return error(GL_OUT_OF_MEMORY);
241 }
242}
243
244void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
245{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000246 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000247
248 try
249 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000250 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000251 {
252 return error(GL_INVALID_ENUM);
253 }
254
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000255 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000256
257 if (context)
258 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000259 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
260 {
261 context->bindReadFramebuffer(framebuffer);
262 }
263
264 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
265 {
266 context->bindDrawFramebuffer(framebuffer);
267 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000268 }
269 }
270 catch(std::bad_alloc&)
271 {
272 return error(GL_OUT_OF_MEMORY);
273 }
274}
275
276void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
277{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000278 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000279
280 try
281 {
282 if (target != GL_RENDERBUFFER)
283 {
284 return error(GL_INVALID_ENUM);
285 }
286
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000287 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000288
289 if (context)
290 {
291 context->bindRenderbuffer(renderbuffer);
292 }
293 }
294 catch(std::bad_alloc&)
295 {
296 return error(GL_OUT_OF_MEMORY);
297 }
298}
299
300void __stdcall glBindTexture(GLenum target, GLuint texture)
301{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000302 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000303
304 try
305 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000306 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000307
308 if (context)
309 {
310 gl::Texture *textureObject = context->getTexture(texture);
311
312 if (textureObject && textureObject->getTarget() != target && texture != 0)
313 {
314 return error(GL_INVALID_OPERATION);
315 }
316
317 switch (target)
318 {
319 case GL_TEXTURE_2D:
320 context->bindTexture2D(texture);
321 return;
322 case GL_TEXTURE_CUBE_MAP:
323 context->bindTextureCubeMap(texture);
324 return;
325 default:
326 return error(GL_INVALID_ENUM);
327 }
328 }
329 }
330 catch(std::bad_alloc&)
331 {
332 return error(GL_OUT_OF_MEMORY);
333 }
334}
335
336void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
337{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000338 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000339 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000340
341 try
342 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000343 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000344
345 if (context)
346 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000347 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000348 }
349 }
350 catch(std::bad_alloc&)
351 {
352 return error(GL_OUT_OF_MEMORY);
353 }
354}
355
356void __stdcall glBlendEquation(GLenum mode)
357{
358 glBlendEquationSeparate(mode, mode);
359}
360
361void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
362{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000363 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000364
365 try
366 {
367 switch (modeRGB)
368 {
369 case GL_FUNC_ADD:
370 case GL_FUNC_SUBTRACT:
371 case GL_FUNC_REVERSE_SUBTRACT:
372 break;
373 default:
374 return error(GL_INVALID_ENUM);
375 }
376
377 switch (modeAlpha)
378 {
379 case GL_FUNC_ADD:
380 case GL_FUNC_SUBTRACT:
381 case GL_FUNC_REVERSE_SUBTRACT:
382 break;
383 default:
384 return error(GL_INVALID_ENUM);
385 }
386
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000387 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000388
389 if (context)
390 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000391 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000392 }
393 }
394 catch(std::bad_alloc&)
395 {
396 return error(GL_OUT_OF_MEMORY);
397 }
398}
399
400void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
401{
402 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
403}
404
405void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
406{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000407 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 +0000408 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000409
410 try
411 {
412 switch (srcRGB)
413 {
414 case GL_ZERO:
415 case GL_ONE:
416 case GL_SRC_COLOR:
417 case GL_ONE_MINUS_SRC_COLOR:
418 case GL_DST_COLOR:
419 case GL_ONE_MINUS_DST_COLOR:
420 case GL_SRC_ALPHA:
421 case GL_ONE_MINUS_SRC_ALPHA:
422 case GL_DST_ALPHA:
423 case GL_ONE_MINUS_DST_ALPHA:
424 case GL_CONSTANT_COLOR:
425 case GL_ONE_MINUS_CONSTANT_COLOR:
426 case GL_CONSTANT_ALPHA:
427 case GL_ONE_MINUS_CONSTANT_ALPHA:
428 case GL_SRC_ALPHA_SATURATE:
429 break;
430 default:
431 return error(GL_INVALID_ENUM);
432 }
433
434 switch (dstRGB)
435 {
436 case GL_ZERO:
437 case GL_ONE:
438 case GL_SRC_COLOR:
439 case GL_ONE_MINUS_SRC_COLOR:
440 case GL_DST_COLOR:
441 case GL_ONE_MINUS_DST_COLOR:
442 case GL_SRC_ALPHA:
443 case GL_ONE_MINUS_SRC_ALPHA:
444 case GL_DST_ALPHA:
445 case GL_ONE_MINUS_DST_ALPHA:
446 case GL_CONSTANT_COLOR:
447 case GL_ONE_MINUS_CONSTANT_COLOR:
448 case GL_CONSTANT_ALPHA:
449 case GL_ONE_MINUS_CONSTANT_ALPHA:
450 break;
451 default:
452 return error(GL_INVALID_ENUM);
453 }
454
455 switch (srcAlpha)
456 {
457 case GL_ZERO:
458 case GL_ONE:
459 case GL_SRC_COLOR:
460 case GL_ONE_MINUS_SRC_COLOR:
461 case GL_DST_COLOR:
462 case GL_ONE_MINUS_DST_COLOR:
463 case GL_SRC_ALPHA:
464 case GL_ONE_MINUS_SRC_ALPHA:
465 case GL_DST_ALPHA:
466 case GL_ONE_MINUS_DST_ALPHA:
467 case GL_CONSTANT_COLOR:
468 case GL_ONE_MINUS_CONSTANT_COLOR:
469 case GL_CONSTANT_ALPHA:
470 case GL_ONE_MINUS_CONSTANT_ALPHA:
471 case GL_SRC_ALPHA_SATURATE:
472 break;
473 default:
474 return error(GL_INVALID_ENUM);
475 }
476
477 switch (dstAlpha)
478 {
479 case GL_ZERO:
480 case GL_ONE:
481 case GL_SRC_COLOR:
482 case GL_ONE_MINUS_SRC_COLOR:
483 case GL_DST_COLOR:
484 case GL_ONE_MINUS_DST_COLOR:
485 case GL_SRC_ALPHA:
486 case GL_ONE_MINUS_SRC_ALPHA:
487 case GL_DST_ALPHA:
488 case GL_ONE_MINUS_DST_ALPHA:
489 case GL_CONSTANT_COLOR:
490 case GL_ONE_MINUS_CONSTANT_COLOR:
491 case GL_CONSTANT_ALPHA:
492 case GL_ONE_MINUS_CONSTANT_ALPHA:
493 break;
494 default:
495 return error(GL_INVALID_ENUM);
496 }
497
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000498 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
499 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
500
501 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
502 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
503
504 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000505 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000506 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
507 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000508 }
509
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000510 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000511
512 if (context)
513 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000514 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000515 }
516 }
517 catch(std::bad_alloc&)
518 {
519 return error(GL_OUT_OF_MEMORY);
520 }
521}
522
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000523void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000524{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000525 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 +0000526 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000527
528 try
529 {
530 if (size < 0)
531 {
532 return error(GL_INVALID_VALUE);
533 }
534
535 switch (usage)
536 {
537 case GL_STREAM_DRAW:
538 case GL_STATIC_DRAW:
539 case GL_DYNAMIC_DRAW:
540 break;
541 default:
542 return error(GL_INVALID_ENUM);
543 }
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 {
549 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000550
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000551 switch (target)
552 {
553 case GL_ARRAY_BUFFER:
554 buffer = context->getArrayBuffer();
555 break;
556 case GL_ELEMENT_ARRAY_BUFFER:
557 buffer = context->getElementArrayBuffer();
558 break;
559 default:
560 return error(GL_INVALID_ENUM);
561 }
562
563 if (!buffer)
564 {
565 return error(GL_INVALID_OPERATION);
566 }
567
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000568 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000569 }
570 }
571 catch(std::bad_alloc&)
572 {
573 return error(GL_OUT_OF_MEMORY);
574 }
575}
576
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000577void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000578{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000579 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 +0000580 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000581
582 try
583 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000584 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000585 {
586 return error(GL_INVALID_VALUE);
587 }
588
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000589 if (data == NULL)
590 {
591 return;
592 }
593
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000594 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000595
596 if (context)
597 {
598 gl::Buffer *buffer;
599
600 switch (target)
601 {
602 case GL_ARRAY_BUFFER:
603 buffer = context->getArrayBuffer();
604 break;
605 case GL_ELEMENT_ARRAY_BUFFER:
606 buffer = context->getElementArrayBuffer();
607 break;
608 default:
609 return error(GL_INVALID_ENUM);
610 }
611
612 if (!buffer)
613 {
614 return error(GL_INVALID_OPERATION);
615 }
616
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000617 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000618 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000619 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000620 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000621
622 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000623 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000624 }
625 catch(std::bad_alloc&)
626 {
627 return error(GL_OUT_OF_MEMORY);
628 }
629}
630
631GLenum __stdcall glCheckFramebufferStatus(GLenum target)
632{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000633 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000634
635 try
636 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000637 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000638 {
639 return error(GL_INVALID_ENUM, 0);
640 }
641
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000642 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000643
644 if (context)
645 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000646 gl::Framebuffer *framebuffer = NULL;
647 if (target == GL_READ_FRAMEBUFFER_ANGLE)
648 {
649 framebuffer = context->getReadFramebuffer();
650 }
651 else
652 {
653 framebuffer = context->getDrawFramebuffer();
654 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000655
656 return framebuffer->completeness();
657 }
658 }
659 catch(std::bad_alloc&)
660 {
661 return error(GL_OUT_OF_MEMORY, 0);
662 }
663
664 return 0;
665}
666
667void __stdcall glClear(GLbitfield mask)
668{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000669 EVENT("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000670
671 try
672 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000673 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000674
675 if (context)
676 {
677 context->clear(mask);
678 }
679 }
680 catch(std::bad_alloc&)
681 {
682 return error(GL_OUT_OF_MEMORY);
683 }
684}
685
686void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
687{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000688 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000689 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000690
691 try
692 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000693 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000694
695 if (context)
696 {
697 context->setClearColor(red, green, blue, alpha);
698 }
699 }
700 catch(std::bad_alloc&)
701 {
702 return error(GL_OUT_OF_MEMORY);
703 }
704}
705
706void __stdcall glClearDepthf(GLclampf depth)
707{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000708 EVENT("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000709
710 try
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 {
716 context->setClearDepth(depth);
717 }
718 }
719 catch(std::bad_alloc&)
720 {
721 return error(GL_OUT_OF_MEMORY);
722 }
723}
724
725void __stdcall glClearStencil(GLint s)
726{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000727 EVENT("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000728
729 try
730 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000731 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000732
733 if (context)
734 {
735 context->setClearStencil(s);
736 }
737 }
738 catch(std::bad_alloc&)
739 {
740 return error(GL_OUT_OF_MEMORY);
741 }
742}
743
744void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
745{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000746 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000747 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748
749 try
750 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000751 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000752
753 if (context)
754 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000755 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000756 }
757 }
758 catch(std::bad_alloc&)
759 {
760 return error(GL_OUT_OF_MEMORY);
761 }
762}
763
764void __stdcall glCompileShader(GLuint shader)
765{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000766 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000767
768 try
769 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000770 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000771
772 if (context)
773 {
774 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000775
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000776 if (!shaderObject)
777 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000778 if (context->getProgram(shader))
779 {
780 return error(GL_INVALID_OPERATION);
781 }
782 else
783 {
784 return error(GL_INVALID_VALUE);
785 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000786 }
787
788 shaderObject->compile();
789 }
790 }
791 catch(std::bad_alloc&)
792 {
793 return error(GL_OUT_OF_MEMORY);
794 }
795}
796
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000797void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
798 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000799{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000800 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000801 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000802 target, level, internalformat, width, height, border, imageSize, data);
803
804 try
805 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000806 if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000807 {
808 return error(GL_INVALID_VALUE);
809 }
810
daniel@transgaming.com01868132010-08-24 19:21:17 +0000811 switch (internalformat)
812 {
813 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
814 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +0000815 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
816 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +0000817 break;
818 default:
819 return error(GL_INVALID_ENUM);
820 }
821
822 if (border != 0)
823 {
824 return error(GL_INVALID_VALUE);
825 }
826
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000827 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000828
829 if (context)
830 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000831 if (level > context->getMaximumTextureLevel())
832 {
833 return error(GL_INVALID_VALUE);
834 }
835
836 switch (target)
837 {
838 case GL_TEXTURE_2D:
839 if (width > (context->getMaximumTextureDimension() >> level) ||
840 height > (context->getMaximumTextureDimension() >> level))
841 {
842 return error(GL_INVALID_VALUE);
843 }
844 break;
845 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
846 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
847 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
848 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
849 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
850 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
851 if (width != height)
852 {
853 return error(GL_INVALID_VALUE);
854 }
855
856 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
857 height > (context->getMaximumCubeTextureDimension() >> level))
858 {
859 return error(GL_INVALID_VALUE);
860 }
861 break;
862 default:
863 return error(GL_INVALID_ENUM);
864 }
865
gman@chromium.org50c526d2011-08-10 05:19:44 +0000866 switch (internalformat) {
867 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
868 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
869 if (!context->supportsDXT1Textures())
870 {
871 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
872 }
873 break;
874 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
875 if (!context->supportsDXT3Textures())
876 {
877 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
878 }
879 break;
880 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
881 if (!context->supportsDXT5Textures())
882 {
883 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
884 }
885 break;
886 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000887 }
888
889 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
890 {
891 return error(GL_INVALID_VALUE);
892 }
893
894 if (target == GL_TEXTURE_2D)
895 {
896 gl::Texture2D *texture = context->getTexture2D();
897
898 if (!texture)
899 {
900 return error(GL_INVALID_OPERATION);
901 }
902
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +0000903 if (texture->isImmutable())
904 {
905 return error(GL_INVALID_OPERATION);
906 }
907
daniel@transgaming.com01868132010-08-24 19:21:17 +0000908 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
909 }
910 else
911 {
912 gl::TextureCubeMap *texture = context->getTextureCubeMap();
913
914 if (!texture)
915 {
916 return error(GL_INVALID_OPERATION);
917 }
918
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +0000919 if (texture->isImmutable())
920 {
921 return error(GL_INVALID_OPERATION);
922 }
923
daniel@transgaming.com01868132010-08-24 19:21:17 +0000924 switch (target)
925 {
926 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
927 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
928 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
929 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
930 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
931 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
932 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
933 break;
934 default: UNREACHABLE();
935 }
936 }
937 }
938
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000939 }
940 catch(std::bad_alloc&)
941 {
942 return error(GL_OUT_OF_MEMORY);
943 }
944}
945
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000946void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
947 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000948{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000949 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000950 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000951 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000952 target, level, xoffset, yoffset, width, height, format, imageSize, data);
953
954 try
955 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000956 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000957 {
958 return error(GL_INVALID_ENUM);
959 }
960
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000961 if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000962 {
963 return error(GL_INVALID_VALUE);
964 }
965
daniel@transgaming.com01868132010-08-24 19:21:17 +0000966 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000967 {
daniel@transgaming.com01868132010-08-24 19:21:17 +0000968 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
969 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +0000970 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
971 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +0000972 break;
973 default:
974 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +0000975 }
976
daniel@transgaming.com01868132010-08-24 19:21:17 +0000977 if (width == 0 || height == 0 || data == NULL)
978 {
979 return;
980 }
981
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000982 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000983
984 if (context)
985 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000986 if (level > context->getMaximumTextureLevel())
987 {
988 return error(GL_INVALID_VALUE);
989 }
990
gman@chromium.org50c526d2011-08-10 05:19:44 +0000991 switch (format) {
992 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
993 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
994 if (!context->supportsDXT1Textures())
995 {
996 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
997 }
998 break;
999 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1000 if (!context->supportsDXT3Textures())
1001 {
1002 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1003 }
1004 break;
1005 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1006 if (!context->supportsDXT5Textures())
1007 {
1008 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1009 }
1010 break;
1011 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001012 }
1013
1014 if (imageSize != gl::ComputeCompressedSize(width, height, format))
1015 {
1016 return error(GL_INVALID_VALUE);
1017 }
1018
1019 if (xoffset % 4 != 0 || yoffset % 4 != 0)
1020 {
1021 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 +00001022 // does not exist unless DXT textures are supported.
daniel@transgaming.com01868132010-08-24 19:21:17 +00001023 }
1024
1025 if (target == GL_TEXTURE_2D)
1026 {
1027 gl::Texture2D *texture = context->getTexture2D();
1028
1029 if (!texture)
1030 {
1031 return error(GL_INVALID_OPERATION);
1032 }
1033
1034 if (!texture->isCompressed())
1035 {
1036 return error(GL_INVALID_OPERATION);
1037 }
1038
daniel@transgaming.comf1286442011-11-29 19:42:23 +00001039 if ((width % 4 != 0 && width != texture->getWidth(0)) ||
1040 (height % 4 != 0 && height != texture->getHeight(0)))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001041 {
1042 return error(GL_INVALID_OPERATION);
1043 }
1044
1045 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
1046 }
1047 else if (gl::IsCubemapTextureTarget(target))
1048 {
1049 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1050
1051 if (!texture)
1052 {
1053 return error(GL_INVALID_OPERATION);
1054 }
1055
1056 if (!texture->isCompressed())
1057 {
1058 return error(GL_INVALID_OPERATION);
1059 }
1060
daniel@transgaming.comf1286442011-11-29 19:42:23 +00001061 if ((width % 4 != 0 && width != texture->getWidth(0)) ||
1062 (height % 4 != 0 && height != texture->getHeight(0)))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001063 {
1064 return error(GL_INVALID_OPERATION);
1065 }
1066
1067 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
1068 }
1069 else
1070 {
1071 UNREACHABLE();
1072 }
1073 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001074 }
1075 catch(std::bad_alloc&)
1076 {
1077 return error(GL_OUT_OF_MEMORY);
1078 }
1079}
1080
1081void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1082{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001083 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001084 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001085 target, level, internalformat, x, y, width, height, border);
1086
1087 try
1088 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001089 if (!validImageSize(level, width, height))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001090 {
1091 return error(GL_INVALID_VALUE);
1092 }
1093
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001094 if (border != 0)
1095 {
1096 return error(GL_INVALID_VALUE);
1097 }
1098
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001099 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001100
1101 if (context)
1102 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00001103 if (level > context->getMaximumTextureLevel())
1104 {
1105 return error(GL_INVALID_VALUE);
1106 }
1107
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001108 switch (target)
1109 {
1110 case GL_TEXTURE_2D:
1111 if (width > (context->getMaximumTextureDimension() >> level) ||
1112 height > (context->getMaximumTextureDimension() >> level))
1113 {
1114 return error(GL_INVALID_VALUE);
1115 }
1116 break;
1117 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1118 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1119 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1120 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1121 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1122 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1123 if (width != height)
1124 {
1125 return error(GL_INVALID_VALUE);
1126 }
1127
1128 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1129 height > (context->getMaximumCubeTextureDimension() >> level))
1130 {
1131 return error(GL_INVALID_VALUE);
1132 }
1133 break;
1134 default:
1135 return error(GL_INVALID_ENUM);
1136 }
1137
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001138 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001139
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001140 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1141 {
1142 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1143 }
1144
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001145 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1146 {
1147 return error(GL_INVALID_OPERATION);
1148 }
1149
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001150 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001151 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001152
1153 // [OpenGL ES 2.0.24] table 3.9
1154 switch (internalformat)
1155 {
1156 case GL_ALPHA:
1157 if (colorbufferFormat != GL_ALPHA &&
1158 colorbufferFormat != GL_RGBA &&
1159 colorbufferFormat != GL_RGBA4 &&
1160 colorbufferFormat != GL_RGB5_A1 &&
1161 colorbufferFormat != GL_RGBA8_OES)
1162 {
1163 return error(GL_INVALID_OPERATION);
1164 }
1165 break;
1166 case GL_LUMINANCE:
1167 case GL_RGB:
1168 if (colorbufferFormat != GL_RGB &&
1169 colorbufferFormat != GL_RGB565 &&
1170 colorbufferFormat != GL_RGB8_OES &&
1171 colorbufferFormat != GL_RGBA &&
1172 colorbufferFormat != GL_RGBA4 &&
1173 colorbufferFormat != GL_RGB5_A1 &&
1174 colorbufferFormat != GL_RGBA8_OES)
1175 {
1176 return error(GL_INVALID_OPERATION);
1177 }
1178 break;
1179 case GL_LUMINANCE_ALPHA:
1180 case GL_RGBA:
1181 if (colorbufferFormat != GL_RGBA &&
1182 colorbufferFormat != GL_RGBA4 &&
1183 colorbufferFormat != GL_RGB5_A1 &&
1184 colorbufferFormat != GL_RGBA8_OES)
1185 {
1186 return error(GL_INVALID_OPERATION);
1187 }
1188 break;
1189 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1190 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001191 if (context->supportsDXT1Textures())
1192 {
1193 return error(GL_INVALID_OPERATION);
1194 }
1195 else
1196 {
1197 return error(GL_INVALID_ENUM);
1198 }
1199 break;
1200 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1201 if (context->supportsDXT3Textures())
1202 {
1203 return error(GL_INVALID_OPERATION);
1204 }
1205 else
1206 {
1207 return error(GL_INVALID_ENUM);
1208 }
1209 break;
1210 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1211 if (context->supportsDXT5Textures())
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001212 {
1213 return error(GL_INVALID_OPERATION);
1214 }
1215 else
1216 {
1217 return error(GL_INVALID_ENUM);
1218 }
1219 break;
1220 default:
1221 return error(GL_INVALID_ENUM);
1222 }
1223
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001224 if (target == GL_TEXTURE_2D)
1225 {
1226 gl::Texture2D *texture = context->getTexture2D();
1227
1228 if (!texture)
1229 {
1230 return error(GL_INVALID_OPERATION);
1231 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001232
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001233 if (texture->isImmutable())
1234 {
1235 return error(GL_INVALID_OPERATION);
1236 }
1237
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001238 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001239 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001240 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001241 {
1242 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1243
1244 if (!texture)
1245 {
1246 return error(GL_INVALID_OPERATION);
1247 }
1248
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001249 if (texture->isImmutable())
1250 {
1251 return error(GL_INVALID_OPERATION);
1252 }
1253
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001254 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001255 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001256 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001257 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001258 }
1259 catch(std::bad_alloc&)
1260 {
1261 return error(GL_OUT_OF_MEMORY);
1262 }
1263}
1264
1265void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1266{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001267 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001268 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001269 target, level, xoffset, yoffset, x, y, width, height);
1270
1271 try
1272 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001273 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001274 {
1275 return error(GL_INVALID_ENUM);
1276 }
1277
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001278 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001279 {
1280 return error(GL_INVALID_VALUE);
1281 }
1282
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001283 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1284 {
1285 return error(GL_INVALID_VALUE);
1286 }
1287
1288 if (width == 0 || height == 0)
1289 {
1290 return;
1291 }
1292
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001293 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001294
1295 if (context)
1296 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001297 if (level > context->getMaximumTextureLevel())
1298 {
1299 return error(GL_INVALID_VALUE);
1300 }
1301
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001302 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001303
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001304 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1305 {
1306 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1307 }
1308
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001309 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1310 {
1311 return error(GL_INVALID_OPERATION);
1312 }
1313
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001314 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001315 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001316 gl::Texture *texture = NULL;
1317
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001318 if (target == GL_TEXTURE_2D)
1319 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001320 texture = context->getTexture2D();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001321 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001322 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001323 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001324 texture = context->getTextureCubeMap();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001325 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001326 else UNREACHABLE();
1327
1328 if (!texture)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001329 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001330 return error(GL_INVALID_OPERATION);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001331 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001332
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001333 GLenum textureFormat = texture->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001334
1335 // [OpenGL ES 2.0.24] table 3.9
1336 switch (textureFormat)
1337 {
1338 case GL_ALPHA:
1339 if (colorbufferFormat != GL_ALPHA &&
1340 colorbufferFormat != GL_RGBA &&
1341 colorbufferFormat != GL_RGBA4 &&
1342 colorbufferFormat != GL_RGB5_A1 &&
1343 colorbufferFormat != GL_RGBA8_OES)
1344 {
1345 return error(GL_INVALID_OPERATION);
1346 }
1347 break;
1348 case GL_LUMINANCE:
1349 case GL_RGB:
1350 if (colorbufferFormat != GL_RGB &&
1351 colorbufferFormat != GL_RGB565 &&
1352 colorbufferFormat != GL_RGB8_OES &&
1353 colorbufferFormat != GL_RGBA &&
1354 colorbufferFormat != GL_RGBA4 &&
1355 colorbufferFormat != GL_RGB5_A1 &&
1356 colorbufferFormat != GL_RGBA8_OES)
1357 {
1358 return error(GL_INVALID_OPERATION);
1359 }
1360 break;
1361 case GL_LUMINANCE_ALPHA:
1362 case GL_RGBA:
1363 if (colorbufferFormat != GL_RGBA &&
1364 colorbufferFormat != GL_RGBA4 &&
1365 colorbufferFormat != GL_RGB5_A1 &&
1366 colorbufferFormat != GL_RGBA8_OES)
1367 {
1368 return error(GL_INVALID_OPERATION);
1369 }
1370 break;
1371 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1372 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001373 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1374 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001375 return error(GL_INVALID_OPERATION);
1376 default:
1377 return error(GL_INVALID_OPERATION);
1378 }
1379
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001380 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001381 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001382 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001383
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001384 catch(std::bad_alloc&)
1385 {
1386 return error(GL_OUT_OF_MEMORY);
1387 }
1388}
1389
1390GLuint __stdcall glCreateProgram(void)
1391{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001392 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001393
1394 try
1395 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001396 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001397
1398 if (context)
1399 {
1400 return context->createProgram();
1401 }
1402 }
1403 catch(std::bad_alloc&)
1404 {
1405 return error(GL_OUT_OF_MEMORY, 0);
1406 }
1407
1408 return 0;
1409}
1410
1411GLuint __stdcall glCreateShader(GLenum type)
1412{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001413 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001414
1415 try
1416 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001417 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001418
1419 if (context)
1420 {
1421 switch (type)
1422 {
1423 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001424 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001425 return context->createShader(type);
1426 default:
1427 return error(GL_INVALID_ENUM, 0);
1428 }
1429 }
1430 }
1431 catch(std::bad_alloc&)
1432 {
1433 return error(GL_OUT_OF_MEMORY, 0);
1434 }
1435
1436 return 0;
1437}
1438
1439void __stdcall glCullFace(GLenum mode)
1440{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001441 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001442
1443 try
1444 {
1445 switch (mode)
1446 {
1447 case GL_FRONT:
1448 case GL_BACK:
1449 case GL_FRONT_AND_BACK:
1450 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001451 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001452
1453 if (context)
1454 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001455 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001456 }
1457 }
1458 break;
1459 default:
1460 return error(GL_INVALID_ENUM);
1461 }
1462 }
1463 catch(std::bad_alloc&)
1464 {
1465 return error(GL_OUT_OF_MEMORY);
1466 }
1467}
1468
1469void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1470{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001471 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001472
1473 try
1474 {
1475 if (n < 0)
1476 {
1477 return error(GL_INVALID_VALUE);
1478 }
1479
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001480 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001481
1482 if (context)
1483 {
1484 for (int i = 0; i < n; i++)
1485 {
1486 context->deleteBuffer(buffers[i]);
1487 }
1488 }
1489 }
1490 catch(std::bad_alloc&)
1491 {
1492 return error(GL_OUT_OF_MEMORY);
1493 }
1494}
1495
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001496void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1497{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001498 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001499
1500 try
1501 {
1502 if (n < 0)
1503 {
1504 return error(GL_INVALID_VALUE);
1505 }
1506
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001507 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001508
1509 if (context)
1510 {
1511 for (int i = 0; i < n; i++)
1512 {
1513 context->deleteFence(fences[i]);
1514 }
1515 }
1516 }
1517 catch(std::bad_alloc&)
1518 {
1519 return error(GL_OUT_OF_MEMORY);
1520 }
1521}
1522
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001523void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1524{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001525 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001526
1527 try
1528 {
1529 if (n < 0)
1530 {
1531 return error(GL_INVALID_VALUE);
1532 }
1533
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001534 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001535
1536 if (context)
1537 {
1538 for (int i = 0; i < n; i++)
1539 {
1540 if (framebuffers[i] != 0)
1541 {
1542 context->deleteFramebuffer(framebuffers[i]);
1543 }
1544 }
1545 }
1546 }
1547 catch(std::bad_alloc&)
1548 {
1549 return error(GL_OUT_OF_MEMORY);
1550 }
1551}
1552
1553void __stdcall glDeleteProgram(GLuint program)
1554{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001555 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001556
1557 try
1558 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001559 if (program == 0)
1560 {
1561 return;
1562 }
1563
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001564 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001565
1566 if (context)
1567 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001568 if (!context->getProgram(program))
1569 {
1570 if(context->getShader(program))
1571 {
1572 return error(GL_INVALID_OPERATION);
1573 }
1574 else
1575 {
1576 return error(GL_INVALID_VALUE);
1577 }
1578 }
1579
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001580 context->deleteProgram(program);
1581 }
1582 }
1583 catch(std::bad_alloc&)
1584 {
1585 return error(GL_OUT_OF_MEMORY);
1586 }
1587}
1588
1589void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1590{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001591 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001592
1593 try
1594 {
1595 if (n < 0)
1596 {
1597 return error(GL_INVALID_VALUE);
1598 }
1599
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001600 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001601
1602 if (context)
1603 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001604 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001605 {
1606 context->deleteRenderbuffer(renderbuffers[i]);
1607 }
1608 }
1609 }
1610 catch(std::bad_alloc&)
1611 {
1612 return error(GL_OUT_OF_MEMORY);
1613 }
1614}
1615
1616void __stdcall glDeleteShader(GLuint shader)
1617{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001618 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001619
1620 try
1621 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001622 if (shader == 0)
1623 {
1624 return;
1625 }
1626
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001627 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001628
1629 if (context)
1630 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001631 if (!context->getShader(shader))
1632 {
1633 if(context->getProgram(shader))
1634 {
1635 return error(GL_INVALID_OPERATION);
1636 }
1637 else
1638 {
1639 return error(GL_INVALID_VALUE);
1640 }
1641 }
1642
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001643 context->deleteShader(shader);
1644 }
1645 }
1646 catch(std::bad_alloc&)
1647 {
1648 return error(GL_OUT_OF_MEMORY);
1649 }
1650}
1651
1652void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1653{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001654 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001655
1656 try
1657 {
1658 if (n < 0)
1659 {
1660 return error(GL_INVALID_VALUE);
1661 }
1662
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001663 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001664
1665 if (context)
1666 {
1667 for (int i = 0; i < n; i++)
1668 {
1669 if (textures[i] != 0)
1670 {
1671 context->deleteTexture(textures[i]);
1672 }
1673 }
1674 }
1675 }
1676 catch(std::bad_alloc&)
1677 {
1678 return error(GL_OUT_OF_MEMORY);
1679 }
1680}
1681
1682void __stdcall glDepthFunc(GLenum func)
1683{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001684 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001685
1686 try
1687 {
1688 switch (func)
1689 {
1690 case GL_NEVER:
1691 case GL_ALWAYS:
1692 case GL_LESS:
1693 case GL_LEQUAL:
1694 case GL_EQUAL:
1695 case GL_GREATER:
1696 case GL_GEQUAL:
1697 case GL_NOTEQUAL:
1698 break;
1699 default:
1700 return error(GL_INVALID_ENUM);
1701 }
1702
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001703 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001704
1705 if (context)
1706 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001707 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001708 }
1709 }
1710 catch(std::bad_alloc&)
1711 {
1712 return error(GL_OUT_OF_MEMORY);
1713 }
1714}
1715
1716void __stdcall glDepthMask(GLboolean flag)
1717{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001718 EVENT("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001719
1720 try
1721 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001722 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001723
1724 if (context)
1725 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001726 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001727 }
1728 }
1729 catch(std::bad_alloc&)
1730 {
1731 return error(GL_OUT_OF_MEMORY);
1732 }
1733}
1734
1735void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1736{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001737 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001738
1739 try
1740 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001741 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001742
1743 if (context)
1744 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001745 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001746 }
1747 }
1748 catch(std::bad_alloc&)
1749 {
1750 return error(GL_OUT_OF_MEMORY);
1751 }
1752}
1753
1754void __stdcall glDetachShader(GLuint program, GLuint shader)
1755{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001756 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001757
1758 try
1759 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001760 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001761
1762 if (context)
1763 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001764
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001765 gl::Program *programObject = context->getProgram(program);
1766 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001767
1768 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001769 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001770 gl::Shader *shaderByProgramHandle;
1771 shaderByProgramHandle = context->getShader(program);
1772 if (!shaderByProgramHandle)
1773 {
1774 return error(GL_INVALID_VALUE);
1775 }
1776 else
1777 {
1778 return error(GL_INVALID_OPERATION);
1779 }
1780 }
1781
1782 if (!shaderObject)
1783 {
1784 gl::Program *programByShaderHandle = context->getProgram(shader);
1785 if (!programByShaderHandle)
1786 {
1787 return error(GL_INVALID_VALUE);
1788 }
1789 else
1790 {
1791 return error(GL_INVALID_OPERATION);
1792 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001793 }
1794
1795 if (!programObject->detachShader(shaderObject))
1796 {
1797 return error(GL_INVALID_OPERATION);
1798 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001799 }
1800 }
1801 catch(std::bad_alloc&)
1802 {
1803 return error(GL_OUT_OF_MEMORY);
1804 }
1805}
1806
1807void __stdcall glDisable(GLenum cap)
1808{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001809 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001810
1811 try
1812 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001813 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001814
1815 if (context)
1816 {
1817 switch (cap)
1818 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001819 case GL_CULL_FACE: context->setCullFace(false); break;
1820 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1821 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1822 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1823 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1824 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1825 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1826 case GL_BLEND: context->setBlend(false); break;
1827 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001828 default:
1829 return error(GL_INVALID_ENUM);
1830 }
1831 }
1832 }
1833 catch(std::bad_alloc&)
1834 {
1835 return error(GL_OUT_OF_MEMORY);
1836 }
1837}
1838
1839void __stdcall glDisableVertexAttribArray(GLuint index)
1840{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001841 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001842
1843 try
1844 {
1845 if (index >= gl::MAX_VERTEX_ATTRIBS)
1846 {
1847 return error(GL_INVALID_VALUE);
1848 }
1849
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001850 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001851
1852 if (context)
1853 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001854 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001855 }
1856 }
1857 catch(std::bad_alloc&)
1858 {
1859 return error(GL_OUT_OF_MEMORY);
1860 }
1861}
1862
1863void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1864{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001865 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001866
1867 try
1868 {
1869 if (count < 0 || first < 0)
1870 {
1871 return error(GL_INVALID_VALUE);
1872 }
1873
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001874 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001875
1876 if (context)
1877 {
1878 context->drawArrays(mode, first, count);
1879 }
1880 }
1881 catch(std::bad_alloc&)
1882 {
1883 return error(GL_OUT_OF_MEMORY);
1884 }
1885}
1886
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001887void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001888{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001889 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 +00001890 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001891
1892 try
1893 {
1894 if (count < 0)
1895 {
1896 return error(GL_INVALID_VALUE);
1897 }
1898
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001899 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001900
1901 if (context)
1902 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001903 switch (type)
1904 {
1905 case GL_UNSIGNED_BYTE:
1906 case GL_UNSIGNED_SHORT:
1907 break;
1908 case GL_UNSIGNED_INT:
1909 if (!context->supports32bitIndices())
1910 {
1911 return error(GL_INVALID_ENUM);
1912 }
1913 break;
1914 default:
1915 return error(GL_INVALID_ENUM);
1916 }
1917
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001918 context->drawElements(mode, count, type, indices);
1919 }
1920 }
1921 catch(std::bad_alloc&)
1922 {
1923 return error(GL_OUT_OF_MEMORY);
1924 }
1925}
1926
1927void __stdcall glEnable(GLenum cap)
1928{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001929 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001930
1931 try
1932 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001933 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001934
1935 if (context)
1936 {
1937 switch (cap)
1938 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001939 case GL_CULL_FACE: context->setCullFace(true); break;
1940 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1941 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1942 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1943 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1944 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1945 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1946 case GL_BLEND: context->setBlend(true); break;
1947 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001948 default:
1949 return error(GL_INVALID_ENUM);
1950 }
1951 }
1952 }
1953 catch(std::bad_alloc&)
1954 {
1955 return error(GL_OUT_OF_MEMORY);
1956 }
1957}
1958
1959void __stdcall glEnableVertexAttribArray(GLuint index)
1960{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001961 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001962
1963 try
1964 {
1965 if (index >= gl::MAX_VERTEX_ATTRIBS)
1966 {
1967 return error(GL_INVALID_VALUE);
1968 }
1969
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001970 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001971
1972 if (context)
1973 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001974 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001975 }
1976 }
1977 catch(std::bad_alloc&)
1978 {
1979 return error(GL_OUT_OF_MEMORY);
1980 }
1981}
1982
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001983void __stdcall glFinishFenceNV(GLuint fence)
1984{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001985 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001986
1987 try
1988 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001989 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001990
1991 if (context)
1992 {
1993 gl::Fence* fenceObject = context->getFence(fence);
1994
1995 if (fenceObject == NULL)
1996 {
1997 return error(GL_INVALID_OPERATION);
1998 }
1999
2000 fenceObject->finishFence();
2001 }
2002 }
2003 catch(std::bad_alloc&)
2004 {
2005 return error(GL_OUT_OF_MEMORY);
2006 }
2007}
2008
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002009void __stdcall glFinish(void)
2010{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002011 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002012
2013 try
2014 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002015 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002016
2017 if (context)
2018 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002019 context->sync(true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002020 }
2021 }
2022 catch(std::bad_alloc&)
2023 {
2024 return error(GL_OUT_OF_MEMORY);
2025 }
2026}
2027
2028void __stdcall glFlush(void)
2029{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002030 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002031
2032 try
2033 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002034 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002035
2036 if (context)
2037 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002038 context->sync(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002039 }
2040 }
2041 catch(std::bad_alloc&)
2042 {
2043 return error(GL_OUT_OF_MEMORY);
2044 }
2045}
2046
2047void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2048{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002049 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002050 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002051
2052 try
2053 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002054 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002055 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002056 {
2057 return error(GL_INVALID_ENUM);
2058 }
2059
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002060 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002061
2062 if (context)
2063 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002064 gl::Framebuffer *framebuffer = NULL;
2065 GLuint framebufferHandle = 0;
2066 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2067 {
2068 framebuffer = context->getReadFramebuffer();
2069 framebufferHandle = context->getReadFramebufferHandle();
2070 }
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002071 else
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002072 {
2073 framebuffer = context->getDrawFramebuffer();
2074 framebufferHandle = context->getDrawFramebufferHandle();
2075 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002076
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002077 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002078 {
2079 return error(GL_INVALID_OPERATION);
2080 }
2081
2082 switch (attachment)
2083 {
2084 case GL_COLOR_ATTACHMENT0:
2085 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2086 break;
2087 case GL_DEPTH_ATTACHMENT:
2088 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2089 break;
2090 case GL_STENCIL_ATTACHMENT:
2091 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2092 break;
2093 default:
2094 return error(GL_INVALID_ENUM);
2095 }
2096 }
2097 }
2098 catch(std::bad_alloc&)
2099 {
2100 return error(GL_OUT_OF_MEMORY);
2101 }
2102}
2103
2104void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2105{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002106 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002107 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002108
2109 try
2110 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002111 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002112 {
2113 return error(GL_INVALID_ENUM);
2114 }
2115
2116 switch (attachment)
2117 {
2118 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002119 case GL_DEPTH_ATTACHMENT:
2120 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002121 break;
2122 default:
2123 return error(GL_INVALID_ENUM);
2124 }
2125
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002126 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002127
2128 if (context)
2129 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002130 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002131 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002132 textarget = GL_NONE;
2133 }
2134 else
2135 {
2136 gl::Texture *tex = context->getTexture(texture);
2137
2138 if (tex == NULL)
2139 {
2140 return error(GL_INVALID_OPERATION);
2141 }
2142
daniel@transgaming.com01868132010-08-24 19:21:17 +00002143 if (tex->isCompressed())
2144 {
2145 return error(GL_INVALID_OPERATION);
2146 }
2147
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002148 switch (textarget)
2149 {
2150 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002151 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002152 {
2153 return error(GL_INVALID_OPERATION);
2154 }
2155 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002156
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002157 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002158 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002159 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002160 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002161 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002162 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002163 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2164 {
2165 return error(GL_INVALID_OPERATION);
2166 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002167 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002168
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002169 default:
2170 return error(GL_INVALID_ENUM);
2171 }
2172
2173 if (level != 0)
2174 {
2175 return error(GL_INVALID_VALUE);
2176 }
2177 }
2178
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002179 gl::Framebuffer *framebuffer = NULL;
2180 GLuint framebufferHandle = 0;
2181 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2182 {
2183 framebuffer = context->getReadFramebuffer();
2184 framebufferHandle = context->getReadFramebufferHandle();
2185 }
2186 else
2187 {
2188 framebuffer = context->getDrawFramebuffer();
2189 framebufferHandle = context->getDrawFramebufferHandle();
2190 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002191
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002192 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002193 {
2194 return error(GL_INVALID_OPERATION);
2195 }
2196
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002197 switch (attachment)
2198 {
2199 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2200 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2201 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2202 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002203 }
2204 }
2205 catch(std::bad_alloc&)
2206 {
2207 return error(GL_OUT_OF_MEMORY);
2208 }
2209}
2210
2211void __stdcall glFrontFace(GLenum mode)
2212{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002213 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002214
2215 try
2216 {
2217 switch (mode)
2218 {
2219 case GL_CW:
2220 case GL_CCW:
2221 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002222 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002223
2224 if (context)
2225 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002226 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002227 }
2228 }
2229 break;
2230 default:
2231 return error(GL_INVALID_ENUM);
2232 }
2233 }
2234 catch(std::bad_alloc&)
2235 {
2236 return error(GL_OUT_OF_MEMORY);
2237 }
2238}
2239
2240void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2241{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002242 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002243
2244 try
2245 {
2246 if (n < 0)
2247 {
2248 return error(GL_INVALID_VALUE);
2249 }
2250
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002251 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002252
2253 if (context)
2254 {
2255 for (int i = 0; i < n; i++)
2256 {
2257 buffers[i] = context->createBuffer();
2258 }
2259 }
2260 }
2261 catch(std::bad_alloc&)
2262 {
2263 return error(GL_OUT_OF_MEMORY);
2264 }
2265}
2266
2267void __stdcall glGenerateMipmap(GLenum target)
2268{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002269 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002270
2271 try
2272 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002273 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002274
2275 if (context)
2276 {
2277 gl::Texture *texture;
2278
2279 switch (target)
2280 {
2281 case GL_TEXTURE_2D:
2282 texture = context->getTexture2D();
2283 break;
2284
2285 case GL_TEXTURE_CUBE_MAP:
2286 texture = context->getTextureCubeMap();
2287 break;
2288
2289 default:
2290 return error(GL_INVALID_ENUM);
2291 }
2292
daniel@transgaming.com01868132010-08-24 19:21:17 +00002293 if (texture->isCompressed())
2294 {
2295 return error(GL_INVALID_OPERATION);
2296 }
2297
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002298 texture->generateMipmaps();
2299 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002300 }
2301 catch(std::bad_alloc&)
2302 {
2303 return error(GL_OUT_OF_MEMORY);
2304 }
2305}
2306
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002307void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2308{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002309 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002310
2311 try
2312 {
2313 if (n < 0)
2314 {
2315 return error(GL_INVALID_VALUE);
2316 }
2317
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002318 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002319
2320 if (context)
2321 {
2322 for (int i = 0; i < n; i++)
2323 {
2324 fences[i] = context->createFence();
2325 }
2326 }
2327 }
2328 catch(std::bad_alloc&)
2329 {
2330 return error(GL_OUT_OF_MEMORY);
2331 }
2332}
2333
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002334void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2335{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002336 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002337
2338 try
2339 {
2340 if (n < 0)
2341 {
2342 return error(GL_INVALID_VALUE);
2343 }
2344
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002345 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002346
2347 if (context)
2348 {
2349 for (int i = 0; i < n; i++)
2350 {
2351 framebuffers[i] = context->createFramebuffer();
2352 }
2353 }
2354 }
2355 catch(std::bad_alloc&)
2356 {
2357 return error(GL_OUT_OF_MEMORY);
2358 }
2359}
2360
2361void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2362{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002363 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002364
2365 try
2366 {
2367 if (n < 0)
2368 {
2369 return error(GL_INVALID_VALUE);
2370 }
2371
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002372 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002373
2374 if (context)
2375 {
2376 for (int i = 0; i < n; i++)
2377 {
2378 renderbuffers[i] = context->createRenderbuffer();
2379 }
2380 }
2381 }
2382 catch(std::bad_alloc&)
2383 {
2384 return error(GL_OUT_OF_MEMORY);
2385 }
2386}
2387
2388void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2389{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002390 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002391
2392 try
2393 {
2394 if (n < 0)
2395 {
2396 return error(GL_INVALID_VALUE);
2397 }
2398
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002399 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002400
2401 if (context)
2402 {
2403 for (int i = 0; i < n; i++)
2404 {
2405 textures[i] = context->createTexture();
2406 }
2407 }
2408 }
2409 catch(std::bad_alloc&)
2410 {
2411 return error(GL_OUT_OF_MEMORY);
2412 }
2413}
2414
daniel@transgaming.com85423182010-04-22 13:35:27 +00002415void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002416{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002417 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002418 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002419 program, index, bufsize, length, size, type, name);
2420
2421 try
2422 {
2423 if (bufsize < 0)
2424 {
2425 return error(GL_INVALID_VALUE);
2426 }
2427
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002428 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com85423182010-04-22 13:35:27 +00002429
2430 if (context)
2431 {
2432 gl::Program *programObject = context->getProgram(program);
2433
2434 if (!programObject)
2435 {
2436 if (context->getShader(program))
2437 {
2438 return error(GL_INVALID_OPERATION);
2439 }
2440 else
2441 {
2442 return error(GL_INVALID_VALUE);
2443 }
2444 }
2445
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002446 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002447 {
2448 return error(GL_INVALID_VALUE);
2449 }
2450
2451 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2452 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002453 }
2454 catch(std::bad_alloc&)
2455 {
2456 return error(GL_OUT_OF_MEMORY);
2457 }
2458}
2459
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002460void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002461{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002462 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002463 "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 +00002464 program, index, bufsize, length, size, type, name);
2465
2466 try
2467 {
2468 if (bufsize < 0)
2469 {
2470 return error(GL_INVALID_VALUE);
2471 }
2472
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002473 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002474
2475 if (context)
2476 {
2477 gl::Program *programObject = context->getProgram(program);
2478
2479 if (!programObject)
2480 {
2481 if (context->getShader(program))
2482 {
2483 return error(GL_INVALID_OPERATION);
2484 }
2485 else
2486 {
2487 return error(GL_INVALID_VALUE);
2488 }
2489 }
2490
2491 if (index >= (GLuint)programObject->getActiveUniformCount())
2492 {
2493 return error(GL_INVALID_VALUE);
2494 }
2495
2496 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2497 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002498 }
2499 catch(std::bad_alloc&)
2500 {
2501 return error(GL_OUT_OF_MEMORY);
2502 }
2503}
2504
2505void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2506{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002507 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 +00002508 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002509
2510 try
2511 {
2512 if (maxcount < 0)
2513 {
2514 return error(GL_INVALID_VALUE);
2515 }
2516
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002517 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002518
2519 if (context)
2520 {
2521 gl::Program *programObject = context->getProgram(program);
2522
2523 if (!programObject)
2524 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002525 if (context->getShader(program))
2526 {
2527 return error(GL_INVALID_OPERATION);
2528 }
2529 else
2530 {
2531 return error(GL_INVALID_VALUE);
2532 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002533 }
2534
2535 return programObject->getAttachedShaders(maxcount, count, shaders);
2536 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002537 }
2538 catch(std::bad_alloc&)
2539 {
2540 return error(GL_OUT_OF_MEMORY);
2541 }
2542}
2543
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002544int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002545{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002546 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002547
2548 try
2549 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002550 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002551
2552 if (context)
2553 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002554
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002555 gl::Program *programObject = context->getProgram(program);
2556
2557 if (!programObject)
2558 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002559 if (context->getShader(program))
2560 {
2561 return error(GL_INVALID_OPERATION, -1);
2562 }
2563 else
2564 {
2565 return error(GL_INVALID_VALUE, -1);
2566 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002567 }
2568
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002569 if (!programObject->isLinked())
2570 {
2571 return error(GL_INVALID_OPERATION, -1);
2572 }
2573
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002574 return programObject->getAttributeLocation(name);
2575 }
2576 }
2577 catch(std::bad_alloc&)
2578 {
2579 return error(GL_OUT_OF_MEMORY, -1);
2580 }
2581
2582 return -1;
2583}
2584
2585void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2586{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002587 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002588
2589 try
2590 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002591 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002592
2593 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002594 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002595 if (!(context->getBooleanv(pname, params)))
2596 {
2597 GLenum nativeType;
2598 unsigned int numParams = 0;
2599 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2600 return error(GL_INVALID_ENUM);
2601
2602 if (numParams == 0)
2603 return; // it is known that the pname is valid, but there are no parameters to return
2604
2605 if (nativeType == GL_FLOAT)
2606 {
2607 GLfloat *floatParams = NULL;
2608 floatParams = new GLfloat[numParams];
2609
2610 context->getFloatv(pname, floatParams);
2611
2612 for (unsigned int i = 0; i < numParams; ++i)
2613 {
2614 if (floatParams[i] == 0.0f)
2615 params[i] = GL_FALSE;
2616 else
2617 params[i] = GL_TRUE;
2618 }
2619
2620 delete [] floatParams;
2621 }
2622 else if (nativeType == GL_INT)
2623 {
2624 GLint *intParams = NULL;
2625 intParams = new GLint[numParams];
2626
2627 context->getIntegerv(pname, intParams);
2628
2629 for (unsigned int i = 0; i < numParams; ++i)
2630 {
2631 if (intParams[i] == 0)
2632 params[i] = GL_FALSE;
2633 else
2634 params[i] = GL_TRUE;
2635 }
2636
2637 delete [] intParams;
2638 }
2639 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002640 }
2641 }
2642 catch(std::bad_alloc&)
2643 {
2644 return error(GL_OUT_OF_MEMORY);
2645 }
2646}
2647
2648void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2649{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002650 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 +00002651
2652 try
2653 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002654 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002655
2656 if (context)
2657 {
2658 gl::Buffer *buffer;
2659
2660 switch (target)
2661 {
2662 case GL_ARRAY_BUFFER:
2663 buffer = context->getArrayBuffer();
2664 break;
2665 case GL_ELEMENT_ARRAY_BUFFER:
2666 buffer = context->getElementArrayBuffer();
2667 break;
2668 default: return error(GL_INVALID_ENUM);
2669 }
2670
2671 if (!buffer)
2672 {
2673 // A null buffer means that "0" is bound to the requested buffer target
2674 return error(GL_INVALID_OPERATION);
2675 }
2676
2677 switch (pname)
2678 {
2679 case GL_BUFFER_USAGE:
2680 *params = buffer->usage();
2681 break;
2682 case GL_BUFFER_SIZE:
2683 *params = buffer->size();
2684 break;
2685 default: return error(GL_INVALID_ENUM);
2686 }
2687 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002688 }
2689 catch(std::bad_alloc&)
2690 {
2691 return error(GL_OUT_OF_MEMORY);
2692 }
2693}
2694
2695GLenum __stdcall glGetError(void)
2696{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002697 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002698
2699 gl::Context *context = gl::getContext();
2700
2701 if (context)
2702 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002703 if (context->isContextLost())
2704 return GL_OUT_OF_MEMORY;
2705 else
2706 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002707 }
2708
2709 return GL_NO_ERROR;
2710}
2711
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002712void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2713{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002714 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002715
2716 try
2717 {
2718
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002719 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002720
2721 if (context)
2722 {
2723 gl::Fence *fenceObject = context->getFence(fence);
2724
2725 if (fenceObject == NULL)
2726 {
2727 return error(GL_INVALID_OPERATION);
2728 }
2729
2730 fenceObject->getFenceiv(pname, params);
2731 }
2732 }
2733 catch(std::bad_alloc&)
2734 {
2735 return error(GL_OUT_OF_MEMORY);
2736 }
2737}
2738
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002739void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2740{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002741 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002742
2743 try
2744 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002745 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002746
2747 if (context)
2748 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002749 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002750 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002751 GLenum nativeType;
2752 unsigned int numParams = 0;
2753 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2754 return error(GL_INVALID_ENUM);
2755
2756 if (numParams == 0)
2757 return; // it is known that the pname is valid, but that there are no parameters to return.
2758
2759 if (nativeType == GL_BOOL)
2760 {
2761 GLboolean *boolParams = NULL;
2762 boolParams = new GLboolean[numParams];
2763
2764 context->getBooleanv(pname, boolParams);
2765
2766 for (unsigned int i = 0; i < numParams; ++i)
2767 {
2768 if (boolParams[i] == GL_FALSE)
2769 params[i] = 0.0f;
2770 else
2771 params[i] = 1.0f;
2772 }
2773
2774 delete [] boolParams;
2775 }
2776 else if (nativeType == GL_INT)
2777 {
2778 GLint *intParams = NULL;
2779 intParams = new GLint[numParams];
2780
2781 context->getIntegerv(pname, intParams);
2782
2783 for (unsigned int i = 0; i < numParams; ++i)
2784 {
2785 params[i] = (GLfloat)intParams[i];
2786 }
2787
2788 delete [] intParams;
2789 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002790 }
2791 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002792 }
2793 catch(std::bad_alloc&)
2794 {
2795 return error(GL_OUT_OF_MEMORY);
2796 }
2797}
2798
2799void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2800{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002801 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 +00002802 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002803
2804 try
2805 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002806 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002807
2808 if (context)
2809 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002810 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002811 {
2812 return error(GL_INVALID_ENUM);
2813 }
2814
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002815 gl::Framebuffer *framebuffer = NULL;
2816 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2817 {
2818 if(context->getReadFramebufferHandle() == 0)
2819 {
2820 return error(GL_INVALID_OPERATION);
2821 }
2822
2823 framebuffer = context->getReadFramebuffer();
2824 }
2825 else
2826 {
2827 if (context->getDrawFramebufferHandle() == 0)
2828 {
2829 return error(GL_INVALID_OPERATION);
2830 }
2831
2832 framebuffer = context->getDrawFramebuffer();
2833 }
2834
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002835 GLenum attachmentType;
2836 GLuint attachmentHandle;
2837 switch (attachment)
2838 {
2839 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002840 attachmentType = framebuffer->getColorbufferType();
2841 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002842 break;
2843 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002844 attachmentType = framebuffer->getDepthbufferType();
2845 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002846 break;
2847 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002848 attachmentType = framebuffer->getStencilbufferType();
2849 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002850 break;
2851 default: return error(GL_INVALID_ENUM);
2852 }
2853
2854 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002855 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002856 {
2857 attachmentObjectType = attachmentType;
2858 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002859 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002860 {
2861 attachmentObjectType = GL_TEXTURE;
2862 }
2863 else UNREACHABLE();
2864
2865 switch (pname)
2866 {
2867 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2868 *params = attachmentObjectType;
2869 break;
2870 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2871 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2872 {
2873 *params = attachmentHandle;
2874 }
2875 else
2876 {
2877 return error(GL_INVALID_ENUM);
2878 }
2879 break;
2880 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2881 if (attachmentObjectType == GL_TEXTURE)
2882 {
2883 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2884 }
2885 else
2886 {
2887 return error(GL_INVALID_ENUM);
2888 }
2889 break;
2890 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2891 if (attachmentObjectType == GL_TEXTURE)
2892 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002893 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002894 {
2895 *params = attachmentType;
2896 }
2897 else
2898 {
2899 *params = 0;
2900 }
2901 }
2902 else
2903 {
2904 return error(GL_INVALID_ENUM);
2905 }
2906 break;
2907 default:
2908 return error(GL_INVALID_ENUM);
2909 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002910 }
2911 }
2912 catch(std::bad_alloc&)
2913 {
2914 return error(GL_OUT_OF_MEMORY);
2915 }
2916}
2917
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00002918GLenum __stdcall glGetGraphicsResetStatusEXT(void)
2919{
2920 EVENT("()");
2921
2922 try
2923 {
2924 gl::Context *context = gl::getContext();
2925
2926 if (context)
2927 {
2928 return context->getResetStatus();
2929 }
2930
2931 return GL_NO_ERROR;
2932 }
2933 catch(std::bad_alloc&)
2934 {
2935 return GL_OUT_OF_MEMORY;
2936 }
2937}
2938
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002939void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2940{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002941 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002942
2943 try
2944 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002945 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002946
2947 if (context)
2948 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002949 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002950 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002951 GLenum nativeType;
2952 unsigned int numParams = 0;
2953 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2954 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002955
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002956 if (numParams == 0)
2957 return; // it is known that pname is valid, but there are no parameters to return
2958
2959 if (nativeType == GL_BOOL)
2960 {
2961 GLboolean *boolParams = NULL;
2962 boolParams = new GLboolean[numParams];
2963
2964 context->getBooleanv(pname, boolParams);
2965
2966 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002967 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002968 if (boolParams[i] == GL_FALSE)
2969 params[i] = 0;
2970 else
2971 params[i] = 1;
2972 }
2973
2974 delete [] boolParams;
2975 }
2976 else if (nativeType == GL_FLOAT)
2977 {
2978 GLfloat *floatParams = NULL;
2979 floatParams = new GLfloat[numParams];
2980
2981 context->getFloatv(pname, floatParams);
2982
2983 for (unsigned int i = 0; i < numParams; ++i)
2984 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002985 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 +00002986 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002987 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002988 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002989 else
2990 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 +00002991 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002992
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002993 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002994 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002995 }
2996 }
2997 }
2998 catch(std::bad_alloc&)
2999 {
3000 return error(GL_OUT_OF_MEMORY);
3001 }
3002}
3003
3004void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3005{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003006 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003007
3008 try
3009 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003010 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003011
3012 if (context)
3013 {
3014 gl::Program *programObject = context->getProgram(program);
3015
3016 if (!programObject)
3017 {
3018 return error(GL_INVALID_VALUE);
3019 }
3020
3021 switch (pname)
3022 {
3023 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003024 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003025 return;
3026 case GL_LINK_STATUS:
3027 *params = programObject->isLinked();
3028 return;
3029 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003030 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003031 return;
3032 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003033 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003034 return;
3035 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003036 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003037 return;
3038 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003039 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003040 return;
3041 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003042 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003043 return;
3044 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003045 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003046 return;
3047 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003048 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003049 return;
3050 default:
3051 return error(GL_INVALID_ENUM);
3052 }
3053 }
3054 }
3055 catch(std::bad_alloc&)
3056 {
3057 return error(GL_OUT_OF_MEMORY);
3058 }
3059}
3060
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003061void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003062{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003063 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 +00003064 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003065
3066 try
3067 {
3068 if (bufsize < 0)
3069 {
3070 return error(GL_INVALID_VALUE);
3071 }
3072
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003073 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003074
3075 if (context)
3076 {
3077 gl::Program *programObject = context->getProgram(program);
3078
3079 if (!programObject)
3080 {
3081 return error(GL_INVALID_VALUE);
3082 }
3083
3084 programObject->getInfoLog(bufsize, length, infolog);
3085 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003086 }
3087 catch(std::bad_alloc&)
3088 {
3089 return error(GL_OUT_OF_MEMORY);
3090 }
3091}
3092
3093void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3094{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003095 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 +00003096
3097 try
3098 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003099 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003100
3101 if (context)
3102 {
3103 if (target != GL_RENDERBUFFER)
3104 {
3105 return error(GL_INVALID_ENUM);
3106 }
3107
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003108 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003109 {
3110 return error(GL_INVALID_OPERATION);
3111 }
3112
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003113 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003114
3115 switch (pname)
3116 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003117 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3118 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3119 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3120 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3121 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3122 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3123 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3124 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3125 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003126 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003127 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003128 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003129 *params = renderbuffer->getSamples();
3130 }
3131 else
3132 {
3133 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003134 }
3135 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003136 default:
3137 return error(GL_INVALID_ENUM);
3138 }
3139 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003140 }
3141 catch(std::bad_alloc&)
3142 {
3143 return error(GL_OUT_OF_MEMORY);
3144 }
3145}
3146
3147void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3148{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003149 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003150
3151 try
3152 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003153 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003154
3155 if (context)
3156 {
3157 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003158
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003159 if (!shaderObject)
3160 {
3161 return error(GL_INVALID_VALUE);
3162 }
3163
3164 switch (pname)
3165 {
3166 case GL_SHADER_TYPE:
3167 *params = shaderObject->getType();
3168 return;
3169 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003170 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003171 return;
3172 case GL_COMPILE_STATUS:
3173 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3174 return;
3175 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003176 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003177 return;
3178 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003179 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003180 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003181 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3182 *params = shaderObject->getTranslatedSourceLength();
3183 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003184 default:
3185 return error(GL_INVALID_ENUM);
3186 }
3187 }
3188 }
3189 catch(std::bad_alloc&)
3190 {
3191 return error(GL_OUT_OF_MEMORY);
3192 }
3193}
3194
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003195void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003196{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003197 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 +00003198 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003199
3200 try
3201 {
3202 if (bufsize < 0)
3203 {
3204 return error(GL_INVALID_VALUE);
3205 }
3206
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003207 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003208
3209 if (context)
3210 {
3211 gl::Shader *shaderObject = context->getShader(shader);
3212
3213 if (!shaderObject)
3214 {
3215 return error(GL_INVALID_VALUE);
3216 }
3217
3218 shaderObject->getInfoLog(bufsize, length, infolog);
3219 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003220 }
3221 catch(std::bad_alloc&)
3222 {
3223 return error(GL_OUT_OF_MEMORY);
3224 }
3225}
3226
3227void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3228{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003229 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 +00003230 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003231
3232 try
3233 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003234 switch (shadertype)
3235 {
3236 case GL_VERTEX_SHADER:
3237 case GL_FRAGMENT_SHADER:
3238 break;
3239 default:
3240 return error(GL_INVALID_ENUM);
3241 }
3242
3243 switch (precisiontype)
3244 {
3245 case GL_LOW_FLOAT:
3246 case GL_MEDIUM_FLOAT:
3247 case GL_HIGH_FLOAT:
3248 // Assume IEEE 754 precision
3249 range[0] = 127;
3250 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003251 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003252 break;
3253 case GL_LOW_INT:
3254 case GL_MEDIUM_INT:
3255 case GL_HIGH_INT:
3256 // Some (most) hardware only supports single-precision floating-point numbers,
3257 // which can accurately represent integers up to +/-16777216
3258 range[0] = 24;
3259 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003260 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003261 break;
3262 default:
3263 return error(GL_INVALID_ENUM);
3264 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003265 }
3266 catch(std::bad_alloc&)
3267 {
3268 return error(GL_OUT_OF_MEMORY);
3269 }
3270}
3271
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003272void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003273{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003274 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 +00003275 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003276
3277 try
3278 {
3279 if (bufsize < 0)
3280 {
3281 return error(GL_INVALID_VALUE);
3282 }
3283
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003284 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003285
3286 if (context)
3287 {
3288 gl::Shader *shaderObject = context->getShader(shader);
3289
3290 if (!shaderObject)
3291 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003292 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003293 }
3294
3295 shaderObject->getSource(bufsize, length, source);
3296 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003297 }
3298 catch(std::bad_alloc&)
3299 {
3300 return error(GL_OUT_OF_MEMORY);
3301 }
3302}
3303
zmo@google.coma574f782011-10-03 21:45:23 +00003304void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3305{
3306 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3307 shader, bufsize, length, source);
3308
3309 try
3310 {
3311 if (bufsize < 0)
3312 {
3313 return error(GL_INVALID_VALUE);
3314 }
3315
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003316 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003317
3318 if (context)
3319 {
3320 gl::Shader *shaderObject = context->getShader(shader);
3321
3322 if (!shaderObject)
3323 {
3324 return error(GL_INVALID_OPERATION);
3325 }
3326
3327 shaderObject->getTranslatedSource(bufsize, length, source);
3328 }
3329 }
3330 catch(std::bad_alloc&)
3331 {
3332 return error(GL_OUT_OF_MEMORY);
3333 }
3334}
3335
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003336const GLubyte* __stdcall glGetString(GLenum name)
3337{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003338 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003339
3340 try
3341 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003342 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003343
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003344 switch (name)
3345 {
3346 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003347 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003348 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003349 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003350 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003351 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003352 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003353 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003354 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003355 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003356 default:
3357 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3358 }
3359 }
3360 catch(std::bad_alloc&)
3361 {
3362 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3363 }
3364
3365 return NULL;
3366}
3367
3368void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3369{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003370 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 +00003371
3372 try
3373 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003374 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003375
3376 if (context)
3377 {
3378 gl::Texture *texture;
3379
3380 switch (target)
3381 {
3382 case GL_TEXTURE_2D:
3383 texture = context->getTexture2D();
3384 break;
3385 case GL_TEXTURE_CUBE_MAP:
3386 texture = context->getTextureCubeMap();
3387 break;
3388 default:
3389 return error(GL_INVALID_ENUM);
3390 }
3391
3392 switch (pname)
3393 {
3394 case GL_TEXTURE_MAG_FILTER:
3395 *params = (GLfloat)texture->getMagFilter();
3396 break;
3397 case GL_TEXTURE_MIN_FILTER:
3398 *params = (GLfloat)texture->getMinFilter();
3399 break;
3400 case GL_TEXTURE_WRAP_S:
3401 *params = (GLfloat)texture->getWrapS();
3402 break;
3403 case GL_TEXTURE_WRAP_T:
3404 *params = (GLfloat)texture->getWrapT();
3405 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003406 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3407 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3408 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003409 case GL_TEXTURE_USAGE_ANGLE:
3410 *params = (GLfloat)texture->getUsage();
3411 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003412 default:
3413 return error(GL_INVALID_ENUM);
3414 }
3415 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003416 }
3417 catch(std::bad_alloc&)
3418 {
3419 return error(GL_OUT_OF_MEMORY);
3420 }
3421}
3422
3423void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3424{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003425 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 +00003426
3427 try
3428 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003429 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003430
3431 if (context)
3432 {
3433 gl::Texture *texture;
3434
3435 switch (target)
3436 {
3437 case GL_TEXTURE_2D:
3438 texture = context->getTexture2D();
3439 break;
3440 case GL_TEXTURE_CUBE_MAP:
3441 texture = context->getTextureCubeMap();
3442 break;
3443 default:
3444 return error(GL_INVALID_ENUM);
3445 }
3446
3447 switch (pname)
3448 {
3449 case GL_TEXTURE_MAG_FILTER:
3450 *params = texture->getMagFilter();
3451 break;
3452 case GL_TEXTURE_MIN_FILTER:
3453 *params = texture->getMinFilter();
3454 break;
3455 case GL_TEXTURE_WRAP_S:
3456 *params = texture->getWrapS();
3457 break;
3458 case GL_TEXTURE_WRAP_T:
3459 *params = texture->getWrapT();
3460 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003461 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3462 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3463 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003464 case GL_TEXTURE_USAGE_ANGLE:
3465 *params = texture->getUsage();
3466 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003467 default:
3468 return error(GL_INVALID_ENUM);
3469 }
3470 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003471 }
3472 catch(std::bad_alloc&)
3473 {
3474 return error(GL_OUT_OF_MEMORY);
3475 }
3476}
3477
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003478void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3479{
3480 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3481 program, location, bufSize, params);
3482
3483 try
3484 {
3485 if (bufSize < 0)
3486 {
3487 return error(GL_INVALID_VALUE);
3488 }
3489
3490 gl::Context *context = gl::getNonLostContext();
3491
3492 if (context)
3493 {
3494 if (program == 0)
3495 {
3496 return error(GL_INVALID_VALUE);
3497 }
3498
3499 gl::Program *programObject = context->getProgram(program);
3500
3501 if (!programObject || !programObject->isLinked())
3502 {
3503 return error(GL_INVALID_OPERATION);
3504 }
3505
3506 if (!programObject->getUniformfv(location, &bufSize, params))
3507 {
3508 return error(GL_INVALID_OPERATION);
3509 }
3510 }
3511 }
3512 catch(std::bad_alloc&)
3513 {
3514 return error(GL_OUT_OF_MEMORY);
3515 }
3516}
3517
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003518void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3519{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003520 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003521
3522 try
3523 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003524 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003525
3526 if (context)
3527 {
3528 if (program == 0)
3529 {
3530 return error(GL_INVALID_VALUE);
3531 }
3532
3533 gl::Program *programObject = context->getProgram(program);
3534
3535 if (!programObject || !programObject->isLinked())
3536 {
3537 return error(GL_INVALID_OPERATION);
3538 }
3539
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003540 if (!programObject->getUniformfv(location, NULL, params))
3541 {
3542 return error(GL_INVALID_OPERATION);
3543 }
3544 }
3545 }
3546 catch(std::bad_alloc&)
3547 {
3548 return error(GL_OUT_OF_MEMORY);
3549 }
3550}
3551
3552void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3553{
3554 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3555 program, location, bufSize, params);
3556
3557 try
3558 {
3559 if (bufSize < 0)
3560 {
3561 return error(GL_INVALID_VALUE);
3562 }
3563
3564 gl::Context *context = gl::getNonLostContext();
3565
3566 if (context)
3567 {
3568 if (program == 0)
3569 {
3570 return error(GL_INVALID_VALUE);
3571 }
3572
3573 gl::Program *programObject = context->getProgram(program);
3574
3575 if (!programObject || !programObject->isLinked())
3576 {
3577 return error(GL_INVALID_OPERATION);
3578 }
3579
3580 if (!programObject)
3581 {
3582 return error(GL_INVALID_OPERATION);
3583 }
3584
3585 if (!programObject->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003586 {
3587 return error(GL_INVALID_OPERATION);
3588 }
3589 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003590 }
3591 catch(std::bad_alloc&)
3592 {
3593 return error(GL_OUT_OF_MEMORY);
3594 }
3595}
3596
3597void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3598{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003599 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003600
3601 try
3602 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003603 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003604
3605 if (context)
3606 {
3607 if (program == 0)
3608 {
3609 return error(GL_INVALID_VALUE);
3610 }
3611
3612 gl::Program *programObject = context->getProgram(program);
3613
3614 if (!programObject || !programObject->isLinked())
3615 {
3616 return error(GL_INVALID_OPERATION);
3617 }
3618
3619 if (!programObject)
3620 {
3621 return error(GL_INVALID_OPERATION);
3622 }
3623
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003624 if (!programObject->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003625 {
3626 return error(GL_INVALID_OPERATION);
3627 }
3628 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003629 }
3630 catch(std::bad_alloc&)
3631 {
3632 return error(GL_OUT_OF_MEMORY);
3633 }
3634}
3635
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003636int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003637{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003638 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003639
3640 try
3641 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003642 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003643
3644 if (strstr(name, "gl_") == name)
3645 {
3646 return -1;
3647 }
3648
3649 if (context)
3650 {
3651 gl::Program *programObject = context->getProgram(program);
3652
3653 if (!programObject)
3654 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003655 if (context->getShader(program))
3656 {
3657 return error(GL_INVALID_OPERATION, -1);
3658 }
3659 else
3660 {
3661 return error(GL_INVALID_VALUE, -1);
3662 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003663 }
3664
3665 if (!programObject->isLinked())
3666 {
3667 return error(GL_INVALID_OPERATION, -1);
3668 }
3669
daniel@transgaming.com024f1a92011-09-20 16:06:25 +00003670 return programObject->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003671 }
3672 }
3673 catch(std::bad_alloc&)
3674 {
3675 return error(GL_OUT_OF_MEMORY, -1);
3676 }
3677
3678 return -1;
3679}
3680
3681void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3682{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003683 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003684
3685 try
3686 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003687 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003688
daniel@transgaming.come0078962010-04-15 20:45:08 +00003689 if (context)
3690 {
3691 if (index >= gl::MAX_VERTEX_ATTRIBS)
3692 {
3693 return error(GL_INVALID_VALUE);
3694 }
3695
daniel@transgaming.com83921382011-01-08 05:46:00 +00003696 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003697
daniel@transgaming.come0078962010-04-15 20:45:08 +00003698 switch (pname)
3699 {
3700 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003701 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003702 break;
3703 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003704 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003705 break;
3706 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003707 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003708 break;
3709 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003710 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003711 break;
3712 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003713 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003714 break;
3715 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003716 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003717 break;
3718 case GL_CURRENT_VERTEX_ATTRIB:
3719 for (int i = 0; i < 4; ++i)
3720 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003721 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003722 }
3723 break;
3724 default: return error(GL_INVALID_ENUM);
3725 }
3726 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003727 }
3728 catch(std::bad_alloc&)
3729 {
3730 return error(GL_OUT_OF_MEMORY);
3731 }
3732}
3733
3734void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3735{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003736 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003737
3738 try
3739 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003740 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003741
daniel@transgaming.come0078962010-04-15 20:45:08 +00003742 if (context)
3743 {
3744 if (index >= gl::MAX_VERTEX_ATTRIBS)
3745 {
3746 return error(GL_INVALID_VALUE);
3747 }
3748
daniel@transgaming.com83921382011-01-08 05:46:00 +00003749 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003750
daniel@transgaming.come0078962010-04-15 20:45:08 +00003751 switch (pname)
3752 {
3753 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003754 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003755 break;
3756 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003757 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003758 break;
3759 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003760 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003761 break;
3762 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003763 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003764 break;
3765 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003766 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003767 break;
3768 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003769 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003770 break;
3771 case GL_CURRENT_VERTEX_ATTRIB:
3772 for (int i = 0; i < 4; ++i)
3773 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003774 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003775 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3776 }
3777 break;
3778 default: return error(GL_INVALID_ENUM);
3779 }
3780 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003781 }
3782 catch(std::bad_alloc&)
3783 {
3784 return error(GL_OUT_OF_MEMORY);
3785 }
3786}
3787
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003788void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003789{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003790 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003791
3792 try
3793 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003794 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003795
daniel@transgaming.come0078962010-04-15 20:45:08 +00003796 if (context)
3797 {
3798 if (index >= gl::MAX_VERTEX_ATTRIBS)
3799 {
3800 return error(GL_INVALID_VALUE);
3801 }
3802
3803 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3804 {
3805 return error(GL_INVALID_ENUM);
3806 }
3807
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003808 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003809 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003810 }
3811 catch(std::bad_alloc&)
3812 {
3813 return error(GL_OUT_OF_MEMORY);
3814 }
3815}
3816
3817void __stdcall glHint(GLenum target, GLenum mode)
3818{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003819 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003820
3821 try
3822 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003823 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003824 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003825 case GL_FASTEST:
3826 case GL_NICEST:
3827 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003828 break;
3829 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003830 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003831 }
3832
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003833 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003834 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003835 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003836 case GL_GENERATE_MIPMAP_HINT:
3837 if (context) context->setGenerateMipmapHint(mode);
3838 break;
3839 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3840 if (context) context->setFragmentShaderDerivativeHint(mode);
3841 break;
3842 default:
3843 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003844 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003845 }
3846 catch(std::bad_alloc&)
3847 {
3848 return error(GL_OUT_OF_MEMORY);
3849 }
3850}
3851
3852GLboolean __stdcall glIsBuffer(GLuint buffer)
3853{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003854 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003855
3856 try
3857 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003858 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003859
3860 if (context && buffer)
3861 {
3862 gl::Buffer *bufferObject = context->getBuffer(buffer);
3863
3864 if (bufferObject)
3865 {
3866 return GL_TRUE;
3867 }
3868 }
3869 }
3870 catch(std::bad_alloc&)
3871 {
3872 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3873 }
3874
3875 return GL_FALSE;
3876}
3877
3878GLboolean __stdcall glIsEnabled(GLenum cap)
3879{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003880 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003881
3882 try
3883 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003884 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003885
3886 if (context)
3887 {
3888 switch (cap)
3889 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003890 case GL_CULL_FACE: return context->isCullFaceEnabled();
3891 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3892 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3893 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3894 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3895 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3896 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3897 case GL_BLEND: return context->isBlendEnabled();
3898 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003899 default:
3900 return error(GL_INVALID_ENUM, false);
3901 }
3902 }
3903 }
3904 catch(std::bad_alloc&)
3905 {
3906 return error(GL_OUT_OF_MEMORY, false);
3907 }
3908
3909 return false;
3910}
3911
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003912GLboolean __stdcall glIsFenceNV(GLuint fence)
3913{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003914 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003915
3916 try
3917 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003918 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003919
3920 if (context)
3921 {
3922 gl::Fence *fenceObject = context->getFence(fence);
3923
3924 if (fenceObject == NULL)
3925 {
3926 return GL_FALSE;
3927 }
3928
3929 return fenceObject->isFence();
3930 }
3931 }
3932 catch(std::bad_alloc&)
3933 {
3934 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3935 }
3936
3937 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003938}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003939
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003940GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3941{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003942 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003943
3944 try
3945 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003946 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003947
3948 if (context && framebuffer)
3949 {
3950 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3951
3952 if (framebufferObject)
3953 {
3954 return GL_TRUE;
3955 }
3956 }
3957 }
3958 catch(std::bad_alloc&)
3959 {
3960 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3961 }
3962
3963 return GL_FALSE;
3964}
3965
3966GLboolean __stdcall glIsProgram(GLuint program)
3967{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003968 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003969
3970 try
3971 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003972 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003973
3974 if (context && program)
3975 {
3976 gl::Program *programObject = context->getProgram(program);
3977
3978 if (programObject)
3979 {
3980 return GL_TRUE;
3981 }
3982 }
3983 }
3984 catch(std::bad_alloc&)
3985 {
3986 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3987 }
3988
3989 return GL_FALSE;
3990}
3991
3992GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3993{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003994 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003995
3996 try
3997 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003998 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003999
4000 if (context && renderbuffer)
4001 {
4002 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4003
4004 if (renderbufferObject)
4005 {
4006 return GL_TRUE;
4007 }
4008 }
4009 }
4010 catch(std::bad_alloc&)
4011 {
4012 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4013 }
4014
4015 return GL_FALSE;
4016}
4017
4018GLboolean __stdcall glIsShader(GLuint shader)
4019{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004020 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004021
4022 try
4023 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004024 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004025
4026 if (context && shader)
4027 {
4028 gl::Shader *shaderObject = context->getShader(shader);
4029
4030 if (shaderObject)
4031 {
4032 return GL_TRUE;
4033 }
4034 }
4035 }
4036 catch(std::bad_alloc&)
4037 {
4038 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4039 }
4040
4041 return GL_FALSE;
4042}
4043
4044GLboolean __stdcall glIsTexture(GLuint texture)
4045{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004046 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004047
4048 try
4049 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004050 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004051
4052 if (context && texture)
4053 {
4054 gl::Texture *textureObject = context->getTexture(texture);
4055
4056 if (textureObject)
4057 {
4058 return GL_TRUE;
4059 }
4060 }
4061 }
4062 catch(std::bad_alloc&)
4063 {
4064 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4065 }
4066
4067 return GL_FALSE;
4068}
4069
4070void __stdcall glLineWidth(GLfloat width)
4071{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004072 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004073
4074 try
4075 {
4076 if (width <= 0.0f)
4077 {
4078 return error(GL_INVALID_VALUE);
4079 }
4080
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004081 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004082
4083 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004084 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004085 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004086 }
4087 }
4088 catch(std::bad_alloc&)
4089 {
4090 return error(GL_OUT_OF_MEMORY);
4091 }
4092}
4093
4094void __stdcall glLinkProgram(GLuint program)
4095{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004096 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004097
4098 try
4099 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004100 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004101
4102 if (context)
4103 {
4104 gl::Program *programObject = context->getProgram(program);
4105
4106 if (!programObject)
4107 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004108 if (context->getShader(program))
4109 {
4110 return error(GL_INVALID_OPERATION);
4111 }
4112 else
4113 {
4114 return error(GL_INVALID_VALUE);
4115 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004116 }
4117
4118 programObject->link();
4119 }
4120 }
4121 catch(std::bad_alloc&)
4122 {
4123 return error(GL_OUT_OF_MEMORY);
4124 }
4125}
4126
4127void __stdcall glPixelStorei(GLenum pname, GLint param)
4128{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004129 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004130
4131 try
4132 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004133 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004134
4135 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004136 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004137 switch (pname)
4138 {
4139 case GL_UNPACK_ALIGNMENT:
4140 if (param != 1 && param != 2 && param != 4 && param != 8)
4141 {
4142 return error(GL_INVALID_VALUE);
4143 }
4144
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004145 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004146 break;
4147
4148 case GL_PACK_ALIGNMENT:
4149 if (param != 1 && param != 2 && param != 4 && param != 8)
4150 {
4151 return error(GL_INVALID_VALUE);
4152 }
4153
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004154 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004155 break;
4156
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004157 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4158 context->setPackReverseRowOrder(param != 0);
4159 break;
4160
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004161 default:
4162 return error(GL_INVALID_ENUM);
4163 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004164 }
4165 }
4166 catch(std::bad_alloc&)
4167 {
4168 return error(GL_OUT_OF_MEMORY);
4169 }
4170}
4171
4172void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4173{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004174 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004175
4176 try
4177 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004178 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004179
4180 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004181 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004182 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004183 }
4184 }
4185 catch(std::bad_alloc&)
4186 {
4187 return error(GL_OUT_OF_MEMORY);
4188 }
4189}
4190
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004191void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4192 GLenum format, GLenum type, GLsizei bufSize,
4193 GLvoid *data)
4194{
4195 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4196 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4197 x, y, width, height, format, type, bufSize, data);
4198
4199 try
4200 {
4201 if (width < 0 || height < 0 || bufSize < 0)
4202 {
4203 return error(GL_INVALID_VALUE);
4204 }
4205
4206 if (!validReadFormatType(format, type))
4207 {
4208 return error(GL_INVALID_OPERATION);
4209 }
4210
4211 gl::Context *context = gl::getNonLostContext();
4212
4213 if (context)
4214 {
4215 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4216 }
4217 }
4218 catch(std::bad_alloc&)
4219 {
4220 return error(GL_OUT_OF_MEMORY);
4221 }
4222}
4223
4224void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4225 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004226{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004227 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004228 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004229 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004230
4231 try
4232 {
4233 if (width < 0 || height < 0)
4234 {
4235 return error(GL_INVALID_VALUE);
4236 }
4237
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004238 if (!validReadFormatType(format, type))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004239 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004240 return error(GL_INVALID_OPERATION);
4241 }
4242
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004243 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004244
4245 if (context)
4246 {
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004247 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004248 }
4249 }
4250 catch(std::bad_alloc&)
4251 {
4252 return error(GL_OUT_OF_MEMORY);
4253 }
4254}
4255
4256void __stdcall glReleaseShaderCompiler(void)
4257{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004258 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004259
4260 try
4261 {
4262 gl::Shader::releaseCompiler();
4263 }
4264 catch(std::bad_alloc&)
4265 {
4266 return error(GL_OUT_OF_MEMORY);
4267 }
4268}
4269
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004270void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004271{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004272 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 +00004273 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004274
4275 try
4276 {
4277 switch (target)
4278 {
4279 case GL_RENDERBUFFER:
4280 break;
4281 default:
4282 return error(GL_INVALID_ENUM);
4283 }
4284
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004285 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004286 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004287 return error(GL_INVALID_ENUM);
4288 }
4289
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004290 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004291 {
4292 return error(GL_INVALID_VALUE);
4293 }
4294
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004295 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004296
4297 if (context)
4298 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004299 if (width > context->getMaximumRenderbufferDimension() ||
4300 height > context->getMaximumRenderbufferDimension() ||
4301 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004302 {
4303 return error(GL_INVALID_VALUE);
4304 }
4305
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004306 GLuint handle = context->getRenderbufferHandle();
4307 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004308 {
4309 return error(GL_INVALID_OPERATION);
4310 }
4311
4312 switch (internalformat)
4313 {
4314 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004315 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004316 break;
4317 case GL_RGBA4:
4318 case GL_RGB5_A1:
4319 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004320 case GL_RGB8_OES:
4321 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004322 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004323 break;
4324 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004325 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004326 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004327 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004328 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004329 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004330 default:
4331 return error(GL_INVALID_ENUM);
4332 }
4333 }
4334 }
4335 catch(std::bad_alloc&)
4336 {
4337 return error(GL_OUT_OF_MEMORY);
4338 }
4339}
4340
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004341void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4342{
4343 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4344}
4345
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004346void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4347{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004348 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004349
4350 try
4351 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004352 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004353
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004354 if (context)
4355 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004356 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004357 }
4358 }
4359 catch(std::bad_alloc&)
4360 {
4361 return error(GL_OUT_OF_MEMORY);
4362 }
4363}
4364
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004365void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4366{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004367 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004368
4369 try
4370 {
4371 if (condition != GL_ALL_COMPLETED_NV)
4372 {
4373 return error(GL_INVALID_ENUM);
4374 }
4375
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004376 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004377
4378 if (context)
4379 {
4380 gl::Fence *fenceObject = context->getFence(fence);
4381
4382 if (fenceObject == NULL)
4383 {
4384 return error(GL_INVALID_OPERATION);
4385 }
4386
4387 fenceObject->setFence(condition);
4388 }
4389 }
4390 catch(std::bad_alloc&)
4391 {
4392 return error(GL_OUT_OF_MEMORY);
4393 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004394}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004395
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004396void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4397{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004398 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 +00004399
4400 try
4401 {
4402 if (width < 0 || height < 0)
4403 {
4404 return error(GL_INVALID_VALUE);
4405 }
4406
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004407 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004408
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004409 if (context)
4410 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004411 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004412 }
4413 }
4414 catch(std::bad_alloc&)
4415 {
4416 return error(GL_OUT_OF_MEMORY);
4417 }
4418}
4419
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004420void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004421{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004422 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004423 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004424 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004425
4426 try
4427 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004428 // No binary shader formats are supported.
4429 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004430 }
4431 catch(std::bad_alloc&)
4432 {
4433 return error(GL_OUT_OF_MEMORY);
4434 }
4435}
4436
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004437void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004438{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004439 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 +00004440 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004441
4442 try
4443 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004444 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004445 {
4446 return error(GL_INVALID_VALUE);
4447 }
4448
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004449 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004450
4451 if (context)
4452 {
4453 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004454
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004455 if (!shaderObject)
4456 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004457 if (context->getProgram(shader))
4458 {
4459 return error(GL_INVALID_OPERATION);
4460 }
4461 else
4462 {
4463 return error(GL_INVALID_VALUE);
4464 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004465 }
4466
4467 shaderObject->setSource(count, string, length);
4468 }
4469 }
4470 catch(std::bad_alloc&)
4471 {
4472 return error(GL_OUT_OF_MEMORY);
4473 }
4474}
4475
4476void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4477{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004478 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004479}
4480
4481void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4482{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004483 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 +00004484
4485 try
4486 {
4487 switch (face)
4488 {
4489 case GL_FRONT:
4490 case GL_BACK:
4491 case GL_FRONT_AND_BACK:
4492 break;
4493 default:
4494 return error(GL_INVALID_ENUM);
4495 }
4496
4497 switch (func)
4498 {
4499 case GL_NEVER:
4500 case GL_ALWAYS:
4501 case GL_LESS:
4502 case GL_LEQUAL:
4503 case GL_EQUAL:
4504 case GL_GEQUAL:
4505 case GL_GREATER:
4506 case GL_NOTEQUAL:
4507 break;
4508 default:
4509 return error(GL_INVALID_ENUM);
4510 }
4511
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004512 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004513
4514 if (context)
4515 {
4516 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4517 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004518 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004519 }
4520
4521 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4522 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004523 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004524 }
4525 }
4526 }
4527 catch(std::bad_alloc&)
4528 {
4529 return error(GL_OUT_OF_MEMORY);
4530 }
4531}
4532
4533void __stdcall glStencilMask(GLuint mask)
4534{
4535 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4536}
4537
4538void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4539{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004540 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004541
4542 try
4543 {
4544 switch (face)
4545 {
4546 case GL_FRONT:
4547 case GL_BACK:
4548 case GL_FRONT_AND_BACK:
4549 break;
4550 default:
4551 return error(GL_INVALID_ENUM);
4552 }
4553
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004554 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004555
4556 if (context)
4557 {
4558 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4559 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004560 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004561 }
4562
4563 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4564 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004565 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004566 }
4567 }
4568 }
4569 catch(std::bad_alloc&)
4570 {
4571 return error(GL_OUT_OF_MEMORY);
4572 }
4573}
4574
4575void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4576{
4577 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4578}
4579
4580void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4581{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004582 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 +00004583 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004584
4585 try
4586 {
4587 switch (face)
4588 {
4589 case GL_FRONT:
4590 case GL_BACK:
4591 case GL_FRONT_AND_BACK:
4592 break;
4593 default:
4594 return error(GL_INVALID_ENUM);
4595 }
4596
4597 switch (fail)
4598 {
4599 case GL_ZERO:
4600 case GL_KEEP:
4601 case GL_REPLACE:
4602 case GL_INCR:
4603 case GL_DECR:
4604 case GL_INVERT:
4605 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004606 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004607 break;
4608 default:
4609 return error(GL_INVALID_ENUM);
4610 }
4611
4612 switch (zfail)
4613 {
4614 case GL_ZERO:
4615 case GL_KEEP:
4616 case GL_REPLACE:
4617 case GL_INCR:
4618 case GL_DECR:
4619 case GL_INVERT:
4620 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004621 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004622 break;
4623 default:
4624 return error(GL_INVALID_ENUM);
4625 }
4626
4627 switch (zpass)
4628 {
4629 case GL_ZERO:
4630 case GL_KEEP:
4631 case GL_REPLACE:
4632 case GL_INCR:
4633 case GL_DECR:
4634 case GL_INVERT:
4635 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004636 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004637 break;
4638 default:
4639 return error(GL_INVALID_ENUM);
4640 }
4641
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004642 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004643
4644 if (context)
4645 {
4646 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4647 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004648 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004649 }
4650
4651 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4652 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004653 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004654 }
4655 }
4656 }
4657 catch(std::bad_alloc&)
4658 {
4659 return error(GL_OUT_OF_MEMORY);
4660 }
4661}
4662
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004663GLboolean __stdcall glTestFenceNV(GLuint fence)
4664{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004665 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004666
4667 try
4668 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004669 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004670
4671 if (context)
4672 {
4673 gl::Fence *fenceObject = context->getFence(fence);
4674
4675 if (fenceObject == NULL)
4676 {
4677 return error(GL_INVALID_OPERATION, GL_TRUE);
4678 }
4679
4680 return fenceObject->testFence();
4681 }
4682 }
4683 catch(std::bad_alloc&)
4684 {
4685 error(GL_OUT_OF_MEMORY);
4686 }
4687
4688 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004689}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004690
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004691void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4692 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004693{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004694 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 +00004695 "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 +00004696 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004697
4698 try
4699 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00004700 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004701 {
4702 return error(GL_INVALID_VALUE);
4703 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004704
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004705 if (internalformat != format)
4706 {
4707 return error(GL_INVALID_OPERATION);
4708 }
4709
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004710 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004711 {
4712 case GL_ALPHA:
4713 case GL_LUMINANCE:
4714 case GL_LUMINANCE_ALPHA:
4715 switch (type)
4716 {
4717 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004718 case GL_FLOAT:
4719 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004720 break;
4721 default:
4722 return error(GL_INVALID_ENUM);
4723 }
4724 break;
4725 case GL_RGB:
4726 switch (type)
4727 {
4728 case GL_UNSIGNED_BYTE:
4729 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004730 case GL_FLOAT:
4731 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004732 break;
4733 default:
4734 return error(GL_INVALID_ENUM);
4735 }
4736 break;
4737 case GL_RGBA:
4738 switch (type)
4739 {
4740 case GL_UNSIGNED_BYTE:
4741 case GL_UNSIGNED_SHORT_4_4_4_4:
4742 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004743 case GL_FLOAT:
4744 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004745 break;
4746 default:
4747 return error(GL_INVALID_ENUM);
4748 }
4749 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004750 case GL_BGRA_EXT:
4751 switch (type)
4752 {
4753 case GL_UNSIGNED_BYTE:
4754 break;
4755 default:
4756 return error(GL_INVALID_ENUM);
4757 }
4758 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004759 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4760 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00004761 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4762 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00004763 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004764 default:
4765 return error(GL_INVALID_VALUE);
4766 }
4767
4768 if (border != 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.com32b11442011-11-19 02:42:48 +00004777 if (level > context->getMaximumTextureLevel())
4778 {
4779 return error(GL_INVALID_VALUE);
4780 }
4781
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004782 switch (target)
4783 {
4784 case GL_TEXTURE_2D:
4785 if (width > (context->getMaximumTextureDimension() >> level) ||
4786 height > (context->getMaximumTextureDimension() >> level))
4787 {
4788 return error(GL_INVALID_VALUE);
4789 }
4790 break;
4791 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4792 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4793 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4794 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4795 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4796 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4797 if (width != height)
4798 {
4799 return error(GL_INVALID_VALUE);
4800 }
4801
4802 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4803 height > (context->getMaximumCubeTextureDimension() >> level))
4804 {
4805 return error(GL_INVALID_VALUE);
4806 }
4807 break;
4808 default:
4809 return error(GL_INVALID_ENUM);
4810 }
4811
gman@chromium.org50c526d2011-08-10 05:19:44 +00004812 switch (format) {
4813 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
4814 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4815 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00004816 {
4817 return error(GL_INVALID_OPERATION);
4818 }
4819 else
4820 {
4821 return error(GL_INVALID_ENUM);
4822 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00004823 break;
4824 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4825 if (context->supportsDXT3Textures())
4826 {
4827 return error(GL_INVALID_OPERATION);
4828 }
4829 else
4830 {
4831 return error(GL_INVALID_ENUM);
4832 }
4833 break;
4834 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
4835 if (context->supportsDXT5Textures())
4836 {
4837 return error(GL_INVALID_OPERATION);
4838 }
4839 else
4840 {
4841 return error(GL_INVALID_ENUM);
4842 }
4843 break;
4844 default:
4845 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004846 }
4847
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004848 if (type == GL_FLOAT)
4849 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004850 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004851 {
4852 return error(GL_INVALID_ENUM);
4853 }
4854 }
4855 else if (type == GL_HALF_FLOAT_OES)
4856 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004857 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004858 {
4859 return error(GL_INVALID_ENUM);
4860 }
4861 }
4862
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004863 if (target == GL_TEXTURE_2D)
4864 {
4865 gl::Texture2D *texture = context->getTexture2D();
4866
4867 if (!texture)
4868 {
4869 return error(GL_INVALID_OPERATION);
4870 }
4871
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004872 if (texture->isImmutable())
4873 {
4874 return error(GL_INVALID_OPERATION);
4875 }
4876
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004877 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004878 }
4879 else
4880 {
4881 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4882
4883 if (!texture)
4884 {
4885 return error(GL_INVALID_OPERATION);
4886 }
4887
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004888 if (texture->isImmutable())
4889 {
4890 return error(GL_INVALID_OPERATION);
4891 }
4892
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004893 switch (target)
4894 {
4895 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004896 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004897 break;
4898 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004899 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004900 break;
4901 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004902 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004903 break;
4904 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004905 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004906 break;
4907 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004908 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004909 break;
4910 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004911 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004912 break;
4913 default: UNREACHABLE();
4914 }
4915 }
4916 }
4917 }
4918 catch(std::bad_alloc&)
4919 {
4920 return error(GL_OUT_OF_MEMORY);
4921 }
4922}
4923
4924void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4925{
4926 glTexParameteri(target, pname, (GLint)param);
4927}
4928
4929void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4930{
4931 glTexParameteri(target, pname, (GLint)*params);
4932}
4933
4934void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4935{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004936 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004937
4938 try
4939 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004940 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004941
4942 if (context)
4943 {
4944 gl::Texture *texture;
4945
4946 switch (target)
4947 {
4948 case GL_TEXTURE_2D:
4949 texture = context->getTexture2D();
4950 break;
4951 case GL_TEXTURE_CUBE_MAP:
4952 texture = context->getTextureCubeMap();
4953 break;
4954 default:
4955 return error(GL_INVALID_ENUM);
4956 }
4957
4958 switch (pname)
4959 {
4960 case GL_TEXTURE_WRAP_S:
4961 if (!texture->setWrapS((GLenum)param))
4962 {
4963 return error(GL_INVALID_ENUM);
4964 }
4965 break;
4966 case GL_TEXTURE_WRAP_T:
4967 if (!texture->setWrapT((GLenum)param))
4968 {
4969 return error(GL_INVALID_ENUM);
4970 }
4971 break;
4972 case GL_TEXTURE_MIN_FILTER:
4973 if (!texture->setMinFilter((GLenum)param))
4974 {
4975 return error(GL_INVALID_ENUM);
4976 }
4977 break;
4978 case GL_TEXTURE_MAG_FILTER:
4979 if (!texture->setMagFilter((GLenum)param))
4980 {
4981 return error(GL_INVALID_ENUM);
4982 }
4983 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00004984 case GL_TEXTURE_USAGE_ANGLE:
4985 if (!texture->setUsage((GLenum)param))
4986 {
4987 return error(GL_INVALID_ENUM);
4988 }
4989 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004990 default:
4991 return error(GL_INVALID_ENUM);
4992 }
4993 }
4994 }
4995 catch(std::bad_alloc&)
4996 {
4997 return error(GL_OUT_OF_MEMORY);
4998 }
4999}
5000
5001void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5002{
5003 glTexParameteri(target, pname, *params);
5004}
5005
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005006void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5007{
5008 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5009 target, levels, internalformat, width, height);
5010
5011 try
5012 {
5013 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5014 {
5015 return error(GL_INVALID_ENUM);
5016 }
5017
5018 if (width < 1 || height < 1 || levels < 1)
5019 {
5020 return error(GL_INVALID_VALUE);
5021 }
5022
5023 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5024 {
5025 return error(GL_INVALID_VALUE);
5026 }
5027
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005028 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005029 {
5030 return error(GL_INVALID_OPERATION);
5031 }
5032
5033 GLenum format = gl::ExtractFormat(internalformat);
5034 GLenum type = gl::ExtractType(internalformat);
5035
5036 if (format == GL_NONE || type == GL_NONE)
5037 {
5038 return error(GL_INVALID_ENUM);
5039 }
5040
5041 gl::Context *context = gl::getNonLostContext();
5042
5043 if (context)
5044 {
5045 if (levels != 1 && !context->supportsNonPower2Texture())
5046 {
5047 if (!gl::isPow2(width) || !gl::isPow2(height))
5048 {
5049 return error(GL_INVALID_OPERATION);
5050 }
5051 }
5052
daniel@transgaming.come1077362011-11-11 04:16:50 +00005053 switch (internalformat)
5054 {
5055 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5056 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5057 if (!context->supportsDXT1Textures())
5058 {
5059 return error(GL_INVALID_ENUM);
5060 }
5061 break;
5062 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5063 if (!context->supportsDXT3Textures())
5064 {
5065 return error(GL_INVALID_ENUM);
5066 }
5067 break;
5068 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5069 if (!context->supportsDXT5Textures())
5070 {
5071 return error(GL_INVALID_ENUM);
5072 }
5073 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005074 case GL_RGBA32F_EXT:
5075 case GL_RGB32F_EXT:
5076 case GL_ALPHA32F_EXT:
5077 case GL_LUMINANCE32F_EXT:
5078 case GL_LUMINANCE_ALPHA32F_EXT:
5079 if (!context->supportsFloat32Textures())
5080 {
5081 return error(GL_INVALID_ENUM);
5082 }
5083 break;
5084 case GL_RGBA16F_EXT:
5085 case GL_RGB16F_EXT:
5086 case GL_ALPHA16F_EXT:
5087 case GL_LUMINANCE16F_EXT:
5088 case GL_LUMINANCE_ALPHA16F_EXT:
5089 if (!context->supportsFloat16Textures())
5090 {
5091 return error(GL_INVALID_ENUM);
5092 }
5093 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005094 }
5095
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005096 if (target == GL_TEXTURE_2D)
5097 {
5098 gl::Texture2D *texture = context->getTexture2D();
5099
5100 if (!texture || texture->id() == 0)
5101 {
5102 return error(GL_INVALID_OPERATION);
5103 }
5104
5105 if (texture->isImmutable())
5106 {
5107 return error(GL_INVALID_OPERATION);
5108 }
5109
5110 texture->storage(levels, internalformat, width, height);
5111 }
5112 else if (target == GL_TEXTURE_CUBE_MAP)
5113 {
5114 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5115
5116 if (!texture || texture->id() == 0)
5117 {
5118 return error(GL_INVALID_OPERATION);
5119 }
5120
5121 if (texture->isImmutable())
5122 {
5123 return error(GL_INVALID_OPERATION);
5124 }
5125
5126 texture->storage(levels, internalformat, width);
5127 }
5128 else UNREACHABLE();
5129 }
5130 }
5131 catch(std::bad_alloc&)
5132 {
5133 return error(GL_OUT_OF_MEMORY);
5134 }
5135}
5136
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005137void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5138 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005139{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005140 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005141 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005142 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005143 target, level, xoffset, yoffset, width, height, format, type, pixels);
5144
5145 try
5146 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005147 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005148 {
5149 return error(GL_INVALID_ENUM);
5150 }
5151
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005152 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005153 {
5154 return error(GL_INVALID_VALUE);
5155 }
5156
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005157 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5158 {
5159 return error(GL_INVALID_VALUE);
5160 }
5161
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005162 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005163 {
5164 return error(GL_INVALID_ENUM);
5165 }
5166
5167 if (width == 0 || height == 0 || pixels == NULL)
5168 {
5169 return;
5170 }
5171
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005172 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005173
5174 if (context)
5175 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005176 if (level > context->getMaximumTextureLevel())
5177 {
5178 return error(GL_INVALID_VALUE);
5179 }
5180
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005181 if (format == GL_FLOAT)
5182 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005183 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005184 {
5185 return error(GL_INVALID_ENUM);
5186 }
5187 }
5188 else if (format == GL_HALF_FLOAT_OES)
5189 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005190 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005191 {
5192 return error(GL_INVALID_ENUM);
5193 }
5194 }
5195
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005196 if (target == GL_TEXTURE_2D)
5197 {
5198 gl::Texture2D *texture = context->getTexture2D();
5199
5200 if (!texture)
5201 {
5202 return error(GL_INVALID_OPERATION);
5203 }
5204
daniel@transgaming.com01868132010-08-24 19:21:17 +00005205 if (texture->isCompressed())
5206 {
5207 return error(GL_INVALID_OPERATION);
5208 }
5209
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00005210 if (format != texture->getInternalFormat())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005211 {
5212 return error(GL_INVALID_OPERATION);
5213 }
5214
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005215 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005216 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005217 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005218 {
5219 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5220
5221 if (!texture)
5222 {
5223 return error(GL_INVALID_OPERATION);
5224 }
5225
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005226 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005227 }
5228 else
5229 {
5230 UNREACHABLE();
5231 }
5232 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005233 }
5234 catch(std::bad_alloc&)
5235 {
5236 return error(GL_OUT_OF_MEMORY);
5237 }
5238}
5239
5240void __stdcall glUniform1f(GLint location, GLfloat x)
5241{
5242 glUniform1fv(location, 1, &x);
5243}
5244
5245void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5246{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005247 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005248
5249 try
5250 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005251 if (count < 0)
5252 {
5253 return error(GL_INVALID_VALUE);
5254 }
5255
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005256 if (location == -1)
5257 {
5258 return;
5259 }
5260
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005261 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005262
5263 if (context)
5264 {
5265 gl::Program *program = context->getCurrentProgram();
5266
5267 if (!program)
5268 {
5269 return error(GL_INVALID_OPERATION);
5270 }
5271
5272 if (!program->setUniform1fv(location, count, v))
5273 {
5274 return error(GL_INVALID_OPERATION);
5275 }
5276 }
5277 }
5278 catch(std::bad_alloc&)
5279 {
5280 return error(GL_OUT_OF_MEMORY);
5281 }
5282}
5283
5284void __stdcall glUniform1i(GLint location, GLint x)
5285{
5286 glUniform1iv(location, 1, &x);
5287}
5288
5289void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5290{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005291 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005292
5293 try
5294 {
5295 if (count < 0)
5296 {
5297 return error(GL_INVALID_VALUE);
5298 }
5299
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005300 if (location == -1)
5301 {
5302 return;
5303 }
5304
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005305 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005306
5307 if (context)
5308 {
5309 gl::Program *program = context->getCurrentProgram();
5310
5311 if (!program)
5312 {
5313 return error(GL_INVALID_OPERATION);
5314 }
5315
5316 if (!program->setUniform1iv(location, count, v))
5317 {
5318 return error(GL_INVALID_OPERATION);
5319 }
5320 }
5321 }
5322 catch(std::bad_alloc&)
5323 {
5324 return error(GL_OUT_OF_MEMORY);
5325 }
5326}
5327
5328void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5329{
5330 GLfloat xy[2] = {x, y};
5331
5332 glUniform2fv(location, 1, (GLfloat*)&xy);
5333}
5334
5335void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5336{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005337 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005338
5339 try
5340 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005341 if (count < 0)
5342 {
5343 return error(GL_INVALID_VALUE);
5344 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005345
5346 if (location == -1)
5347 {
5348 return;
5349 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005350
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005351 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005352
5353 if (context)
5354 {
5355 gl::Program *program = context->getCurrentProgram();
5356
5357 if (!program)
5358 {
5359 return error(GL_INVALID_OPERATION);
5360 }
5361
5362 if (!program->setUniform2fv(location, count, v))
5363 {
5364 return error(GL_INVALID_OPERATION);
5365 }
5366 }
5367 }
5368 catch(std::bad_alloc&)
5369 {
5370 return error(GL_OUT_OF_MEMORY);
5371 }
5372}
5373
5374void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5375{
5376 GLint xy[4] = {x, y};
5377
5378 glUniform2iv(location, 1, (GLint*)&xy);
5379}
5380
5381void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5382{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005383 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005384
5385 try
5386 {
5387 if (count < 0)
5388 {
5389 return error(GL_INVALID_VALUE);
5390 }
5391
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005392 if (location == -1)
5393 {
5394 return;
5395 }
5396
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005397 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005398
5399 if (context)
5400 {
5401 gl::Program *program = context->getCurrentProgram();
5402
5403 if (!program)
5404 {
5405 return error(GL_INVALID_OPERATION);
5406 }
5407
5408 if (!program->setUniform2iv(location, count, v))
5409 {
5410 return error(GL_INVALID_OPERATION);
5411 }
5412 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005413 }
5414 catch(std::bad_alloc&)
5415 {
5416 return error(GL_OUT_OF_MEMORY);
5417 }
5418}
5419
5420void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5421{
5422 GLfloat xyz[3] = {x, y, z};
5423
5424 glUniform3fv(location, 1, (GLfloat*)&xyz);
5425}
5426
5427void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5428{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005429 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005430
5431 try
5432 {
5433 if (count < 0)
5434 {
5435 return error(GL_INVALID_VALUE);
5436 }
5437
5438 if (location == -1)
5439 {
5440 return;
5441 }
5442
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005443 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005444
5445 if (context)
5446 {
5447 gl::Program *program = context->getCurrentProgram();
5448
5449 if (!program)
5450 {
5451 return error(GL_INVALID_OPERATION);
5452 }
5453
5454 if (!program->setUniform3fv(location, count, v))
5455 {
5456 return error(GL_INVALID_OPERATION);
5457 }
5458 }
5459 }
5460 catch(std::bad_alloc&)
5461 {
5462 return error(GL_OUT_OF_MEMORY);
5463 }
5464}
5465
5466void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5467{
5468 GLint xyz[3] = {x, y, z};
5469
5470 glUniform3iv(location, 1, (GLint*)&xyz);
5471}
5472
5473void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5474{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005475 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005476
5477 try
5478 {
5479 if (count < 0)
5480 {
5481 return error(GL_INVALID_VALUE);
5482 }
5483
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005484 if (location == -1)
5485 {
5486 return;
5487 }
5488
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005489 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005490
5491 if (context)
5492 {
5493 gl::Program *program = context->getCurrentProgram();
5494
5495 if (!program)
5496 {
5497 return error(GL_INVALID_OPERATION);
5498 }
5499
5500 if (!program->setUniform3iv(location, count, v))
5501 {
5502 return error(GL_INVALID_OPERATION);
5503 }
5504 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005505 }
5506 catch(std::bad_alloc&)
5507 {
5508 return error(GL_OUT_OF_MEMORY);
5509 }
5510}
5511
5512void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5513{
5514 GLfloat xyzw[4] = {x, y, z, w};
5515
5516 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5517}
5518
5519void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5520{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005521 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005522
5523 try
5524 {
5525 if (count < 0)
5526 {
5527 return error(GL_INVALID_VALUE);
5528 }
5529
5530 if (location == -1)
5531 {
5532 return;
5533 }
5534
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005535 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005536
5537 if (context)
5538 {
5539 gl::Program *program = context->getCurrentProgram();
5540
5541 if (!program)
5542 {
5543 return error(GL_INVALID_OPERATION);
5544 }
5545
5546 if (!program->setUniform4fv(location, count, v))
5547 {
5548 return error(GL_INVALID_OPERATION);
5549 }
5550 }
5551 }
5552 catch(std::bad_alloc&)
5553 {
5554 return error(GL_OUT_OF_MEMORY);
5555 }
5556}
5557
5558void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5559{
5560 GLint xyzw[4] = {x, y, z, w};
5561
5562 glUniform4iv(location, 1, (GLint*)&xyzw);
5563}
5564
5565void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5566{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005567 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005568
5569 try
5570 {
5571 if (count < 0)
5572 {
5573 return error(GL_INVALID_VALUE);
5574 }
5575
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005576 if (location == -1)
5577 {
5578 return;
5579 }
5580
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005581 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005582
5583 if (context)
5584 {
5585 gl::Program *program = context->getCurrentProgram();
5586
5587 if (!program)
5588 {
5589 return error(GL_INVALID_OPERATION);
5590 }
5591
5592 if (!program->setUniform4iv(location, count, v))
5593 {
5594 return error(GL_INVALID_OPERATION);
5595 }
5596 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005597 }
5598 catch(std::bad_alloc&)
5599 {
5600 return error(GL_OUT_OF_MEMORY);
5601 }
5602}
5603
5604void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5605{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005606 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005607 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005608
5609 try
5610 {
5611 if (count < 0 || transpose != GL_FALSE)
5612 {
5613 return error(GL_INVALID_VALUE);
5614 }
5615
5616 if (location == -1)
5617 {
5618 return;
5619 }
5620
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005621 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005622
5623 if (context)
5624 {
5625 gl::Program *program = context->getCurrentProgram();
5626
5627 if (!program)
5628 {
5629 return error(GL_INVALID_OPERATION);
5630 }
5631
5632 if (!program->setUniformMatrix2fv(location, count, value))
5633 {
5634 return error(GL_INVALID_OPERATION);
5635 }
5636 }
5637 }
5638 catch(std::bad_alloc&)
5639 {
5640 return error(GL_OUT_OF_MEMORY);
5641 }
5642}
5643
5644void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5645{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005646 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005647 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005648
5649 try
5650 {
5651 if (count < 0 || transpose != GL_FALSE)
5652 {
5653 return error(GL_INVALID_VALUE);
5654 }
5655
5656 if (location == -1)
5657 {
5658 return;
5659 }
5660
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005661 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005662
5663 if (context)
5664 {
5665 gl::Program *program = context->getCurrentProgram();
5666
5667 if (!program)
5668 {
5669 return error(GL_INVALID_OPERATION);
5670 }
5671
5672 if (!program->setUniformMatrix3fv(location, count, value))
5673 {
5674 return error(GL_INVALID_OPERATION);
5675 }
5676 }
5677 }
5678 catch(std::bad_alloc&)
5679 {
5680 return error(GL_OUT_OF_MEMORY);
5681 }
5682}
5683
5684void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5685{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005686 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005687 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005688
5689 try
5690 {
5691 if (count < 0 || transpose != GL_FALSE)
5692 {
5693 return error(GL_INVALID_VALUE);
5694 }
5695
5696 if (location == -1)
5697 {
5698 return;
5699 }
5700
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005701 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005702
5703 if (context)
5704 {
5705 gl::Program *program = context->getCurrentProgram();
5706
5707 if (!program)
5708 {
5709 return error(GL_INVALID_OPERATION);
5710 }
5711
5712 if (!program->setUniformMatrix4fv(location, count, value))
5713 {
5714 return error(GL_INVALID_OPERATION);
5715 }
5716 }
5717 }
5718 catch(std::bad_alloc&)
5719 {
5720 return error(GL_OUT_OF_MEMORY);
5721 }
5722}
5723
5724void __stdcall glUseProgram(GLuint program)
5725{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005726 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005727
5728 try
5729 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005730 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005731
5732 if (context)
5733 {
5734 gl::Program *programObject = context->getProgram(program);
5735
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005736 if (!programObject && program != 0)
5737 {
5738 if (context->getShader(program))
5739 {
5740 return error(GL_INVALID_OPERATION);
5741 }
5742 else
5743 {
5744 return error(GL_INVALID_VALUE);
5745 }
5746 }
5747
5748 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005749 {
5750 return error(GL_INVALID_OPERATION);
5751 }
5752
5753 context->useProgram(program);
5754 }
5755 }
5756 catch(std::bad_alloc&)
5757 {
5758 return error(GL_OUT_OF_MEMORY);
5759 }
5760}
5761
5762void __stdcall glValidateProgram(GLuint program)
5763{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005764 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005765
5766 try
5767 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005768 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005769
5770 if (context)
5771 {
5772 gl::Program *programObject = context->getProgram(program);
5773
5774 if (!programObject)
5775 {
5776 if (context->getShader(program))
5777 {
5778 return error(GL_INVALID_OPERATION);
5779 }
5780 else
5781 {
5782 return error(GL_INVALID_VALUE);
5783 }
5784 }
5785
5786 programObject->validate();
5787 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005788 }
5789 catch(std::bad_alloc&)
5790 {
5791 return error(GL_OUT_OF_MEMORY);
5792 }
5793}
5794
5795void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5796{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005797 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005798
5799 try
5800 {
5801 if (index >= gl::MAX_VERTEX_ATTRIBS)
5802 {
5803 return error(GL_INVALID_VALUE);
5804 }
5805
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005806 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005807
5808 if (context)
5809 {
5810 GLfloat vals[4] = { x, 0, 0, 1 };
5811 context->setVertexAttrib(index, vals);
5812 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005813 }
5814 catch(std::bad_alloc&)
5815 {
5816 return error(GL_OUT_OF_MEMORY);
5817 }
5818}
5819
5820void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5821{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005822 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005823
5824 try
5825 {
5826 if (index >= gl::MAX_VERTEX_ATTRIBS)
5827 {
5828 return error(GL_INVALID_VALUE);
5829 }
5830
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005831 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005832
5833 if (context)
5834 {
5835 GLfloat vals[4] = { values[0], 0, 0, 1 };
5836 context->setVertexAttrib(index, vals);
5837 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005838 }
5839 catch(std::bad_alloc&)
5840 {
5841 return error(GL_OUT_OF_MEMORY);
5842 }
5843}
5844
5845void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5846{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005847 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005848
5849 try
5850 {
5851 if (index >= gl::MAX_VERTEX_ATTRIBS)
5852 {
5853 return error(GL_INVALID_VALUE);
5854 }
5855
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005856 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005857
5858 if (context)
5859 {
5860 GLfloat vals[4] = { x, y, 0, 1 };
5861 context->setVertexAttrib(index, vals);
5862 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005863 }
5864 catch(std::bad_alloc&)
5865 {
5866 return error(GL_OUT_OF_MEMORY);
5867 }
5868}
5869
5870void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5871{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005872 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005873
5874 try
5875 {
5876 if (index >= gl::MAX_VERTEX_ATTRIBS)
5877 {
5878 return error(GL_INVALID_VALUE);
5879 }
5880
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005881 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005882
5883 if (context)
5884 {
5885 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5886 context->setVertexAttrib(index, vals);
5887 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005888 }
5889 catch(std::bad_alloc&)
5890 {
5891 return error(GL_OUT_OF_MEMORY);
5892 }
5893}
5894
5895void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5896{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005897 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 +00005898
5899 try
5900 {
5901 if (index >= gl::MAX_VERTEX_ATTRIBS)
5902 {
5903 return error(GL_INVALID_VALUE);
5904 }
5905
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005906 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005907
5908 if (context)
5909 {
5910 GLfloat vals[4] = { x, y, z, 1 };
5911 context->setVertexAttrib(index, vals);
5912 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005913 }
5914 catch(std::bad_alloc&)
5915 {
5916 return error(GL_OUT_OF_MEMORY);
5917 }
5918}
5919
5920void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5921{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005922 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005923
5924 try
5925 {
5926 if (index >= gl::MAX_VERTEX_ATTRIBS)
5927 {
5928 return error(GL_INVALID_VALUE);
5929 }
5930
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005931 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005932
5933 if (context)
5934 {
5935 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5936 context->setVertexAttrib(index, vals);
5937 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005938 }
5939 catch(std::bad_alloc&)
5940 {
5941 return error(GL_OUT_OF_MEMORY);
5942 }
5943}
5944
5945void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5946{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005947 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 +00005948
5949 try
5950 {
5951 if (index >= gl::MAX_VERTEX_ATTRIBS)
5952 {
5953 return error(GL_INVALID_VALUE);
5954 }
5955
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005956 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005957
5958 if (context)
5959 {
5960 GLfloat vals[4] = { x, y, z, w };
5961 context->setVertexAttrib(index, vals);
5962 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005963 }
5964 catch(std::bad_alloc&)
5965 {
5966 return error(GL_OUT_OF_MEMORY);
5967 }
5968}
5969
5970void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5971{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005972 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005973
5974 try
5975 {
5976 if (index >= gl::MAX_VERTEX_ATTRIBS)
5977 {
5978 return error(GL_INVALID_VALUE);
5979 }
5980
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005981 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005982
5983 if (context)
5984 {
5985 context->setVertexAttrib(index, values);
5986 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005987 }
5988 catch(std::bad_alloc&)
5989 {
5990 return error(GL_OUT_OF_MEMORY);
5991 }
5992}
5993
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005994void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005995{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005996 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005997 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005998 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005999
6000 try
6001 {
6002 if (index >= gl::MAX_VERTEX_ATTRIBS)
6003 {
6004 return error(GL_INVALID_VALUE);
6005 }
6006
6007 if (size < 1 || size > 4)
6008 {
6009 return error(GL_INVALID_VALUE);
6010 }
6011
6012 switch (type)
6013 {
6014 case GL_BYTE:
6015 case GL_UNSIGNED_BYTE:
6016 case GL_SHORT:
6017 case GL_UNSIGNED_SHORT:
6018 case GL_FIXED:
6019 case GL_FLOAT:
6020 break;
6021 default:
6022 return error(GL_INVALID_ENUM);
6023 }
6024
6025 if (stride < 0)
6026 {
6027 return error(GL_INVALID_VALUE);
6028 }
6029
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006030 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006031
6032 if (context)
6033 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006034 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006035 }
6036 }
6037 catch(std::bad_alloc&)
6038 {
6039 return error(GL_OUT_OF_MEMORY);
6040 }
6041}
6042
6043void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6044{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006045 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 +00006046
6047 try
6048 {
6049 if (width < 0 || height < 0)
6050 {
6051 return error(GL_INVALID_VALUE);
6052 }
6053
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006054 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006055
6056 if (context)
6057 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006058 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006059 }
6060 }
6061 catch(std::bad_alloc&)
6062 {
6063 return error(GL_OUT_OF_MEMORY);
6064 }
6065}
6066
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006067void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6068 GLbitfield mask, GLenum filter)
6069{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006070 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006071 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6072 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6073 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6074
6075 try
6076 {
6077 switch (filter)
6078 {
6079 case GL_NEAREST:
6080 break;
6081 default:
6082 return error(GL_INVALID_ENUM);
6083 }
6084
6085 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6086 {
6087 return error(GL_INVALID_VALUE);
6088 }
6089
6090 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6091 {
6092 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6093 return error(GL_INVALID_OPERATION);
6094 }
6095
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006096 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006097
6098 if (context)
6099 {
6100 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6101 {
6102 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6103 return error(GL_INVALID_OPERATION);
6104 }
6105
6106 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6107 }
6108 }
6109 catch(std::bad_alloc&)
6110 {
6111 return error(GL_OUT_OF_MEMORY);
6112 }
6113}
6114
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006115void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6116 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006117{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006118 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006119 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006120 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006121 target, level, internalformat, width, height, depth, border, format, type, pixels);
6122
6123 try
6124 {
6125 UNIMPLEMENTED(); // FIXME
6126 }
6127 catch(std::bad_alloc&)
6128 {
6129 return error(GL_OUT_OF_MEMORY);
6130 }
6131}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006132
6133__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6134{
6135 struct Extension
6136 {
6137 const char *name;
6138 __eglMustCastToProperFunctionPointerType address;
6139 };
6140
6141 static const Extension glExtensions[] =
6142 {
6143 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006144 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006145 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006146 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6147 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6148 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6149 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6150 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6151 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6152 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006153 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006154 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006155 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6156 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6157 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6158 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006159 };
6160
6161 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6162 {
6163 if (strcmp(procname, glExtensions[ext].name) == 0)
6164 {
6165 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6166 }
6167 }
6168
6169 return NULL;
6170}
6171
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006172// Non-public functions used by EGL
6173
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006174bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006175{
6176 EVENT("(egl::Surface* surface = 0x%0.8p)",
6177 surface);
6178
6179 try
6180 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006181 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006182
6183 if (context)
6184 {
6185 gl::Texture2D *textureObject = context->getTexture2D();
6186
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006187 if (textureObject->isImmutable())
6188 {
6189 return false;
6190 }
6191
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006192 if (textureObject)
6193 {
6194 textureObject->bindTexImage(surface);
6195 }
6196 }
6197 }
6198 catch(std::bad_alloc&)
6199 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006200 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006201 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006202
6203 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006204}
6205
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006206}