blob: 7ff1a635fd06ecad9d9d94671b06b7dfbb56cdb2 [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
1039 if ((width % 4 != 0 && width != texture->getWidth()) ||
1040 (height % 4 != 0 && height != texture->getHeight()))
1041 {
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
1061 if ((width % 4 != 0 && width != texture->getWidth()) ||
1062 (height % 4 != 0 && height != texture->getHeight()))
1063 {
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.com5d752f22010-10-07 13:37:20 +00001103 switch (target)
1104 {
1105 case GL_TEXTURE_2D:
1106 if (width > (context->getMaximumTextureDimension() >> level) ||
1107 height > (context->getMaximumTextureDimension() >> level))
1108 {
1109 return error(GL_INVALID_VALUE);
1110 }
1111 break;
1112 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1113 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1114 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1115 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1116 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1117 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1118 if (width != height)
1119 {
1120 return error(GL_INVALID_VALUE);
1121 }
1122
1123 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1124 height > (context->getMaximumCubeTextureDimension() >> level))
1125 {
1126 return error(GL_INVALID_VALUE);
1127 }
1128 break;
1129 default:
1130 return error(GL_INVALID_ENUM);
1131 }
1132
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001133 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001134
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001135 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1136 {
1137 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1138 }
1139
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001140 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1141 {
1142 return error(GL_INVALID_OPERATION);
1143 }
1144
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001145 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001146 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001147
1148 // [OpenGL ES 2.0.24] table 3.9
1149 switch (internalformat)
1150 {
1151 case GL_ALPHA:
1152 if (colorbufferFormat != GL_ALPHA &&
1153 colorbufferFormat != GL_RGBA &&
1154 colorbufferFormat != GL_RGBA4 &&
1155 colorbufferFormat != GL_RGB5_A1 &&
1156 colorbufferFormat != GL_RGBA8_OES)
1157 {
1158 return error(GL_INVALID_OPERATION);
1159 }
1160 break;
1161 case GL_LUMINANCE:
1162 case GL_RGB:
1163 if (colorbufferFormat != GL_RGB &&
1164 colorbufferFormat != GL_RGB565 &&
1165 colorbufferFormat != GL_RGB8_OES &&
1166 colorbufferFormat != GL_RGBA &&
1167 colorbufferFormat != GL_RGBA4 &&
1168 colorbufferFormat != GL_RGB5_A1 &&
1169 colorbufferFormat != GL_RGBA8_OES)
1170 {
1171 return error(GL_INVALID_OPERATION);
1172 }
1173 break;
1174 case GL_LUMINANCE_ALPHA:
1175 case GL_RGBA:
1176 if (colorbufferFormat != GL_RGBA &&
1177 colorbufferFormat != GL_RGBA4 &&
1178 colorbufferFormat != GL_RGB5_A1 &&
1179 colorbufferFormat != GL_RGBA8_OES)
1180 {
1181 return error(GL_INVALID_OPERATION);
1182 }
1183 break;
1184 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1185 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001186 if (context->supportsDXT1Textures())
1187 {
1188 return error(GL_INVALID_OPERATION);
1189 }
1190 else
1191 {
1192 return error(GL_INVALID_ENUM);
1193 }
1194 break;
1195 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1196 if (context->supportsDXT3Textures())
1197 {
1198 return error(GL_INVALID_OPERATION);
1199 }
1200 else
1201 {
1202 return error(GL_INVALID_ENUM);
1203 }
1204 break;
1205 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1206 if (context->supportsDXT5Textures())
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001207 {
1208 return error(GL_INVALID_OPERATION);
1209 }
1210 else
1211 {
1212 return error(GL_INVALID_ENUM);
1213 }
1214 break;
1215 default:
1216 return error(GL_INVALID_ENUM);
1217 }
1218
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001219 if (target == GL_TEXTURE_2D)
1220 {
1221 gl::Texture2D *texture = context->getTexture2D();
1222
1223 if (!texture)
1224 {
1225 return error(GL_INVALID_OPERATION);
1226 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001227
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001228 if (texture->isImmutable())
1229 {
1230 return error(GL_INVALID_OPERATION);
1231 }
1232
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001233 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001234 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001235 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001236 {
1237 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1238
1239 if (!texture)
1240 {
1241 return error(GL_INVALID_OPERATION);
1242 }
1243
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001244 if (texture->isImmutable())
1245 {
1246 return error(GL_INVALID_OPERATION);
1247 }
1248
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001249 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001250 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001251 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001252 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001253 }
1254 catch(std::bad_alloc&)
1255 {
1256 return error(GL_OUT_OF_MEMORY);
1257 }
1258}
1259
1260void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1261{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001262 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001263 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001264 target, level, xoffset, yoffset, x, y, width, height);
1265
1266 try
1267 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001268 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001269 {
1270 return error(GL_INVALID_ENUM);
1271 }
1272
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001273 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001274 {
1275 return error(GL_INVALID_VALUE);
1276 }
1277
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001278 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1279 {
1280 return error(GL_INVALID_VALUE);
1281 }
1282
1283 if (width == 0 || height == 0)
1284 {
1285 return;
1286 }
1287
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001288 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001289
1290 if (context)
1291 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001292 if (level > context->getMaximumTextureLevel())
1293 {
1294 return error(GL_INVALID_VALUE);
1295 }
1296
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001297 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001298
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001299 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1300 {
1301 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1302 }
1303
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001304 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1305 {
1306 return error(GL_INVALID_OPERATION);
1307 }
1308
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001309 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001310 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001311 gl::Texture *texture = NULL;
1312
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001313 if (target == GL_TEXTURE_2D)
1314 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001315 texture = context->getTexture2D();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001316 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001317 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001318 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001319 texture = context->getTextureCubeMap();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001320 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001321 else UNREACHABLE();
1322
1323 if (!texture)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001324 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001325 return error(GL_INVALID_OPERATION);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001326 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001327
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001328 GLenum textureFormat = texture->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001329
1330 // [OpenGL ES 2.0.24] table 3.9
1331 switch (textureFormat)
1332 {
1333 case GL_ALPHA:
1334 if (colorbufferFormat != GL_ALPHA &&
1335 colorbufferFormat != GL_RGBA &&
1336 colorbufferFormat != GL_RGBA4 &&
1337 colorbufferFormat != GL_RGB5_A1 &&
1338 colorbufferFormat != GL_RGBA8_OES)
1339 {
1340 return error(GL_INVALID_OPERATION);
1341 }
1342 break;
1343 case GL_LUMINANCE:
1344 case GL_RGB:
1345 if (colorbufferFormat != GL_RGB &&
1346 colorbufferFormat != GL_RGB565 &&
1347 colorbufferFormat != GL_RGB8_OES &&
1348 colorbufferFormat != GL_RGBA &&
1349 colorbufferFormat != GL_RGBA4 &&
1350 colorbufferFormat != GL_RGB5_A1 &&
1351 colorbufferFormat != GL_RGBA8_OES)
1352 {
1353 return error(GL_INVALID_OPERATION);
1354 }
1355 break;
1356 case GL_LUMINANCE_ALPHA:
1357 case GL_RGBA:
1358 if (colorbufferFormat != GL_RGBA &&
1359 colorbufferFormat != GL_RGBA4 &&
1360 colorbufferFormat != GL_RGB5_A1 &&
1361 colorbufferFormat != GL_RGBA8_OES)
1362 {
1363 return error(GL_INVALID_OPERATION);
1364 }
1365 break;
1366 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1367 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001368 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1369 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001370 return error(GL_INVALID_OPERATION);
1371 default:
1372 return error(GL_INVALID_OPERATION);
1373 }
1374
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001375 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001376 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001377 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001378
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001379 catch(std::bad_alloc&)
1380 {
1381 return error(GL_OUT_OF_MEMORY);
1382 }
1383}
1384
1385GLuint __stdcall glCreateProgram(void)
1386{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001387 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001388
1389 try
1390 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001391 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001392
1393 if (context)
1394 {
1395 return context->createProgram();
1396 }
1397 }
1398 catch(std::bad_alloc&)
1399 {
1400 return error(GL_OUT_OF_MEMORY, 0);
1401 }
1402
1403 return 0;
1404}
1405
1406GLuint __stdcall glCreateShader(GLenum type)
1407{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001408 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001409
1410 try
1411 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001412 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001413
1414 if (context)
1415 {
1416 switch (type)
1417 {
1418 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001419 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001420 return context->createShader(type);
1421 default:
1422 return error(GL_INVALID_ENUM, 0);
1423 }
1424 }
1425 }
1426 catch(std::bad_alloc&)
1427 {
1428 return error(GL_OUT_OF_MEMORY, 0);
1429 }
1430
1431 return 0;
1432}
1433
1434void __stdcall glCullFace(GLenum mode)
1435{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001436 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001437
1438 try
1439 {
1440 switch (mode)
1441 {
1442 case GL_FRONT:
1443 case GL_BACK:
1444 case GL_FRONT_AND_BACK:
1445 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001446 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001447
1448 if (context)
1449 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001450 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001451 }
1452 }
1453 break;
1454 default:
1455 return error(GL_INVALID_ENUM);
1456 }
1457 }
1458 catch(std::bad_alloc&)
1459 {
1460 return error(GL_OUT_OF_MEMORY);
1461 }
1462}
1463
1464void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1465{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001466 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001467
1468 try
1469 {
1470 if (n < 0)
1471 {
1472 return error(GL_INVALID_VALUE);
1473 }
1474
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001475 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001476
1477 if (context)
1478 {
1479 for (int i = 0; i < n; i++)
1480 {
1481 context->deleteBuffer(buffers[i]);
1482 }
1483 }
1484 }
1485 catch(std::bad_alloc&)
1486 {
1487 return error(GL_OUT_OF_MEMORY);
1488 }
1489}
1490
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001491void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1492{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001493 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001494
1495 try
1496 {
1497 if (n < 0)
1498 {
1499 return error(GL_INVALID_VALUE);
1500 }
1501
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001502 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001503
1504 if (context)
1505 {
1506 for (int i = 0; i < n; i++)
1507 {
1508 context->deleteFence(fences[i]);
1509 }
1510 }
1511 }
1512 catch(std::bad_alloc&)
1513 {
1514 return error(GL_OUT_OF_MEMORY);
1515 }
1516}
1517
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001518void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1519{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001520 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001521
1522 try
1523 {
1524 if (n < 0)
1525 {
1526 return error(GL_INVALID_VALUE);
1527 }
1528
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001529 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001530
1531 if (context)
1532 {
1533 for (int i = 0; i < n; i++)
1534 {
1535 if (framebuffers[i] != 0)
1536 {
1537 context->deleteFramebuffer(framebuffers[i]);
1538 }
1539 }
1540 }
1541 }
1542 catch(std::bad_alloc&)
1543 {
1544 return error(GL_OUT_OF_MEMORY);
1545 }
1546}
1547
1548void __stdcall glDeleteProgram(GLuint program)
1549{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001550 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001551
1552 try
1553 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001554 if (program == 0)
1555 {
1556 return;
1557 }
1558
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001559 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001560
1561 if (context)
1562 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001563 if (!context->getProgram(program))
1564 {
1565 if(context->getShader(program))
1566 {
1567 return error(GL_INVALID_OPERATION);
1568 }
1569 else
1570 {
1571 return error(GL_INVALID_VALUE);
1572 }
1573 }
1574
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001575 context->deleteProgram(program);
1576 }
1577 }
1578 catch(std::bad_alloc&)
1579 {
1580 return error(GL_OUT_OF_MEMORY);
1581 }
1582}
1583
1584void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1585{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001586 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001587
1588 try
1589 {
1590 if (n < 0)
1591 {
1592 return error(GL_INVALID_VALUE);
1593 }
1594
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001595 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001596
1597 if (context)
1598 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001599 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001600 {
1601 context->deleteRenderbuffer(renderbuffers[i]);
1602 }
1603 }
1604 }
1605 catch(std::bad_alloc&)
1606 {
1607 return error(GL_OUT_OF_MEMORY);
1608 }
1609}
1610
1611void __stdcall glDeleteShader(GLuint shader)
1612{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001613 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001614
1615 try
1616 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001617 if (shader == 0)
1618 {
1619 return;
1620 }
1621
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001622 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001623
1624 if (context)
1625 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001626 if (!context->getShader(shader))
1627 {
1628 if(context->getProgram(shader))
1629 {
1630 return error(GL_INVALID_OPERATION);
1631 }
1632 else
1633 {
1634 return error(GL_INVALID_VALUE);
1635 }
1636 }
1637
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001638 context->deleteShader(shader);
1639 }
1640 }
1641 catch(std::bad_alloc&)
1642 {
1643 return error(GL_OUT_OF_MEMORY);
1644 }
1645}
1646
1647void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1648{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001649 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001650
1651 try
1652 {
1653 if (n < 0)
1654 {
1655 return error(GL_INVALID_VALUE);
1656 }
1657
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001658 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001659
1660 if (context)
1661 {
1662 for (int i = 0; i < n; i++)
1663 {
1664 if (textures[i] != 0)
1665 {
1666 context->deleteTexture(textures[i]);
1667 }
1668 }
1669 }
1670 }
1671 catch(std::bad_alloc&)
1672 {
1673 return error(GL_OUT_OF_MEMORY);
1674 }
1675}
1676
1677void __stdcall glDepthFunc(GLenum func)
1678{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001679 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001680
1681 try
1682 {
1683 switch (func)
1684 {
1685 case GL_NEVER:
1686 case GL_ALWAYS:
1687 case GL_LESS:
1688 case GL_LEQUAL:
1689 case GL_EQUAL:
1690 case GL_GREATER:
1691 case GL_GEQUAL:
1692 case GL_NOTEQUAL:
1693 break;
1694 default:
1695 return error(GL_INVALID_ENUM);
1696 }
1697
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001698 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001699
1700 if (context)
1701 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001702 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001703 }
1704 }
1705 catch(std::bad_alloc&)
1706 {
1707 return error(GL_OUT_OF_MEMORY);
1708 }
1709}
1710
1711void __stdcall glDepthMask(GLboolean flag)
1712{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001713 EVENT("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001714
1715 try
1716 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001717 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001718
1719 if (context)
1720 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001721 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001722 }
1723 }
1724 catch(std::bad_alloc&)
1725 {
1726 return error(GL_OUT_OF_MEMORY);
1727 }
1728}
1729
1730void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1731{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001732 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001733
1734 try
1735 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001736 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001737
1738 if (context)
1739 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001740 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001741 }
1742 }
1743 catch(std::bad_alloc&)
1744 {
1745 return error(GL_OUT_OF_MEMORY);
1746 }
1747}
1748
1749void __stdcall glDetachShader(GLuint program, GLuint shader)
1750{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001751 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001752
1753 try
1754 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001755 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001756
1757 if (context)
1758 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001759
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001760 gl::Program *programObject = context->getProgram(program);
1761 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001762
1763 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001764 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001765 gl::Shader *shaderByProgramHandle;
1766 shaderByProgramHandle = context->getShader(program);
1767 if (!shaderByProgramHandle)
1768 {
1769 return error(GL_INVALID_VALUE);
1770 }
1771 else
1772 {
1773 return error(GL_INVALID_OPERATION);
1774 }
1775 }
1776
1777 if (!shaderObject)
1778 {
1779 gl::Program *programByShaderHandle = context->getProgram(shader);
1780 if (!programByShaderHandle)
1781 {
1782 return error(GL_INVALID_VALUE);
1783 }
1784 else
1785 {
1786 return error(GL_INVALID_OPERATION);
1787 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001788 }
1789
1790 if (!programObject->detachShader(shaderObject))
1791 {
1792 return error(GL_INVALID_OPERATION);
1793 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001794 }
1795 }
1796 catch(std::bad_alloc&)
1797 {
1798 return error(GL_OUT_OF_MEMORY);
1799 }
1800}
1801
1802void __stdcall glDisable(GLenum cap)
1803{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001804 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001805
1806 try
1807 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001808 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001809
1810 if (context)
1811 {
1812 switch (cap)
1813 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001814 case GL_CULL_FACE: context->setCullFace(false); break;
1815 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1816 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1817 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1818 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1819 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1820 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1821 case GL_BLEND: context->setBlend(false); break;
1822 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001823 default:
1824 return error(GL_INVALID_ENUM);
1825 }
1826 }
1827 }
1828 catch(std::bad_alloc&)
1829 {
1830 return error(GL_OUT_OF_MEMORY);
1831 }
1832}
1833
1834void __stdcall glDisableVertexAttribArray(GLuint index)
1835{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001836 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001837
1838 try
1839 {
1840 if (index >= gl::MAX_VERTEX_ATTRIBS)
1841 {
1842 return error(GL_INVALID_VALUE);
1843 }
1844
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001845 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001846
1847 if (context)
1848 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001849 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001850 }
1851 }
1852 catch(std::bad_alloc&)
1853 {
1854 return error(GL_OUT_OF_MEMORY);
1855 }
1856}
1857
1858void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1859{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001860 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001861
1862 try
1863 {
1864 if (count < 0 || first < 0)
1865 {
1866 return error(GL_INVALID_VALUE);
1867 }
1868
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001869 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001870
1871 if (context)
1872 {
1873 context->drawArrays(mode, first, count);
1874 }
1875 }
1876 catch(std::bad_alloc&)
1877 {
1878 return error(GL_OUT_OF_MEMORY);
1879 }
1880}
1881
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001882void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001883{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001884 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 +00001885 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001886
1887 try
1888 {
1889 if (count < 0)
1890 {
1891 return error(GL_INVALID_VALUE);
1892 }
1893
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001894 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001895
1896 if (context)
1897 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001898 switch (type)
1899 {
1900 case GL_UNSIGNED_BYTE:
1901 case GL_UNSIGNED_SHORT:
1902 break;
1903 case GL_UNSIGNED_INT:
1904 if (!context->supports32bitIndices())
1905 {
1906 return error(GL_INVALID_ENUM);
1907 }
1908 break;
1909 default:
1910 return error(GL_INVALID_ENUM);
1911 }
1912
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001913 context->drawElements(mode, count, type, indices);
1914 }
1915 }
1916 catch(std::bad_alloc&)
1917 {
1918 return error(GL_OUT_OF_MEMORY);
1919 }
1920}
1921
1922void __stdcall glEnable(GLenum cap)
1923{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001924 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001925
1926 try
1927 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001928 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001929
1930 if (context)
1931 {
1932 switch (cap)
1933 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001934 case GL_CULL_FACE: context->setCullFace(true); break;
1935 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1936 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1937 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1938 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1939 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1940 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1941 case GL_BLEND: context->setBlend(true); break;
1942 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001943 default:
1944 return error(GL_INVALID_ENUM);
1945 }
1946 }
1947 }
1948 catch(std::bad_alloc&)
1949 {
1950 return error(GL_OUT_OF_MEMORY);
1951 }
1952}
1953
1954void __stdcall glEnableVertexAttribArray(GLuint index)
1955{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001956 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001957
1958 try
1959 {
1960 if (index >= gl::MAX_VERTEX_ATTRIBS)
1961 {
1962 return error(GL_INVALID_VALUE);
1963 }
1964
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001965 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001966
1967 if (context)
1968 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001969 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001970 }
1971 }
1972 catch(std::bad_alloc&)
1973 {
1974 return error(GL_OUT_OF_MEMORY);
1975 }
1976}
1977
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001978void __stdcall glFinishFenceNV(GLuint fence)
1979{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001980 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001981
1982 try
1983 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001984 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001985
1986 if (context)
1987 {
1988 gl::Fence* fenceObject = context->getFence(fence);
1989
1990 if (fenceObject == NULL)
1991 {
1992 return error(GL_INVALID_OPERATION);
1993 }
1994
1995 fenceObject->finishFence();
1996 }
1997 }
1998 catch(std::bad_alloc&)
1999 {
2000 return error(GL_OUT_OF_MEMORY);
2001 }
2002}
2003
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002004void __stdcall glFinish(void)
2005{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002006 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002007
2008 try
2009 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002010 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002011
2012 if (context)
2013 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002014 context->sync(true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002015 }
2016 }
2017 catch(std::bad_alloc&)
2018 {
2019 return error(GL_OUT_OF_MEMORY);
2020 }
2021}
2022
2023void __stdcall glFlush(void)
2024{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002025 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002026
2027 try
2028 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002029 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002030
2031 if (context)
2032 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002033 context->sync(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002034 }
2035 }
2036 catch(std::bad_alloc&)
2037 {
2038 return error(GL_OUT_OF_MEMORY);
2039 }
2040}
2041
2042void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2043{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002044 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002045 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002046
2047 try
2048 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002049 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002050 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002051 {
2052 return error(GL_INVALID_ENUM);
2053 }
2054
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002055 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002056
2057 if (context)
2058 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002059 gl::Framebuffer *framebuffer = NULL;
2060 GLuint framebufferHandle = 0;
2061 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2062 {
2063 framebuffer = context->getReadFramebuffer();
2064 framebufferHandle = context->getReadFramebufferHandle();
2065 }
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002066 else
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002067 {
2068 framebuffer = context->getDrawFramebuffer();
2069 framebufferHandle = context->getDrawFramebufferHandle();
2070 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002071
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002072 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002073 {
2074 return error(GL_INVALID_OPERATION);
2075 }
2076
2077 switch (attachment)
2078 {
2079 case GL_COLOR_ATTACHMENT0:
2080 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2081 break;
2082 case GL_DEPTH_ATTACHMENT:
2083 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2084 break;
2085 case GL_STENCIL_ATTACHMENT:
2086 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2087 break;
2088 default:
2089 return error(GL_INVALID_ENUM);
2090 }
2091 }
2092 }
2093 catch(std::bad_alloc&)
2094 {
2095 return error(GL_OUT_OF_MEMORY);
2096 }
2097}
2098
2099void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2100{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002101 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002102 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002103
2104 try
2105 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002106 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002107 {
2108 return error(GL_INVALID_ENUM);
2109 }
2110
2111 switch (attachment)
2112 {
2113 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002114 case GL_DEPTH_ATTACHMENT:
2115 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002116 break;
2117 default:
2118 return error(GL_INVALID_ENUM);
2119 }
2120
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002121 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002122
2123 if (context)
2124 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002125 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002126 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002127 textarget = GL_NONE;
2128 }
2129 else
2130 {
2131 gl::Texture *tex = context->getTexture(texture);
2132
2133 if (tex == NULL)
2134 {
2135 return error(GL_INVALID_OPERATION);
2136 }
2137
daniel@transgaming.com01868132010-08-24 19:21:17 +00002138 if (tex->isCompressed())
2139 {
2140 return error(GL_INVALID_OPERATION);
2141 }
2142
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002143 switch (textarget)
2144 {
2145 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002146 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002147 {
2148 return error(GL_INVALID_OPERATION);
2149 }
2150 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002151
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002152 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002153 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002154 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002155 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002156 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002157 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002158 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2159 {
2160 return error(GL_INVALID_OPERATION);
2161 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002162 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002163
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002164 default:
2165 return error(GL_INVALID_ENUM);
2166 }
2167
2168 if (level != 0)
2169 {
2170 return error(GL_INVALID_VALUE);
2171 }
2172 }
2173
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002174 gl::Framebuffer *framebuffer = NULL;
2175 GLuint framebufferHandle = 0;
2176 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2177 {
2178 framebuffer = context->getReadFramebuffer();
2179 framebufferHandle = context->getReadFramebufferHandle();
2180 }
2181 else
2182 {
2183 framebuffer = context->getDrawFramebuffer();
2184 framebufferHandle = context->getDrawFramebufferHandle();
2185 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002186
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002187 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002188 {
2189 return error(GL_INVALID_OPERATION);
2190 }
2191
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002192 switch (attachment)
2193 {
2194 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2195 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2196 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2197 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002198 }
2199 }
2200 catch(std::bad_alloc&)
2201 {
2202 return error(GL_OUT_OF_MEMORY);
2203 }
2204}
2205
2206void __stdcall glFrontFace(GLenum mode)
2207{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002208 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002209
2210 try
2211 {
2212 switch (mode)
2213 {
2214 case GL_CW:
2215 case GL_CCW:
2216 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002217 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002218
2219 if (context)
2220 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002221 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002222 }
2223 }
2224 break;
2225 default:
2226 return error(GL_INVALID_ENUM);
2227 }
2228 }
2229 catch(std::bad_alloc&)
2230 {
2231 return error(GL_OUT_OF_MEMORY);
2232 }
2233}
2234
2235void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2236{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002237 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002238
2239 try
2240 {
2241 if (n < 0)
2242 {
2243 return error(GL_INVALID_VALUE);
2244 }
2245
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002246 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002247
2248 if (context)
2249 {
2250 for (int i = 0; i < n; i++)
2251 {
2252 buffers[i] = context->createBuffer();
2253 }
2254 }
2255 }
2256 catch(std::bad_alloc&)
2257 {
2258 return error(GL_OUT_OF_MEMORY);
2259 }
2260}
2261
2262void __stdcall glGenerateMipmap(GLenum target)
2263{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002264 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002265
2266 try
2267 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002268 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002269
2270 if (context)
2271 {
2272 gl::Texture *texture;
2273
2274 switch (target)
2275 {
2276 case GL_TEXTURE_2D:
2277 texture = context->getTexture2D();
2278 break;
2279
2280 case GL_TEXTURE_CUBE_MAP:
2281 texture = context->getTextureCubeMap();
2282 break;
2283
2284 default:
2285 return error(GL_INVALID_ENUM);
2286 }
2287
daniel@transgaming.com01868132010-08-24 19:21:17 +00002288 if (texture->isCompressed())
2289 {
2290 return error(GL_INVALID_OPERATION);
2291 }
2292
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002293 texture->generateMipmaps();
2294 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002295 }
2296 catch(std::bad_alloc&)
2297 {
2298 return error(GL_OUT_OF_MEMORY);
2299 }
2300}
2301
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002302void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2303{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002304 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002305
2306 try
2307 {
2308 if (n < 0)
2309 {
2310 return error(GL_INVALID_VALUE);
2311 }
2312
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002313 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002314
2315 if (context)
2316 {
2317 for (int i = 0; i < n; i++)
2318 {
2319 fences[i] = context->createFence();
2320 }
2321 }
2322 }
2323 catch(std::bad_alloc&)
2324 {
2325 return error(GL_OUT_OF_MEMORY);
2326 }
2327}
2328
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002329void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2330{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002331 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002332
2333 try
2334 {
2335 if (n < 0)
2336 {
2337 return error(GL_INVALID_VALUE);
2338 }
2339
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002340 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002341
2342 if (context)
2343 {
2344 for (int i = 0; i < n; i++)
2345 {
2346 framebuffers[i] = context->createFramebuffer();
2347 }
2348 }
2349 }
2350 catch(std::bad_alloc&)
2351 {
2352 return error(GL_OUT_OF_MEMORY);
2353 }
2354}
2355
2356void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2357{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002358 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002359
2360 try
2361 {
2362 if (n < 0)
2363 {
2364 return error(GL_INVALID_VALUE);
2365 }
2366
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002367 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002368
2369 if (context)
2370 {
2371 for (int i = 0; i < n; i++)
2372 {
2373 renderbuffers[i] = context->createRenderbuffer();
2374 }
2375 }
2376 }
2377 catch(std::bad_alloc&)
2378 {
2379 return error(GL_OUT_OF_MEMORY);
2380 }
2381}
2382
2383void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2384{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002385 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002386
2387 try
2388 {
2389 if (n < 0)
2390 {
2391 return error(GL_INVALID_VALUE);
2392 }
2393
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002394 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002395
2396 if (context)
2397 {
2398 for (int i = 0; i < n; i++)
2399 {
2400 textures[i] = context->createTexture();
2401 }
2402 }
2403 }
2404 catch(std::bad_alloc&)
2405 {
2406 return error(GL_OUT_OF_MEMORY);
2407 }
2408}
2409
daniel@transgaming.com85423182010-04-22 13:35:27 +00002410void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002411{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002412 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002413 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002414 program, index, bufsize, length, size, type, name);
2415
2416 try
2417 {
2418 if (bufsize < 0)
2419 {
2420 return error(GL_INVALID_VALUE);
2421 }
2422
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002423 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com85423182010-04-22 13:35:27 +00002424
2425 if (context)
2426 {
2427 gl::Program *programObject = context->getProgram(program);
2428
2429 if (!programObject)
2430 {
2431 if (context->getShader(program))
2432 {
2433 return error(GL_INVALID_OPERATION);
2434 }
2435 else
2436 {
2437 return error(GL_INVALID_VALUE);
2438 }
2439 }
2440
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002441 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002442 {
2443 return error(GL_INVALID_VALUE);
2444 }
2445
2446 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2447 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002448 }
2449 catch(std::bad_alloc&)
2450 {
2451 return error(GL_OUT_OF_MEMORY);
2452 }
2453}
2454
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002455void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002456{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002457 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002458 "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 +00002459 program, index, bufsize, length, size, type, name);
2460
2461 try
2462 {
2463 if (bufsize < 0)
2464 {
2465 return error(GL_INVALID_VALUE);
2466 }
2467
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002468 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002469
2470 if (context)
2471 {
2472 gl::Program *programObject = context->getProgram(program);
2473
2474 if (!programObject)
2475 {
2476 if (context->getShader(program))
2477 {
2478 return error(GL_INVALID_OPERATION);
2479 }
2480 else
2481 {
2482 return error(GL_INVALID_VALUE);
2483 }
2484 }
2485
2486 if (index >= (GLuint)programObject->getActiveUniformCount())
2487 {
2488 return error(GL_INVALID_VALUE);
2489 }
2490
2491 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2492 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002493 }
2494 catch(std::bad_alloc&)
2495 {
2496 return error(GL_OUT_OF_MEMORY);
2497 }
2498}
2499
2500void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2501{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002502 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 +00002503 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002504
2505 try
2506 {
2507 if (maxcount < 0)
2508 {
2509 return error(GL_INVALID_VALUE);
2510 }
2511
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002512 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002513
2514 if (context)
2515 {
2516 gl::Program *programObject = context->getProgram(program);
2517
2518 if (!programObject)
2519 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002520 if (context->getShader(program))
2521 {
2522 return error(GL_INVALID_OPERATION);
2523 }
2524 else
2525 {
2526 return error(GL_INVALID_VALUE);
2527 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002528 }
2529
2530 return programObject->getAttachedShaders(maxcount, count, shaders);
2531 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002532 }
2533 catch(std::bad_alloc&)
2534 {
2535 return error(GL_OUT_OF_MEMORY);
2536 }
2537}
2538
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002539int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002540{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002541 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002542
2543 try
2544 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002545 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002546
2547 if (context)
2548 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002549
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002550 gl::Program *programObject = context->getProgram(program);
2551
2552 if (!programObject)
2553 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002554 if (context->getShader(program))
2555 {
2556 return error(GL_INVALID_OPERATION, -1);
2557 }
2558 else
2559 {
2560 return error(GL_INVALID_VALUE, -1);
2561 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002562 }
2563
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002564 if (!programObject->isLinked())
2565 {
2566 return error(GL_INVALID_OPERATION, -1);
2567 }
2568
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002569 return programObject->getAttributeLocation(name);
2570 }
2571 }
2572 catch(std::bad_alloc&)
2573 {
2574 return error(GL_OUT_OF_MEMORY, -1);
2575 }
2576
2577 return -1;
2578}
2579
2580void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2581{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002582 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002583
2584 try
2585 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002586 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002587
2588 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002589 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002590 if (!(context->getBooleanv(pname, params)))
2591 {
2592 GLenum nativeType;
2593 unsigned int numParams = 0;
2594 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2595 return error(GL_INVALID_ENUM);
2596
2597 if (numParams == 0)
2598 return; // it is known that the pname is valid, but there are no parameters to return
2599
2600 if (nativeType == GL_FLOAT)
2601 {
2602 GLfloat *floatParams = NULL;
2603 floatParams = new GLfloat[numParams];
2604
2605 context->getFloatv(pname, floatParams);
2606
2607 for (unsigned int i = 0; i < numParams; ++i)
2608 {
2609 if (floatParams[i] == 0.0f)
2610 params[i] = GL_FALSE;
2611 else
2612 params[i] = GL_TRUE;
2613 }
2614
2615 delete [] floatParams;
2616 }
2617 else if (nativeType == GL_INT)
2618 {
2619 GLint *intParams = NULL;
2620 intParams = new GLint[numParams];
2621
2622 context->getIntegerv(pname, intParams);
2623
2624 for (unsigned int i = 0; i < numParams; ++i)
2625 {
2626 if (intParams[i] == 0)
2627 params[i] = GL_FALSE;
2628 else
2629 params[i] = GL_TRUE;
2630 }
2631
2632 delete [] intParams;
2633 }
2634 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002635 }
2636 }
2637 catch(std::bad_alloc&)
2638 {
2639 return error(GL_OUT_OF_MEMORY);
2640 }
2641}
2642
2643void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2644{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002645 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 +00002646
2647 try
2648 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002649 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002650
2651 if (context)
2652 {
2653 gl::Buffer *buffer;
2654
2655 switch (target)
2656 {
2657 case GL_ARRAY_BUFFER:
2658 buffer = context->getArrayBuffer();
2659 break;
2660 case GL_ELEMENT_ARRAY_BUFFER:
2661 buffer = context->getElementArrayBuffer();
2662 break;
2663 default: return error(GL_INVALID_ENUM);
2664 }
2665
2666 if (!buffer)
2667 {
2668 // A null buffer means that "0" is bound to the requested buffer target
2669 return error(GL_INVALID_OPERATION);
2670 }
2671
2672 switch (pname)
2673 {
2674 case GL_BUFFER_USAGE:
2675 *params = buffer->usage();
2676 break;
2677 case GL_BUFFER_SIZE:
2678 *params = buffer->size();
2679 break;
2680 default: return error(GL_INVALID_ENUM);
2681 }
2682 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002683 }
2684 catch(std::bad_alloc&)
2685 {
2686 return error(GL_OUT_OF_MEMORY);
2687 }
2688}
2689
2690GLenum __stdcall glGetError(void)
2691{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002692 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002693
2694 gl::Context *context = gl::getContext();
2695
2696 if (context)
2697 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002698 if (context->isContextLost())
2699 return GL_OUT_OF_MEMORY;
2700 else
2701 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002702 }
2703
2704 return GL_NO_ERROR;
2705}
2706
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002707void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2708{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002709 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002710
2711 try
2712 {
2713
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002714 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002715
2716 if (context)
2717 {
2718 gl::Fence *fenceObject = context->getFence(fence);
2719
2720 if (fenceObject == NULL)
2721 {
2722 return error(GL_INVALID_OPERATION);
2723 }
2724
2725 fenceObject->getFenceiv(pname, params);
2726 }
2727 }
2728 catch(std::bad_alloc&)
2729 {
2730 return error(GL_OUT_OF_MEMORY);
2731 }
2732}
2733
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002734void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2735{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002736 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002737
2738 try
2739 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002740 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002741
2742 if (context)
2743 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002744 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002745 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002746 GLenum nativeType;
2747 unsigned int numParams = 0;
2748 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2749 return error(GL_INVALID_ENUM);
2750
2751 if (numParams == 0)
2752 return; // it is known that the pname is valid, but that there are no parameters to return.
2753
2754 if (nativeType == GL_BOOL)
2755 {
2756 GLboolean *boolParams = NULL;
2757 boolParams = new GLboolean[numParams];
2758
2759 context->getBooleanv(pname, boolParams);
2760
2761 for (unsigned int i = 0; i < numParams; ++i)
2762 {
2763 if (boolParams[i] == GL_FALSE)
2764 params[i] = 0.0f;
2765 else
2766 params[i] = 1.0f;
2767 }
2768
2769 delete [] boolParams;
2770 }
2771 else if (nativeType == GL_INT)
2772 {
2773 GLint *intParams = NULL;
2774 intParams = new GLint[numParams];
2775
2776 context->getIntegerv(pname, intParams);
2777
2778 for (unsigned int i = 0; i < numParams; ++i)
2779 {
2780 params[i] = (GLfloat)intParams[i];
2781 }
2782
2783 delete [] intParams;
2784 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002785 }
2786 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002787 }
2788 catch(std::bad_alloc&)
2789 {
2790 return error(GL_OUT_OF_MEMORY);
2791 }
2792}
2793
2794void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2795{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002796 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 +00002797 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002798
2799 try
2800 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002801 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002802
2803 if (context)
2804 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002805 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002806 {
2807 return error(GL_INVALID_ENUM);
2808 }
2809
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002810 gl::Framebuffer *framebuffer = NULL;
2811 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2812 {
2813 if(context->getReadFramebufferHandle() == 0)
2814 {
2815 return error(GL_INVALID_OPERATION);
2816 }
2817
2818 framebuffer = context->getReadFramebuffer();
2819 }
2820 else
2821 {
2822 if (context->getDrawFramebufferHandle() == 0)
2823 {
2824 return error(GL_INVALID_OPERATION);
2825 }
2826
2827 framebuffer = context->getDrawFramebuffer();
2828 }
2829
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002830 GLenum attachmentType;
2831 GLuint attachmentHandle;
2832 switch (attachment)
2833 {
2834 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002835 attachmentType = framebuffer->getColorbufferType();
2836 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002837 break;
2838 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002839 attachmentType = framebuffer->getDepthbufferType();
2840 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002841 break;
2842 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002843 attachmentType = framebuffer->getStencilbufferType();
2844 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002845 break;
2846 default: return error(GL_INVALID_ENUM);
2847 }
2848
2849 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002850 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002851 {
2852 attachmentObjectType = attachmentType;
2853 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002854 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002855 {
2856 attachmentObjectType = GL_TEXTURE;
2857 }
2858 else UNREACHABLE();
2859
2860 switch (pname)
2861 {
2862 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2863 *params = attachmentObjectType;
2864 break;
2865 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2866 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2867 {
2868 *params = attachmentHandle;
2869 }
2870 else
2871 {
2872 return error(GL_INVALID_ENUM);
2873 }
2874 break;
2875 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2876 if (attachmentObjectType == GL_TEXTURE)
2877 {
2878 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2879 }
2880 else
2881 {
2882 return error(GL_INVALID_ENUM);
2883 }
2884 break;
2885 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2886 if (attachmentObjectType == GL_TEXTURE)
2887 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002888 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002889 {
2890 *params = attachmentType;
2891 }
2892 else
2893 {
2894 *params = 0;
2895 }
2896 }
2897 else
2898 {
2899 return error(GL_INVALID_ENUM);
2900 }
2901 break;
2902 default:
2903 return error(GL_INVALID_ENUM);
2904 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002905 }
2906 }
2907 catch(std::bad_alloc&)
2908 {
2909 return error(GL_OUT_OF_MEMORY);
2910 }
2911}
2912
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00002913GLenum __stdcall glGetGraphicsResetStatusEXT(void)
2914{
2915 EVENT("()");
2916
2917 try
2918 {
2919 gl::Context *context = gl::getContext();
2920
2921 if (context)
2922 {
2923 return context->getResetStatus();
2924 }
2925
2926 return GL_NO_ERROR;
2927 }
2928 catch(std::bad_alloc&)
2929 {
2930 return GL_OUT_OF_MEMORY;
2931 }
2932}
2933
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002934void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2935{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002936 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002937
2938 try
2939 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002940 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002941
2942 if (context)
2943 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002944 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002945 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002946 GLenum nativeType;
2947 unsigned int numParams = 0;
2948 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2949 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002950
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002951 if (numParams == 0)
2952 return; // it is known that pname is valid, but there are no parameters to return
2953
2954 if (nativeType == GL_BOOL)
2955 {
2956 GLboolean *boolParams = NULL;
2957 boolParams = new GLboolean[numParams];
2958
2959 context->getBooleanv(pname, boolParams);
2960
2961 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002962 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002963 if (boolParams[i] == GL_FALSE)
2964 params[i] = 0;
2965 else
2966 params[i] = 1;
2967 }
2968
2969 delete [] boolParams;
2970 }
2971 else if (nativeType == GL_FLOAT)
2972 {
2973 GLfloat *floatParams = NULL;
2974 floatParams = new GLfloat[numParams];
2975
2976 context->getFloatv(pname, floatParams);
2977
2978 for (unsigned int i = 0; i < numParams; ++i)
2979 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002980 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 +00002981 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002982 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002983 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002984 else
2985 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 +00002986 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002987
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002988 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002989 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002990 }
2991 }
2992 }
2993 catch(std::bad_alloc&)
2994 {
2995 return error(GL_OUT_OF_MEMORY);
2996 }
2997}
2998
2999void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3000{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003001 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003002
3003 try
3004 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003005 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003006
3007 if (context)
3008 {
3009 gl::Program *programObject = context->getProgram(program);
3010
3011 if (!programObject)
3012 {
3013 return error(GL_INVALID_VALUE);
3014 }
3015
3016 switch (pname)
3017 {
3018 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003019 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003020 return;
3021 case GL_LINK_STATUS:
3022 *params = programObject->isLinked();
3023 return;
3024 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003025 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003026 return;
3027 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003028 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003029 return;
3030 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003031 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003032 return;
3033 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003034 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003035 return;
3036 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003037 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003038 return;
3039 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003040 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003041 return;
3042 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003043 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003044 return;
3045 default:
3046 return error(GL_INVALID_ENUM);
3047 }
3048 }
3049 }
3050 catch(std::bad_alloc&)
3051 {
3052 return error(GL_OUT_OF_MEMORY);
3053 }
3054}
3055
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003056void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003057{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003058 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 +00003059 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003060
3061 try
3062 {
3063 if (bufsize < 0)
3064 {
3065 return error(GL_INVALID_VALUE);
3066 }
3067
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003068 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003069
3070 if (context)
3071 {
3072 gl::Program *programObject = context->getProgram(program);
3073
3074 if (!programObject)
3075 {
3076 return error(GL_INVALID_VALUE);
3077 }
3078
3079 programObject->getInfoLog(bufsize, length, infolog);
3080 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003081 }
3082 catch(std::bad_alloc&)
3083 {
3084 return error(GL_OUT_OF_MEMORY);
3085 }
3086}
3087
3088void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3089{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003090 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 +00003091
3092 try
3093 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003094 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003095
3096 if (context)
3097 {
3098 if (target != GL_RENDERBUFFER)
3099 {
3100 return error(GL_INVALID_ENUM);
3101 }
3102
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003103 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003104 {
3105 return error(GL_INVALID_OPERATION);
3106 }
3107
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003108 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003109
3110 switch (pname)
3111 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003112 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3113 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3114 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3115 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3116 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3117 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3118 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3119 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3120 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003121 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003122 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003123 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003124 *params = renderbuffer->getSamples();
3125 }
3126 else
3127 {
3128 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003129 }
3130 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003131 default:
3132 return error(GL_INVALID_ENUM);
3133 }
3134 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003135 }
3136 catch(std::bad_alloc&)
3137 {
3138 return error(GL_OUT_OF_MEMORY);
3139 }
3140}
3141
3142void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3143{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003144 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003145
3146 try
3147 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003148 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003149
3150 if (context)
3151 {
3152 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003153
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003154 if (!shaderObject)
3155 {
3156 return error(GL_INVALID_VALUE);
3157 }
3158
3159 switch (pname)
3160 {
3161 case GL_SHADER_TYPE:
3162 *params = shaderObject->getType();
3163 return;
3164 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003165 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003166 return;
3167 case GL_COMPILE_STATUS:
3168 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3169 return;
3170 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003171 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003172 return;
3173 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003174 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003175 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003176 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3177 *params = shaderObject->getTranslatedSourceLength();
3178 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003179 default:
3180 return error(GL_INVALID_ENUM);
3181 }
3182 }
3183 }
3184 catch(std::bad_alloc&)
3185 {
3186 return error(GL_OUT_OF_MEMORY);
3187 }
3188}
3189
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003190void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003191{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003192 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 +00003193 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003194
3195 try
3196 {
3197 if (bufsize < 0)
3198 {
3199 return error(GL_INVALID_VALUE);
3200 }
3201
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003202 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003203
3204 if (context)
3205 {
3206 gl::Shader *shaderObject = context->getShader(shader);
3207
3208 if (!shaderObject)
3209 {
3210 return error(GL_INVALID_VALUE);
3211 }
3212
3213 shaderObject->getInfoLog(bufsize, length, infolog);
3214 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003215 }
3216 catch(std::bad_alloc&)
3217 {
3218 return error(GL_OUT_OF_MEMORY);
3219 }
3220}
3221
3222void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3223{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003224 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 +00003225 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003226
3227 try
3228 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003229 switch (shadertype)
3230 {
3231 case GL_VERTEX_SHADER:
3232 case GL_FRAGMENT_SHADER:
3233 break;
3234 default:
3235 return error(GL_INVALID_ENUM);
3236 }
3237
3238 switch (precisiontype)
3239 {
3240 case GL_LOW_FLOAT:
3241 case GL_MEDIUM_FLOAT:
3242 case GL_HIGH_FLOAT:
3243 // Assume IEEE 754 precision
3244 range[0] = 127;
3245 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003246 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003247 break;
3248 case GL_LOW_INT:
3249 case GL_MEDIUM_INT:
3250 case GL_HIGH_INT:
3251 // Some (most) hardware only supports single-precision floating-point numbers,
3252 // which can accurately represent integers up to +/-16777216
3253 range[0] = 24;
3254 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003255 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003256 break;
3257 default:
3258 return error(GL_INVALID_ENUM);
3259 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003260 }
3261 catch(std::bad_alloc&)
3262 {
3263 return error(GL_OUT_OF_MEMORY);
3264 }
3265}
3266
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003267void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003268{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003269 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 +00003270 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003271
3272 try
3273 {
3274 if (bufsize < 0)
3275 {
3276 return error(GL_INVALID_VALUE);
3277 }
3278
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003279 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003280
3281 if (context)
3282 {
3283 gl::Shader *shaderObject = context->getShader(shader);
3284
3285 if (!shaderObject)
3286 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003287 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003288 }
3289
3290 shaderObject->getSource(bufsize, length, source);
3291 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003292 }
3293 catch(std::bad_alloc&)
3294 {
3295 return error(GL_OUT_OF_MEMORY);
3296 }
3297}
3298
zmo@google.coma574f782011-10-03 21:45:23 +00003299void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3300{
3301 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3302 shader, bufsize, length, source);
3303
3304 try
3305 {
3306 if (bufsize < 0)
3307 {
3308 return error(GL_INVALID_VALUE);
3309 }
3310
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003311 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003312
3313 if (context)
3314 {
3315 gl::Shader *shaderObject = context->getShader(shader);
3316
3317 if (!shaderObject)
3318 {
3319 return error(GL_INVALID_OPERATION);
3320 }
3321
3322 shaderObject->getTranslatedSource(bufsize, length, source);
3323 }
3324 }
3325 catch(std::bad_alloc&)
3326 {
3327 return error(GL_OUT_OF_MEMORY);
3328 }
3329}
3330
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003331const GLubyte* __stdcall glGetString(GLenum name)
3332{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003333 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003334
3335 try
3336 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003337 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003338
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003339 switch (name)
3340 {
3341 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003342 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003343 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003344 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003345 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003346 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003347 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003348 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003349 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003350 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003351 default:
3352 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3353 }
3354 }
3355 catch(std::bad_alloc&)
3356 {
3357 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3358 }
3359
3360 return NULL;
3361}
3362
3363void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3364{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003365 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 +00003366
3367 try
3368 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003369 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003370
3371 if (context)
3372 {
3373 gl::Texture *texture;
3374
3375 switch (target)
3376 {
3377 case GL_TEXTURE_2D:
3378 texture = context->getTexture2D();
3379 break;
3380 case GL_TEXTURE_CUBE_MAP:
3381 texture = context->getTextureCubeMap();
3382 break;
3383 default:
3384 return error(GL_INVALID_ENUM);
3385 }
3386
3387 switch (pname)
3388 {
3389 case GL_TEXTURE_MAG_FILTER:
3390 *params = (GLfloat)texture->getMagFilter();
3391 break;
3392 case GL_TEXTURE_MIN_FILTER:
3393 *params = (GLfloat)texture->getMinFilter();
3394 break;
3395 case GL_TEXTURE_WRAP_S:
3396 *params = (GLfloat)texture->getWrapS();
3397 break;
3398 case GL_TEXTURE_WRAP_T:
3399 *params = (GLfloat)texture->getWrapT();
3400 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003401 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3402 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3403 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003404 case GL_TEXTURE_USAGE_ANGLE:
3405 *params = (GLfloat)texture->getUsage();
3406 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003407 default:
3408 return error(GL_INVALID_ENUM);
3409 }
3410 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003411 }
3412 catch(std::bad_alloc&)
3413 {
3414 return error(GL_OUT_OF_MEMORY);
3415 }
3416}
3417
3418void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3419{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003420 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 +00003421
3422 try
3423 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003424 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003425
3426 if (context)
3427 {
3428 gl::Texture *texture;
3429
3430 switch (target)
3431 {
3432 case GL_TEXTURE_2D:
3433 texture = context->getTexture2D();
3434 break;
3435 case GL_TEXTURE_CUBE_MAP:
3436 texture = context->getTextureCubeMap();
3437 break;
3438 default:
3439 return error(GL_INVALID_ENUM);
3440 }
3441
3442 switch (pname)
3443 {
3444 case GL_TEXTURE_MAG_FILTER:
3445 *params = texture->getMagFilter();
3446 break;
3447 case GL_TEXTURE_MIN_FILTER:
3448 *params = texture->getMinFilter();
3449 break;
3450 case GL_TEXTURE_WRAP_S:
3451 *params = texture->getWrapS();
3452 break;
3453 case GL_TEXTURE_WRAP_T:
3454 *params = texture->getWrapT();
3455 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003456 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3457 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3458 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003459 case GL_TEXTURE_USAGE_ANGLE:
3460 *params = texture->getUsage();
3461 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003462 default:
3463 return error(GL_INVALID_ENUM);
3464 }
3465 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003466 }
3467 catch(std::bad_alloc&)
3468 {
3469 return error(GL_OUT_OF_MEMORY);
3470 }
3471}
3472
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003473void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3474{
3475 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3476 program, location, bufSize, params);
3477
3478 try
3479 {
3480 if (bufSize < 0)
3481 {
3482 return error(GL_INVALID_VALUE);
3483 }
3484
3485 gl::Context *context = gl::getNonLostContext();
3486
3487 if (context)
3488 {
3489 if (program == 0)
3490 {
3491 return error(GL_INVALID_VALUE);
3492 }
3493
3494 gl::Program *programObject = context->getProgram(program);
3495
3496 if (!programObject || !programObject->isLinked())
3497 {
3498 return error(GL_INVALID_OPERATION);
3499 }
3500
3501 if (!programObject->getUniformfv(location, &bufSize, params))
3502 {
3503 return error(GL_INVALID_OPERATION);
3504 }
3505 }
3506 }
3507 catch(std::bad_alloc&)
3508 {
3509 return error(GL_OUT_OF_MEMORY);
3510 }
3511}
3512
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003513void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3514{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003515 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003516
3517 try
3518 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003519 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003520
3521 if (context)
3522 {
3523 if (program == 0)
3524 {
3525 return error(GL_INVALID_VALUE);
3526 }
3527
3528 gl::Program *programObject = context->getProgram(program);
3529
3530 if (!programObject || !programObject->isLinked())
3531 {
3532 return error(GL_INVALID_OPERATION);
3533 }
3534
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003535 if (!programObject->getUniformfv(location, NULL, params))
3536 {
3537 return error(GL_INVALID_OPERATION);
3538 }
3539 }
3540 }
3541 catch(std::bad_alloc&)
3542 {
3543 return error(GL_OUT_OF_MEMORY);
3544 }
3545}
3546
3547void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3548{
3549 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3550 program, location, bufSize, params);
3551
3552 try
3553 {
3554 if (bufSize < 0)
3555 {
3556 return error(GL_INVALID_VALUE);
3557 }
3558
3559 gl::Context *context = gl::getNonLostContext();
3560
3561 if (context)
3562 {
3563 if (program == 0)
3564 {
3565 return error(GL_INVALID_VALUE);
3566 }
3567
3568 gl::Program *programObject = context->getProgram(program);
3569
3570 if (!programObject || !programObject->isLinked())
3571 {
3572 return error(GL_INVALID_OPERATION);
3573 }
3574
3575 if (!programObject)
3576 {
3577 return error(GL_INVALID_OPERATION);
3578 }
3579
3580 if (!programObject->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003581 {
3582 return error(GL_INVALID_OPERATION);
3583 }
3584 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003585 }
3586 catch(std::bad_alloc&)
3587 {
3588 return error(GL_OUT_OF_MEMORY);
3589 }
3590}
3591
3592void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3593{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003594 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003595
3596 try
3597 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003598 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003599
3600 if (context)
3601 {
3602 if (program == 0)
3603 {
3604 return error(GL_INVALID_VALUE);
3605 }
3606
3607 gl::Program *programObject = context->getProgram(program);
3608
3609 if (!programObject || !programObject->isLinked())
3610 {
3611 return error(GL_INVALID_OPERATION);
3612 }
3613
3614 if (!programObject)
3615 {
3616 return error(GL_INVALID_OPERATION);
3617 }
3618
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003619 if (!programObject->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003620 {
3621 return error(GL_INVALID_OPERATION);
3622 }
3623 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003624 }
3625 catch(std::bad_alloc&)
3626 {
3627 return error(GL_OUT_OF_MEMORY);
3628 }
3629}
3630
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003631int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003632{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003633 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003634
3635 try
3636 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003637 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003638
3639 if (strstr(name, "gl_") == name)
3640 {
3641 return -1;
3642 }
3643
3644 if (context)
3645 {
3646 gl::Program *programObject = context->getProgram(program);
3647
3648 if (!programObject)
3649 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003650 if (context->getShader(program))
3651 {
3652 return error(GL_INVALID_OPERATION, -1);
3653 }
3654 else
3655 {
3656 return error(GL_INVALID_VALUE, -1);
3657 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003658 }
3659
3660 if (!programObject->isLinked())
3661 {
3662 return error(GL_INVALID_OPERATION, -1);
3663 }
3664
daniel@transgaming.com024f1a92011-09-20 16:06:25 +00003665 return programObject->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003666 }
3667 }
3668 catch(std::bad_alloc&)
3669 {
3670 return error(GL_OUT_OF_MEMORY, -1);
3671 }
3672
3673 return -1;
3674}
3675
3676void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3677{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003678 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003679
3680 try
3681 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003682 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003683
daniel@transgaming.come0078962010-04-15 20:45:08 +00003684 if (context)
3685 {
3686 if (index >= gl::MAX_VERTEX_ATTRIBS)
3687 {
3688 return error(GL_INVALID_VALUE);
3689 }
3690
daniel@transgaming.com83921382011-01-08 05:46:00 +00003691 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003692
daniel@transgaming.come0078962010-04-15 20:45:08 +00003693 switch (pname)
3694 {
3695 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003696 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003697 break;
3698 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003699 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003700 break;
3701 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003702 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003703 break;
3704 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003705 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003706 break;
3707 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003708 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003709 break;
3710 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003711 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003712 break;
3713 case GL_CURRENT_VERTEX_ATTRIB:
3714 for (int i = 0; i < 4; ++i)
3715 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003716 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003717 }
3718 break;
3719 default: return error(GL_INVALID_ENUM);
3720 }
3721 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003722 }
3723 catch(std::bad_alloc&)
3724 {
3725 return error(GL_OUT_OF_MEMORY);
3726 }
3727}
3728
3729void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3730{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003731 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003732
3733 try
3734 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003735 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003736
daniel@transgaming.come0078962010-04-15 20:45:08 +00003737 if (context)
3738 {
3739 if (index >= gl::MAX_VERTEX_ATTRIBS)
3740 {
3741 return error(GL_INVALID_VALUE);
3742 }
3743
daniel@transgaming.com83921382011-01-08 05:46:00 +00003744 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003745
daniel@transgaming.come0078962010-04-15 20:45:08 +00003746 switch (pname)
3747 {
3748 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003749 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003750 break;
3751 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003752 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003753 break;
3754 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003755 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003756 break;
3757 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003758 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003759 break;
3760 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003761 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003762 break;
3763 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003764 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003765 break;
3766 case GL_CURRENT_VERTEX_ATTRIB:
3767 for (int i = 0; i < 4; ++i)
3768 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003769 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003770 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3771 }
3772 break;
3773 default: return error(GL_INVALID_ENUM);
3774 }
3775 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003776 }
3777 catch(std::bad_alloc&)
3778 {
3779 return error(GL_OUT_OF_MEMORY);
3780 }
3781}
3782
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003783void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003784{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003785 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003786
3787 try
3788 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003789 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003790
daniel@transgaming.come0078962010-04-15 20:45:08 +00003791 if (context)
3792 {
3793 if (index >= gl::MAX_VERTEX_ATTRIBS)
3794 {
3795 return error(GL_INVALID_VALUE);
3796 }
3797
3798 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3799 {
3800 return error(GL_INVALID_ENUM);
3801 }
3802
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003803 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003804 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003805 }
3806 catch(std::bad_alloc&)
3807 {
3808 return error(GL_OUT_OF_MEMORY);
3809 }
3810}
3811
3812void __stdcall glHint(GLenum target, GLenum mode)
3813{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003814 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003815
3816 try
3817 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003818 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003819 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003820 case GL_FASTEST:
3821 case GL_NICEST:
3822 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003823 break;
3824 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003825 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003826 }
3827
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003828 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003829 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003830 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003831 case GL_GENERATE_MIPMAP_HINT:
3832 if (context) context->setGenerateMipmapHint(mode);
3833 break;
3834 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3835 if (context) context->setFragmentShaderDerivativeHint(mode);
3836 break;
3837 default:
3838 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003839 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003840 }
3841 catch(std::bad_alloc&)
3842 {
3843 return error(GL_OUT_OF_MEMORY);
3844 }
3845}
3846
3847GLboolean __stdcall glIsBuffer(GLuint buffer)
3848{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003849 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003850
3851 try
3852 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003853 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003854
3855 if (context && buffer)
3856 {
3857 gl::Buffer *bufferObject = context->getBuffer(buffer);
3858
3859 if (bufferObject)
3860 {
3861 return GL_TRUE;
3862 }
3863 }
3864 }
3865 catch(std::bad_alloc&)
3866 {
3867 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3868 }
3869
3870 return GL_FALSE;
3871}
3872
3873GLboolean __stdcall glIsEnabled(GLenum cap)
3874{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003875 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003876
3877 try
3878 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003879 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003880
3881 if (context)
3882 {
3883 switch (cap)
3884 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003885 case GL_CULL_FACE: return context->isCullFaceEnabled();
3886 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3887 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3888 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3889 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3890 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3891 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3892 case GL_BLEND: return context->isBlendEnabled();
3893 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003894 default:
3895 return error(GL_INVALID_ENUM, false);
3896 }
3897 }
3898 }
3899 catch(std::bad_alloc&)
3900 {
3901 return error(GL_OUT_OF_MEMORY, false);
3902 }
3903
3904 return false;
3905}
3906
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003907GLboolean __stdcall glIsFenceNV(GLuint fence)
3908{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003909 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003910
3911 try
3912 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003913 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003914
3915 if (context)
3916 {
3917 gl::Fence *fenceObject = context->getFence(fence);
3918
3919 if (fenceObject == NULL)
3920 {
3921 return GL_FALSE;
3922 }
3923
3924 return fenceObject->isFence();
3925 }
3926 }
3927 catch(std::bad_alloc&)
3928 {
3929 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3930 }
3931
3932 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003933}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003934
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003935GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3936{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003937 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003938
3939 try
3940 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003941 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003942
3943 if (context && framebuffer)
3944 {
3945 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3946
3947 if (framebufferObject)
3948 {
3949 return GL_TRUE;
3950 }
3951 }
3952 }
3953 catch(std::bad_alloc&)
3954 {
3955 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3956 }
3957
3958 return GL_FALSE;
3959}
3960
3961GLboolean __stdcall glIsProgram(GLuint program)
3962{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003963 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003964
3965 try
3966 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003967 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003968
3969 if (context && program)
3970 {
3971 gl::Program *programObject = context->getProgram(program);
3972
3973 if (programObject)
3974 {
3975 return GL_TRUE;
3976 }
3977 }
3978 }
3979 catch(std::bad_alloc&)
3980 {
3981 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3982 }
3983
3984 return GL_FALSE;
3985}
3986
3987GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3988{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003989 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003990
3991 try
3992 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003993 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003994
3995 if (context && renderbuffer)
3996 {
3997 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3998
3999 if (renderbufferObject)
4000 {
4001 return GL_TRUE;
4002 }
4003 }
4004 }
4005 catch(std::bad_alloc&)
4006 {
4007 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4008 }
4009
4010 return GL_FALSE;
4011}
4012
4013GLboolean __stdcall glIsShader(GLuint shader)
4014{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004015 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004016
4017 try
4018 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004019 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004020
4021 if (context && shader)
4022 {
4023 gl::Shader *shaderObject = context->getShader(shader);
4024
4025 if (shaderObject)
4026 {
4027 return GL_TRUE;
4028 }
4029 }
4030 }
4031 catch(std::bad_alloc&)
4032 {
4033 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4034 }
4035
4036 return GL_FALSE;
4037}
4038
4039GLboolean __stdcall glIsTexture(GLuint texture)
4040{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004041 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004042
4043 try
4044 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004045 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004046
4047 if (context && texture)
4048 {
4049 gl::Texture *textureObject = context->getTexture(texture);
4050
4051 if (textureObject)
4052 {
4053 return GL_TRUE;
4054 }
4055 }
4056 }
4057 catch(std::bad_alloc&)
4058 {
4059 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4060 }
4061
4062 return GL_FALSE;
4063}
4064
4065void __stdcall glLineWidth(GLfloat width)
4066{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004067 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004068
4069 try
4070 {
4071 if (width <= 0.0f)
4072 {
4073 return error(GL_INVALID_VALUE);
4074 }
4075
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004076 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004077
4078 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004079 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004080 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004081 }
4082 }
4083 catch(std::bad_alloc&)
4084 {
4085 return error(GL_OUT_OF_MEMORY);
4086 }
4087}
4088
4089void __stdcall glLinkProgram(GLuint program)
4090{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004091 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004092
4093 try
4094 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004095 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004096
4097 if (context)
4098 {
4099 gl::Program *programObject = context->getProgram(program);
4100
4101 if (!programObject)
4102 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004103 if (context->getShader(program))
4104 {
4105 return error(GL_INVALID_OPERATION);
4106 }
4107 else
4108 {
4109 return error(GL_INVALID_VALUE);
4110 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004111 }
4112
4113 programObject->link();
4114 }
4115 }
4116 catch(std::bad_alloc&)
4117 {
4118 return error(GL_OUT_OF_MEMORY);
4119 }
4120}
4121
4122void __stdcall glPixelStorei(GLenum pname, GLint param)
4123{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004124 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004125
4126 try
4127 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004128 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004129
4130 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004131 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004132 switch (pname)
4133 {
4134 case GL_UNPACK_ALIGNMENT:
4135 if (param != 1 && param != 2 && param != 4 && param != 8)
4136 {
4137 return error(GL_INVALID_VALUE);
4138 }
4139
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004140 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004141 break;
4142
4143 case GL_PACK_ALIGNMENT:
4144 if (param != 1 && param != 2 && param != 4 && param != 8)
4145 {
4146 return error(GL_INVALID_VALUE);
4147 }
4148
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004149 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004150 break;
4151
4152 default:
4153 return error(GL_INVALID_ENUM);
4154 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004155 }
4156 }
4157 catch(std::bad_alloc&)
4158 {
4159 return error(GL_OUT_OF_MEMORY);
4160 }
4161}
4162
4163void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4164{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004165 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004166
4167 try
4168 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004169 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004170
4171 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004172 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004173 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004174 }
4175 }
4176 catch(std::bad_alloc&)
4177 {
4178 return error(GL_OUT_OF_MEMORY);
4179 }
4180}
4181
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004182void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4183 GLenum format, GLenum type, GLsizei bufSize,
4184 GLvoid *data)
4185{
4186 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4187 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4188 x, y, width, height, format, type, bufSize, data);
4189
4190 try
4191 {
4192 if (width < 0 || height < 0 || bufSize < 0)
4193 {
4194 return error(GL_INVALID_VALUE);
4195 }
4196
4197 if (!validReadFormatType(format, type))
4198 {
4199 return error(GL_INVALID_OPERATION);
4200 }
4201
4202 gl::Context *context = gl::getNonLostContext();
4203
4204 if (context)
4205 {
4206 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4207 }
4208 }
4209 catch(std::bad_alloc&)
4210 {
4211 return error(GL_OUT_OF_MEMORY);
4212 }
4213}
4214
4215void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4216 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004217{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004218 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004219 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004220 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004221
4222 try
4223 {
4224 if (width < 0 || height < 0)
4225 {
4226 return error(GL_INVALID_VALUE);
4227 }
4228
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004229 if (!validReadFormatType(format, type))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004230 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004231 return error(GL_INVALID_OPERATION);
4232 }
4233
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004234 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004235
4236 if (context)
4237 {
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004238 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004239 }
4240 }
4241 catch(std::bad_alloc&)
4242 {
4243 return error(GL_OUT_OF_MEMORY);
4244 }
4245}
4246
4247void __stdcall glReleaseShaderCompiler(void)
4248{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004249 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004250
4251 try
4252 {
4253 gl::Shader::releaseCompiler();
4254 }
4255 catch(std::bad_alloc&)
4256 {
4257 return error(GL_OUT_OF_MEMORY);
4258 }
4259}
4260
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004261void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004262{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004263 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 +00004264 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004265
4266 try
4267 {
4268 switch (target)
4269 {
4270 case GL_RENDERBUFFER:
4271 break;
4272 default:
4273 return error(GL_INVALID_ENUM);
4274 }
4275
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004276 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004277 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004278 return error(GL_INVALID_ENUM);
4279 }
4280
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004281 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004282 {
4283 return error(GL_INVALID_VALUE);
4284 }
4285
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004286 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004287
4288 if (context)
4289 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004290 if (width > context->getMaximumRenderbufferDimension() ||
4291 height > context->getMaximumRenderbufferDimension() ||
4292 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004293 {
4294 return error(GL_INVALID_VALUE);
4295 }
4296
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004297 GLuint handle = context->getRenderbufferHandle();
4298 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004299 {
4300 return error(GL_INVALID_OPERATION);
4301 }
4302
4303 switch (internalformat)
4304 {
4305 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004306 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004307 break;
4308 case GL_RGBA4:
4309 case GL_RGB5_A1:
4310 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004311 case GL_RGB8_OES:
4312 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004313 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004314 break;
4315 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004316 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004317 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004318 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004319 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004320 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004321 default:
4322 return error(GL_INVALID_ENUM);
4323 }
4324 }
4325 }
4326 catch(std::bad_alloc&)
4327 {
4328 return error(GL_OUT_OF_MEMORY);
4329 }
4330}
4331
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004332void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4333{
4334 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4335}
4336
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004337void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4338{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004339 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004340
4341 try
4342 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004343 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004344
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004345 if (context)
4346 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004347 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004348 }
4349 }
4350 catch(std::bad_alloc&)
4351 {
4352 return error(GL_OUT_OF_MEMORY);
4353 }
4354}
4355
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004356void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4357{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004358 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004359
4360 try
4361 {
4362 if (condition != GL_ALL_COMPLETED_NV)
4363 {
4364 return error(GL_INVALID_ENUM);
4365 }
4366
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004367 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004368
4369 if (context)
4370 {
4371 gl::Fence *fenceObject = context->getFence(fence);
4372
4373 if (fenceObject == NULL)
4374 {
4375 return error(GL_INVALID_OPERATION);
4376 }
4377
4378 fenceObject->setFence(condition);
4379 }
4380 }
4381 catch(std::bad_alloc&)
4382 {
4383 return error(GL_OUT_OF_MEMORY);
4384 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004385}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004386
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004387void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4388{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004389 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 +00004390
4391 try
4392 {
4393 if (width < 0 || height < 0)
4394 {
4395 return error(GL_INVALID_VALUE);
4396 }
4397
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004398 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004399
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004400 if (context)
4401 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004402 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004403 }
4404 }
4405 catch(std::bad_alloc&)
4406 {
4407 return error(GL_OUT_OF_MEMORY);
4408 }
4409}
4410
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004411void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004412{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004413 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004414 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004415 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004416
4417 try
4418 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004419 // No binary shader formats are supported.
4420 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004421 }
4422 catch(std::bad_alloc&)
4423 {
4424 return error(GL_OUT_OF_MEMORY);
4425 }
4426}
4427
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004428void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004429{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004430 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 +00004431 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004432
4433 try
4434 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004435 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004436 {
4437 return error(GL_INVALID_VALUE);
4438 }
4439
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004440 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004441
4442 if (context)
4443 {
4444 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004445
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004446 if (!shaderObject)
4447 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004448 if (context->getProgram(shader))
4449 {
4450 return error(GL_INVALID_OPERATION);
4451 }
4452 else
4453 {
4454 return error(GL_INVALID_VALUE);
4455 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004456 }
4457
4458 shaderObject->setSource(count, string, length);
4459 }
4460 }
4461 catch(std::bad_alloc&)
4462 {
4463 return error(GL_OUT_OF_MEMORY);
4464 }
4465}
4466
4467void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4468{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004469 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004470}
4471
4472void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4473{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004474 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 +00004475
4476 try
4477 {
4478 switch (face)
4479 {
4480 case GL_FRONT:
4481 case GL_BACK:
4482 case GL_FRONT_AND_BACK:
4483 break;
4484 default:
4485 return error(GL_INVALID_ENUM);
4486 }
4487
4488 switch (func)
4489 {
4490 case GL_NEVER:
4491 case GL_ALWAYS:
4492 case GL_LESS:
4493 case GL_LEQUAL:
4494 case GL_EQUAL:
4495 case GL_GEQUAL:
4496 case GL_GREATER:
4497 case GL_NOTEQUAL:
4498 break;
4499 default:
4500 return error(GL_INVALID_ENUM);
4501 }
4502
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004503 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004504
4505 if (context)
4506 {
4507 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4508 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004509 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004510 }
4511
4512 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4513 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004514 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004515 }
4516 }
4517 }
4518 catch(std::bad_alloc&)
4519 {
4520 return error(GL_OUT_OF_MEMORY);
4521 }
4522}
4523
4524void __stdcall glStencilMask(GLuint mask)
4525{
4526 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4527}
4528
4529void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4530{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004531 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004532
4533 try
4534 {
4535 switch (face)
4536 {
4537 case GL_FRONT:
4538 case GL_BACK:
4539 case GL_FRONT_AND_BACK:
4540 break;
4541 default:
4542 return error(GL_INVALID_ENUM);
4543 }
4544
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004545 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004546
4547 if (context)
4548 {
4549 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4550 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004551 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004552 }
4553
4554 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4555 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004556 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004557 }
4558 }
4559 }
4560 catch(std::bad_alloc&)
4561 {
4562 return error(GL_OUT_OF_MEMORY);
4563 }
4564}
4565
4566void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4567{
4568 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4569}
4570
4571void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4572{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004573 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 +00004574 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004575
4576 try
4577 {
4578 switch (face)
4579 {
4580 case GL_FRONT:
4581 case GL_BACK:
4582 case GL_FRONT_AND_BACK:
4583 break;
4584 default:
4585 return error(GL_INVALID_ENUM);
4586 }
4587
4588 switch (fail)
4589 {
4590 case GL_ZERO:
4591 case GL_KEEP:
4592 case GL_REPLACE:
4593 case GL_INCR:
4594 case GL_DECR:
4595 case GL_INVERT:
4596 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004597 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004598 break;
4599 default:
4600 return error(GL_INVALID_ENUM);
4601 }
4602
4603 switch (zfail)
4604 {
4605 case GL_ZERO:
4606 case GL_KEEP:
4607 case GL_REPLACE:
4608 case GL_INCR:
4609 case GL_DECR:
4610 case GL_INVERT:
4611 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004612 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004613 break;
4614 default:
4615 return error(GL_INVALID_ENUM);
4616 }
4617
4618 switch (zpass)
4619 {
4620 case GL_ZERO:
4621 case GL_KEEP:
4622 case GL_REPLACE:
4623 case GL_INCR:
4624 case GL_DECR:
4625 case GL_INVERT:
4626 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004627 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004628 break;
4629 default:
4630 return error(GL_INVALID_ENUM);
4631 }
4632
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004633 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004634
4635 if (context)
4636 {
4637 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4638 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004639 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004640 }
4641
4642 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4643 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004644 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004645 }
4646 }
4647 }
4648 catch(std::bad_alloc&)
4649 {
4650 return error(GL_OUT_OF_MEMORY);
4651 }
4652}
4653
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004654GLboolean __stdcall glTestFenceNV(GLuint fence)
4655{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004656 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004657
4658 try
4659 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004660 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004661
4662 if (context)
4663 {
4664 gl::Fence *fenceObject = context->getFence(fence);
4665
4666 if (fenceObject == NULL)
4667 {
4668 return error(GL_INVALID_OPERATION, GL_TRUE);
4669 }
4670
4671 return fenceObject->testFence();
4672 }
4673 }
4674 catch(std::bad_alloc&)
4675 {
4676 error(GL_OUT_OF_MEMORY);
4677 }
4678
4679 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004680}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004681
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004682void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4683 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004684{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004685 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 +00004686 "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 +00004687 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004688
4689 try
4690 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00004691 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004692 {
4693 return error(GL_INVALID_VALUE);
4694 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004695
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004696 if (internalformat != format)
4697 {
4698 return error(GL_INVALID_OPERATION);
4699 }
4700
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004701 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004702 {
4703 case GL_ALPHA:
4704 case GL_LUMINANCE:
4705 case GL_LUMINANCE_ALPHA:
4706 switch (type)
4707 {
4708 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004709 case GL_FLOAT:
4710 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004711 break;
4712 default:
4713 return error(GL_INVALID_ENUM);
4714 }
4715 break;
4716 case GL_RGB:
4717 switch (type)
4718 {
4719 case GL_UNSIGNED_BYTE:
4720 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004721 case GL_FLOAT:
4722 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004723 break;
4724 default:
4725 return error(GL_INVALID_ENUM);
4726 }
4727 break;
4728 case GL_RGBA:
4729 switch (type)
4730 {
4731 case GL_UNSIGNED_BYTE:
4732 case GL_UNSIGNED_SHORT_4_4_4_4:
4733 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004734 case GL_FLOAT:
4735 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004736 break;
4737 default:
4738 return error(GL_INVALID_ENUM);
4739 }
4740 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004741 case GL_BGRA_EXT:
4742 switch (type)
4743 {
4744 case GL_UNSIGNED_BYTE:
4745 break;
4746 default:
4747 return error(GL_INVALID_ENUM);
4748 }
4749 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004750 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4751 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00004752 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4753 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00004754 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004755 default:
4756 return error(GL_INVALID_VALUE);
4757 }
4758
4759 if (border != 0)
4760 {
4761 return error(GL_INVALID_VALUE);
4762 }
4763
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004764 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004765
4766 if (context)
4767 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004768 switch (target)
4769 {
4770 case GL_TEXTURE_2D:
4771 if (width > (context->getMaximumTextureDimension() >> level) ||
4772 height > (context->getMaximumTextureDimension() >> level))
4773 {
4774 return error(GL_INVALID_VALUE);
4775 }
4776 break;
4777 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4778 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4779 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4780 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4781 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4782 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4783 if (width != height)
4784 {
4785 return error(GL_INVALID_VALUE);
4786 }
4787
4788 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4789 height > (context->getMaximumCubeTextureDimension() >> level))
4790 {
4791 return error(GL_INVALID_VALUE);
4792 }
4793 break;
4794 default:
4795 return error(GL_INVALID_ENUM);
4796 }
4797
gman@chromium.org50c526d2011-08-10 05:19:44 +00004798 switch (format) {
4799 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
4800 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4801 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00004802 {
4803 return error(GL_INVALID_OPERATION);
4804 }
4805 else
4806 {
4807 return error(GL_INVALID_ENUM);
4808 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00004809 break;
4810 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4811 if (context->supportsDXT3Textures())
4812 {
4813 return error(GL_INVALID_OPERATION);
4814 }
4815 else
4816 {
4817 return error(GL_INVALID_ENUM);
4818 }
4819 break;
4820 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
4821 if (context->supportsDXT5Textures())
4822 {
4823 return error(GL_INVALID_OPERATION);
4824 }
4825 else
4826 {
4827 return error(GL_INVALID_ENUM);
4828 }
4829 break;
4830 default:
4831 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004832 }
4833
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004834 if (type == GL_FLOAT)
4835 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004836 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004837 {
4838 return error(GL_INVALID_ENUM);
4839 }
4840 }
4841 else if (type == GL_HALF_FLOAT_OES)
4842 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004843 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004844 {
4845 return error(GL_INVALID_ENUM);
4846 }
4847 }
4848
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004849 if (target == GL_TEXTURE_2D)
4850 {
4851 gl::Texture2D *texture = context->getTexture2D();
4852
4853 if (!texture)
4854 {
4855 return error(GL_INVALID_OPERATION);
4856 }
4857
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004858 if (texture->isImmutable())
4859 {
4860 return error(GL_INVALID_OPERATION);
4861 }
4862
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004863 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004864 }
4865 else
4866 {
4867 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4868
4869 if (!texture)
4870 {
4871 return error(GL_INVALID_OPERATION);
4872 }
4873
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004874 if (texture->isImmutable())
4875 {
4876 return error(GL_INVALID_OPERATION);
4877 }
4878
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004879 switch (target)
4880 {
4881 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004882 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004883 break;
4884 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004885 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004886 break;
4887 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004888 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004889 break;
4890 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004891 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004892 break;
4893 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004894 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004895 break;
4896 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004897 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004898 break;
4899 default: UNREACHABLE();
4900 }
4901 }
4902 }
4903 }
4904 catch(std::bad_alloc&)
4905 {
4906 return error(GL_OUT_OF_MEMORY);
4907 }
4908}
4909
4910void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4911{
4912 glTexParameteri(target, pname, (GLint)param);
4913}
4914
4915void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4916{
4917 glTexParameteri(target, pname, (GLint)*params);
4918}
4919
4920void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4921{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004922 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004923
4924 try
4925 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004926 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004927
4928 if (context)
4929 {
4930 gl::Texture *texture;
4931
4932 switch (target)
4933 {
4934 case GL_TEXTURE_2D:
4935 texture = context->getTexture2D();
4936 break;
4937 case GL_TEXTURE_CUBE_MAP:
4938 texture = context->getTextureCubeMap();
4939 break;
4940 default:
4941 return error(GL_INVALID_ENUM);
4942 }
4943
4944 switch (pname)
4945 {
4946 case GL_TEXTURE_WRAP_S:
4947 if (!texture->setWrapS((GLenum)param))
4948 {
4949 return error(GL_INVALID_ENUM);
4950 }
4951 break;
4952 case GL_TEXTURE_WRAP_T:
4953 if (!texture->setWrapT((GLenum)param))
4954 {
4955 return error(GL_INVALID_ENUM);
4956 }
4957 break;
4958 case GL_TEXTURE_MIN_FILTER:
4959 if (!texture->setMinFilter((GLenum)param))
4960 {
4961 return error(GL_INVALID_ENUM);
4962 }
4963 break;
4964 case GL_TEXTURE_MAG_FILTER:
4965 if (!texture->setMagFilter((GLenum)param))
4966 {
4967 return error(GL_INVALID_ENUM);
4968 }
4969 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00004970 case GL_TEXTURE_USAGE_ANGLE:
4971 if (!texture->setUsage((GLenum)param))
4972 {
4973 return error(GL_INVALID_ENUM);
4974 }
4975 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004976 default:
4977 return error(GL_INVALID_ENUM);
4978 }
4979 }
4980 }
4981 catch(std::bad_alloc&)
4982 {
4983 return error(GL_OUT_OF_MEMORY);
4984 }
4985}
4986
4987void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4988{
4989 glTexParameteri(target, pname, *params);
4990}
4991
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004992void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
4993{
4994 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4995 target, levels, internalformat, width, height);
4996
4997 try
4998 {
4999 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5000 {
5001 return error(GL_INVALID_ENUM);
5002 }
5003
5004 if (width < 1 || height < 1 || levels < 1)
5005 {
5006 return error(GL_INVALID_VALUE);
5007 }
5008
5009 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5010 {
5011 return error(GL_INVALID_VALUE);
5012 }
5013
5014 if (levels > gl::log2(std::max(width, height)) + 1)
5015 {
5016 return error(GL_INVALID_OPERATION);
5017 }
5018
5019 GLenum format = gl::ExtractFormat(internalformat);
5020 GLenum type = gl::ExtractType(internalformat);
5021
5022 if (format == GL_NONE || type == GL_NONE)
5023 {
5024 return error(GL_INVALID_ENUM);
5025 }
5026
5027 gl::Context *context = gl::getNonLostContext();
5028
5029 if (context)
5030 {
5031 if (levels != 1 && !context->supportsNonPower2Texture())
5032 {
5033 if (!gl::isPow2(width) || !gl::isPow2(height))
5034 {
5035 return error(GL_INVALID_OPERATION);
5036 }
5037 }
5038
daniel@transgaming.come1077362011-11-11 04:16:50 +00005039 switch (internalformat)
5040 {
5041 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5042 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5043 if (!context->supportsDXT1Textures())
5044 {
5045 return error(GL_INVALID_ENUM);
5046 }
5047 break;
5048 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5049 if (!context->supportsDXT3Textures())
5050 {
5051 return error(GL_INVALID_ENUM);
5052 }
5053 break;
5054 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5055 if (!context->supportsDXT5Textures())
5056 {
5057 return error(GL_INVALID_ENUM);
5058 }
5059 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005060 case GL_RGBA32F_EXT:
5061 case GL_RGB32F_EXT:
5062 case GL_ALPHA32F_EXT:
5063 case GL_LUMINANCE32F_EXT:
5064 case GL_LUMINANCE_ALPHA32F_EXT:
5065 if (!context->supportsFloat32Textures())
5066 {
5067 return error(GL_INVALID_ENUM);
5068 }
5069 break;
5070 case GL_RGBA16F_EXT:
5071 case GL_RGB16F_EXT:
5072 case GL_ALPHA16F_EXT:
5073 case GL_LUMINANCE16F_EXT:
5074 case GL_LUMINANCE_ALPHA16F_EXT:
5075 if (!context->supportsFloat16Textures())
5076 {
5077 return error(GL_INVALID_ENUM);
5078 }
5079 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005080 }
5081
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005082 if (target == GL_TEXTURE_2D)
5083 {
5084 gl::Texture2D *texture = context->getTexture2D();
5085
5086 if (!texture || texture->id() == 0)
5087 {
5088 return error(GL_INVALID_OPERATION);
5089 }
5090
5091 if (texture->isImmutable())
5092 {
5093 return error(GL_INVALID_OPERATION);
5094 }
5095
5096 texture->storage(levels, internalformat, width, height);
5097 }
5098 else if (target == GL_TEXTURE_CUBE_MAP)
5099 {
5100 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5101
5102 if (!texture || texture->id() == 0)
5103 {
5104 return error(GL_INVALID_OPERATION);
5105 }
5106
5107 if (texture->isImmutable())
5108 {
5109 return error(GL_INVALID_OPERATION);
5110 }
5111
5112 texture->storage(levels, internalformat, width);
5113 }
5114 else UNREACHABLE();
5115 }
5116 }
5117 catch(std::bad_alloc&)
5118 {
5119 return error(GL_OUT_OF_MEMORY);
5120 }
5121}
5122
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005123void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5124 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005125{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005126 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005127 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005128 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005129 target, level, xoffset, yoffset, width, height, format, type, pixels);
5130
5131 try
5132 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005133 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005134 {
5135 return error(GL_INVALID_ENUM);
5136 }
5137
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005138 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005139 {
5140 return error(GL_INVALID_VALUE);
5141 }
5142
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005143 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5144 {
5145 return error(GL_INVALID_VALUE);
5146 }
5147
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005148 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005149 {
5150 return error(GL_INVALID_ENUM);
5151 }
5152
5153 if (width == 0 || height == 0 || pixels == NULL)
5154 {
5155 return;
5156 }
5157
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005158 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005159
5160 if (context)
5161 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005162 if (level > context->getMaximumTextureLevel())
5163 {
5164 return error(GL_INVALID_VALUE);
5165 }
5166
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005167 if (format == GL_FLOAT)
5168 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005169 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005170 {
5171 return error(GL_INVALID_ENUM);
5172 }
5173 }
5174 else if (format == GL_HALF_FLOAT_OES)
5175 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005176 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005177 {
5178 return error(GL_INVALID_ENUM);
5179 }
5180 }
5181
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005182 if (target == GL_TEXTURE_2D)
5183 {
5184 gl::Texture2D *texture = context->getTexture2D();
5185
5186 if (!texture)
5187 {
5188 return error(GL_INVALID_OPERATION);
5189 }
5190
daniel@transgaming.com01868132010-08-24 19:21:17 +00005191 if (texture->isCompressed())
5192 {
5193 return error(GL_INVALID_OPERATION);
5194 }
5195
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00005196 if (format != texture->getInternalFormat())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005197 {
5198 return error(GL_INVALID_OPERATION);
5199 }
5200
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005201 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005202 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005203 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005204 {
5205 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5206
5207 if (!texture)
5208 {
5209 return error(GL_INVALID_OPERATION);
5210 }
5211
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005212 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005213 }
5214 else
5215 {
5216 UNREACHABLE();
5217 }
5218 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005219 }
5220 catch(std::bad_alloc&)
5221 {
5222 return error(GL_OUT_OF_MEMORY);
5223 }
5224}
5225
5226void __stdcall glUniform1f(GLint location, GLfloat x)
5227{
5228 glUniform1fv(location, 1, &x);
5229}
5230
5231void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5232{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005233 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005234
5235 try
5236 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005237 if (count < 0)
5238 {
5239 return error(GL_INVALID_VALUE);
5240 }
5241
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005242 if (location == -1)
5243 {
5244 return;
5245 }
5246
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005247 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005248
5249 if (context)
5250 {
5251 gl::Program *program = context->getCurrentProgram();
5252
5253 if (!program)
5254 {
5255 return error(GL_INVALID_OPERATION);
5256 }
5257
5258 if (!program->setUniform1fv(location, count, v))
5259 {
5260 return error(GL_INVALID_OPERATION);
5261 }
5262 }
5263 }
5264 catch(std::bad_alloc&)
5265 {
5266 return error(GL_OUT_OF_MEMORY);
5267 }
5268}
5269
5270void __stdcall glUniform1i(GLint location, GLint x)
5271{
5272 glUniform1iv(location, 1, &x);
5273}
5274
5275void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5276{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005277 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005278
5279 try
5280 {
5281 if (count < 0)
5282 {
5283 return error(GL_INVALID_VALUE);
5284 }
5285
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005286 if (location == -1)
5287 {
5288 return;
5289 }
5290
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005291 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005292
5293 if (context)
5294 {
5295 gl::Program *program = context->getCurrentProgram();
5296
5297 if (!program)
5298 {
5299 return error(GL_INVALID_OPERATION);
5300 }
5301
5302 if (!program->setUniform1iv(location, count, v))
5303 {
5304 return error(GL_INVALID_OPERATION);
5305 }
5306 }
5307 }
5308 catch(std::bad_alloc&)
5309 {
5310 return error(GL_OUT_OF_MEMORY);
5311 }
5312}
5313
5314void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5315{
5316 GLfloat xy[2] = {x, y};
5317
5318 glUniform2fv(location, 1, (GLfloat*)&xy);
5319}
5320
5321void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5322{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005323 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005324
5325 try
5326 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005327 if (count < 0)
5328 {
5329 return error(GL_INVALID_VALUE);
5330 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005331
5332 if (location == -1)
5333 {
5334 return;
5335 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005336
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005337 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005338
5339 if (context)
5340 {
5341 gl::Program *program = context->getCurrentProgram();
5342
5343 if (!program)
5344 {
5345 return error(GL_INVALID_OPERATION);
5346 }
5347
5348 if (!program->setUniform2fv(location, count, v))
5349 {
5350 return error(GL_INVALID_OPERATION);
5351 }
5352 }
5353 }
5354 catch(std::bad_alloc&)
5355 {
5356 return error(GL_OUT_OF_MEMORY);
5357 }
5358}
5359
5360void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5361{
5362 GLint xy[4] = {x, y};
5363
5364 glUniform2iv(location, 1, (GLint*)&xy);
5365}
5366
5367void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5368{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005369 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005370
5371 try
5372 {
5373 if (count < 0)
5374 {
5375 return error(GL_INVALID_VALUE);
5376 }
5377
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005378 if (location == -1)
5379 {
5380 return;
5381 }
5382
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005383 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005384
5385 if (context)
5386 {
5387 gl::Program *program = context->getCurrentProgram();
5388
5389 if (!program)
5390 {
5391 return error(GL_INVALID_OPERATION);
5392 }
5393
5394 if (!program->setUniform2iv(location, count, v))
5395 {
5396 return error(GL_INVALID_OPERATION);
5397 }
5398 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005399 }
5400 catch(std::bad_alloc&)
5401 {
5402 return error(GL_OUT_OF_MEMORY);
5403 }
5404}
5405
5406void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5407{
5408 GLfloat xyz[3] = {x, y, z};
5409
5410 glUniform3fv(location, 1, (GLfloat*)&xyz);
5411}
5412
5413void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5414{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005415 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005416
5417 try
5418 {
5419 if (count < 0)
5420 {
5421 return error(GL_INVALID_VALUE);
5422 }
5423
5424 if (location == -1)
5425 {
5426 return;
5427 }
5428
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005429 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005430
5431 if (context)
5432 {
5433 gl::Program *program = context->getCurrentProgram();
5434
5435 if (!program)
5436 {
5437 return error(GL_INVALID_OPERATION);
5438 }
5439
5440 if (!program->setUniform3fv(location, count, v))
5441 {
5442 return error(GL_INVALID_OPERATION);
5443 }
5444 }
5445 }
5446 catch(std::bad_alloc&)
5447 {
5448 return error(GL_OUT_OF_MEMORY);
5449 }
5450}
5451
5452void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5453{
5454 GLint xyz[3] = {x, y, z};
5455
5456 glUniform3iv(location, 1, (GLint*)&xyz);
5457}
5458
5459void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5460{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005461 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005462
5463 try
5464 {
5465 if (count < 0)
5466 {
5467 return error(GL_INVALID_VALUE);
5468 }
5469
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005470 if (location == -1)
5471 {
5472 return;
5473 }
5474
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005475 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005476
5477 if (context)
5478 {
5479 gl::Program *program = context->getCurrentProgram();
5480
5481 if (!program)
5482 {
5483 return error(GL_INVALID_OPERATION);
5484 }
5485
5486 if (!program->setUniform3iv(location, count, v))
5487 {
5488 return error(GL_INVALID_OPERATION);
5489 }
5490 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005491 }
5492 catch(std::bad_alloc&)
5493 {
5494 return error(GL_OUT_OF_MEMORY);
5495 }
5496}
5497
5498void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5499{
5500 GLfloat xyzw[4] = {x, y, z, w};
5501
5502 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5503}
5504
5505void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5506{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005507 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005508
5509 try
5510 {
5511 if (count < 0)
5512 {
5513 return error(GL_INVALID_VALUE);
5514 }
5515
5516 if (location == -1)
5517 {
5518 return;
5519 }
5520
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005521 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005522
5523 if (context)
5524 {
5525 gl::Program *program = context->getCurrentProgram();
5526
5527 if (!program)
5528 {
5529 return error(GL_INVALID_OPERATION);
5530 }
5531
5532 if (!program->setUniform4fv(location, count, v))
5533 {
5534 return error(GL_INVALID_OPERATION);
5535 }
5536 }
5537 }
5538 catch(std::bad_alloc&)
5539 {
5540 return error(GL_OUT_OF_MEMORY);
5541 }
5542}
5543
5544void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5545{
5546 GLint xyzw[4] = {x, y, z, w};
5547
5548 glUniform4iv(location, 1, (GLint*)&xyzw);
5549}
5550
5551void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5552{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005553 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005554
5555 try
5556 {
5557 if (count < 0)
5558 {
5559 return error(GL_INVALID_VALUE);
5560 }
5561
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005562 if (location == -1)
5563 {
5564 return;
5565 }
5566
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005567 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005568
5569 if (context)
5570 {
5571 gl::Program *program = context->getCurrentProgram();
5572
5573 if (!program)
5574 {
5575 return error(GL_INVALID_OPERATION);
5576 }
5577
5578 if (!program->setUniform4iv(location, count, v))
5579 {
5580 return error(GL_INVALID_OPERATION);
5581 }
5582 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005583 }
5584 catch(std::bad_alloc&)
5585 {
5586 return error(GL_OUT_OF_MEMORY);
5587 }
5588}
5589
5590void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5591{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005592 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005593 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005594
5595 try
5596 {
5597 if (count < 0 || transpose != GL_FALSE)
5598 {
5599 return error(GL_INVALID_VALUE);
5600 }
5601
5602 if (location == -1)
5603 {
5604 return;
5605 }
5606
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005607 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005608
5609 if (context)
5610 {
5611 gl::Program *program = context->getCurrentProgram();
5612
5613 if (!program)
5614 {
5615 return error(GL_INVALID_OPERATION);
5616 }
5617
5618 if (!program->setUniformMatrix2fv(location, count, value))
5619 {
5620 return error(GL_INVALID_OPERATION);
5621 }
5622 }
5623 }
5624 catch(std::bad_alloc&)
5625 {
5626 return error(GL_OUT_OF_MEMORY);
5627 }
5628}
5629
5630void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5631{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005632 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005633 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005634
5635 try
5636 {
5637 if (count < 0 || transpose != GL_FALSE)
5638 {
5639 return error(GL_INVALID_VALUE);
5640 }
5641
5642 if (location == -1)
5643 {
5644 return;
5645 }
5646
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005647 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005648
5649 if (context)
5650 {
5651 gl::Program *program = context->getCurrentProgram();
5652
5653 if (!program)
5654 {
5655 return error(GL_INVALID_OPERATION);
5656 }
5657
5658 if (!program->setUniformMatrix3fv(location, count, value))
5659 {
5660 return error(GL_INVALID_OPERATION);
5661 }
5662 }
5663 }
5664 catch(std::bad_alloc&)
5665 {
5666 return error(GL_OUT_OF_MEMORY);
5667 }
5668}
5669
5670void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5671{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005672 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005673 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005674
5675 try
5676 {
5677 if (count < 0 || transpose != GL_FALSE)
5678 {
5679 return error(GL_INVALID_VALUE);
5680 }
5681
5682 if (location == -1)
5683 {
5684 return;
5685 }
5686
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005687 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005688
5689 if (context)
5690 {
5691 gl::Program *program = context->getCurrentProgram();
5692
5693 if (!program)
5694 {
5695 return error(GL_INVALID_OPERATION);
5696 }
5697
5698 if (!program->setUniformMatrix4fv(location, count, value))
5699 {
5700 return error(GL_INVALID_OPERATION);
5701 }
5702 }
5703 }
5704 catch(std::bad_alloc&)
5705 {
5706 return error(GL_OUT_OF_MEMORY);
5707 }
5708}
5709
5710void __stdcall glUseProgram(GLuint program)
5711{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005712 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005713
5714 try
5715 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005716 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005717
5718 if (context)
5719 {
5720 gl::Program *programObject = context->getProgram(program);
5721
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005722 if (!programObject && program != 0)
5723 {
5724 if (context->getShader(program))
5725 {
5726 return error(GL_INVALID_OPERATION);
5727 }
5728 else
5729 {
5730 return error(GL_INVALID_VALUE);
5731 }
5732 }
5733
5734 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005735 {
5736 return error(GL_INVALID_OPERATION);
5737 }
5738
5739 context->useProgram(program);
5740 }
5741 }
5742 catch(std::bad_alloc&)
5743 {
5744 return error(GL_OUT_OF_MEMORY);
5745 }
5746}
5747
5748void __stdcall glValidateProgram(GLuint program)
5749{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005750 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005751
5752 try
5753 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005754 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005755
5756 if (context)
5757 {
5758 gl::Program *programObject = context->getProgram(program);
5759
5760 if (!programObject)
5761 {
5762 if (context->getShader(program))
5763 {
5764 return error(GL_INVALID_OPERATION);
5765 }
5766 else
5767 {
5768 return error(GL_INVALID_VALUE);
5769 }
5770 }
5771
5772 programObject->validate();
5773 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005774 }
5775 catch(std::bad_alloc&)
5776 {
5777 return error(GL_OUT_OF_MEMORY);
5778 }
5779}
5780
5781void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5782{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005783 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005784
5785 try
5786 {
5787 if (index >= gl::MAX_VERTEX_ATTRIBS)
5788 {
5789 return error(GL_INVALID_VALUE);
5790 }
5791
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005792 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005793
5794 if (context)
5795 {
5796 GLfloat vals[4] = { x, 0, 0, 1 };
5797 context->setVertexAttrib(index, vals);
5798 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005799 }
5800 catch(std::bad_alloc&)
5801 {
5802 return error(GL_OUT_OF_MEMORY);
5803 }
5804}
5805
5806void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5807{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005808 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005809
5810 try
5811 {
5812 if (index >= gl::MAX_VERTEX_ATTRIBS)
5813 {
5814 return error(GL_INVALID_VALUE);
5815 }
5816
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005817 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005818
5819 if (context)
5820 {
5821 GLfloat vals[4] = { values[0], 0, 0, 1 };
5822 context->setVertexAttrib(index, vals);
5823 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005824 }
5825 catch(std::bad_alloc&)
5826 {
5827 return error(GL_OUT_OF_MEMORY);
5828 }
5829}
5830
5831void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5832{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005833 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005834
5835 try
5836 {
5837 if (index >= gl::MAX_VERTEX_ATTRIBS)
5838 {
5839 return error(GL_INVALID_VALUE);
5840 }
5841
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005842 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005843
5844 if (context)
5845 {
5846 GLfloat vals[4] = { x, y, 0, 1 };
5847 context->setVertexAttrib(index, vals);
5848 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005849 }
5850 catch(std::bad_alloc&)
5851 {
5852 return error(GL_OUT_OF_MEMORY);
5853 }
5854}
5855
5856void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5857{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005858 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005859
5860 try
5861 {
5862 if (index >= gl::MAX_VERTEX_ATTRIBS)
5863 {
5864 return error(GL_INVALID_VALUE);
5865 }
5866
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005867 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005868
5869 if (context)
5870 {
5871 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5872 context->setVertexAttrib(index, vals);
5873 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005874 }
5875 catch(std::bad_alloc&)
5876 {
5877 return error(GL_OUT_OF_MEMORY);
5878 }
5879}
5880
5881void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5882{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005883 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 +00005884
5885 try
5886 {
5887 if (index >= gl::MAX_VERTEX_ATTRIBS)
5888 {
5889 return error(GL_INVALID_VALUE);
5890 }
5891
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005892 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005893
5894 if (context)
5895 {
5896 GLfloat vals[4] = { x, y, z, 1 };
5897 context->setVertexAttrib(index, vals);
5898 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005899 }
5900 catch(std::bad_alloc&)
5901 {
5902 return error(GL_OUT_OF_MEMORY);
5903 }
5904}
5905
5906void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5907{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005908 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005909
5910 try
5911 {
5912 if (index >= gl::MAX_VERTEX_ATTRIBS)
5913 {
5914 return error(GL_INVALID_VALUE);
5915 }
5916
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005917 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005918
5919 if (context)
5920 {
5921 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5922 context->setVertexAttrib(index, vals);
5923 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005924 }
5925 catch(std::bad_alloc&)
5926 {
5927 return error(GL_OUT_OF_MEMORY);
5928 }
5929}
5930
5931void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5932{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005933 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 +00005934
5935 try
5936 {
5937 if (index >= gl::MAX_VERTEX_ATTRIBS)
5938 {
5939 return error(GL_INVALID_VALUE);
5940 }
5941
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005942 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005943
5944 if (context)
5945 {
5946 GLfloat vals[4] = { x, y, z, w };
5947 context->setVertexAttrib(index, vals);
5948 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005949 }
5950 catch(std::bad_alloc&)
5951 {
5952 return error(GL_OUT_OF_MEMORY);
5953 }
5954}
5955
5956void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5957{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005958 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005959
5960 try
5961 {
5962 if (index >= gl::MAX_VERTEX_ATTRIBS)
5963 {
5964 return error(GL_INVALID_VALUE);
5965 }
5966
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005967 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005968
5969 if (context)
5970 {
5971 context->setVertexAttrib(index, values);
5972 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005973 }
5974 catch(std::bad_alloc&)
5975 {
5976 return error(GL_OUT_OF_MEMORY);
5977 }
5978}
5979
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005980void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005981{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005982 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005983 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005984 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005985
5986 try
5987 {
5988 if (index >= gl::MAX_VERTEX_ATTRIBS)
5989 {
5990 return error(GL_INVALID_VALUE);
5991 }
5992
5993 if (size < 1 || size > 4)
5994 {
5995 return error(GL_INVALID_VALUE);
5996 }
5997
5998 switch (type)
5999 {
6000 case GL_BYTE:
6001 case GL_UNSIGNED_BYTE:
6002 case GL_SHORT:
6003 case GL_UNSIGNED_SHORT:
6004 case GL_FIXED:
6005 case GL_FLOAT:
6006 break;
6007 default:
6008 return error(GL_INVALID_ENUM);
6009 }
6010
6011 if (stride < 0)
6012 {
6013 return error(GL_INVALID_VALUE);
6014 }
6015
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006016 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006017
6018 if (context)
6019 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006020 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006021 }
6022 }
6023 catch(std::bad_alloc&)
6024 {
6025 return error(GL_OUT_OF_MEMORY);
6026 }
6027}
6028
6029void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6030{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006031 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 +00006032
6033 try
6034 {
6035 if (width < 0 || height < 0)
6036 {
6037 return error(GL_INVALID_VALUE);
6038 }
6039
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006040 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006041
6042 if (context)
6043 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006044 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006045 }
6046 }
6047 catch(std::bad_alloc&)
6048 {
6049 return error(GL_OUT_OF_MEMORY);
6050 }
6051}
6052
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006053void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6054 GLbitfield mask, GLenum filter)
6055{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006056 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006057 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6058 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6059 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6060
6061 try
6062 {
6063 switch (filter)
6064 {
6065 case GL_NEAREST:
6066 break;
6067 default:
6068 return error(GL_INVALID_ENUM);
6069 }
6070
6071 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6072 {
6073 return error(GL_INVALID_VALUE);
6074 }
6075
6076 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6077 {
6078 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6079 return error(GL_INVALID_OPERATION);
6080 }
6081
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006082 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006083
6084 if (context)
6085 {
6086 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6087 {
6088 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6089 return error(GL_INVALID_OPERATION);
6090 }
6091
6092 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6093 }
6094 }
6095 catch(std::bad_alloc&)
6096 {
6097 return error(GL_OUT_OF_MEMORY);
6098 }
6099}
6100
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006101void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6102 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006103{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006104 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006105 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006106 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006107 target, level, internalformat, width, height, depth, border, format, type, pixels);
6108
6109 try
6110 {
6111 UNIMPLEMENTED(); // FIXME
6112 }
6113 catch(std::bad_alloc&)
6114 {
6115 return error(GL_OUT_OF_MEMORY);
6116 }
6117}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006118
6119__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6120{
6121 struct Extension
6122 {
6123 const char *name;
6124 __eglMustCastToProperFunctionPointerType address;
6125 };
6126
6127 static const Extension glExtensions[] =
6128 {
6129 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006130 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006131 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006132 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6133 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006134 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006135 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6136 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6137 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6138 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6139 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006140 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006141 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006142 };
6143
6144 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6145 {
6146 if (strcmp(procname, glExtensions[ext].name) == 0)
6147 {
6148 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6149 }
6150 }
6151
6152 return NULL;
6153}
6154
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006155// Non-public functions used by EGL
6156
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006157bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006158{
6159 EVENT("(egl::Surface* surface = 0x%0.8p)",
6160 surface);
6161
6162 try
6163 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006164 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006165
6166 if (context)
6167 {
6168 gl::Texture2D *textureObject = context->getTexture2D();
6169
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006170 if (textureObject->isImmutable())
6171 {
6172 return false;
6173 }
6174
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006175 if (textureObject)
6176 {
6177 textureObject->bindTexImage(surface);
6178 }
6179 }
6180 }
6181 catch(std::bad_alloc&)
6182 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006183 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006184 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006185
6186 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006187}
6188
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006189}