blob: f75d798d895c362aafcafc46b9e524e5cea90b3f [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +00002// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +000017#include "common/version.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000018
19#include "libGLESv2/main.h"
20#include "libGLESv2/mathutil.h"
21#include "libGLESv2/utilities.h"
22#include "libGLESv2/Buffer.h"
23#include "libGLESv2/Context.h"
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000024#include "libGLESv2/Fence.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000025#include "libGLESv2/Framebuffer.h"
26#include "libGLESv2/Program.h"
27#include "libGLESv2/Renderbuffer.h"
28#include "libGLESv2/Shader.h"
29#include "libGLESv2/Texture.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000030
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +000031bool validImageSize(GLint level, GLsizei width, GLsizei height)
32{
33 if (level < 0 || width < 0 || height < 0)
34 {
35 return false;
36 }
37
38 if (gl::getContext() && gl::getContext()->supportsNonPower2Texture())
39 {
40 return true;
41 }
42
43 if (level == 0)
44 {
45 return true;
46 }
47
48 if (gl::isPow2(width) && gl::isPow2(height))
49 {
50 return true;
51 }
52
53 return false;
54}
55
daniel@transgaming.comb7915a52011-11-12 03:14:20 +000056// check for combinations of format and type that are valid for ReadPixels
57bool validReadFormatType(GLenum format, GLenum type)
58{
59 switch (format)
60 {
61 case GL_RGBA:
62 switch (type)
63 {
64 case GL_UNSIGNED_BYTE:
65 break;
66 default:
67 return false;
68 }
69 break;
70 case GL_BGRA_EXT:
71 switch (type)
72 {
73 case GL_UNSIGNED_BYTE:
74 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
75 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
76 break;
77 default:
78 return false;
79 }
80 break;
81 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
82 switch (type)
83 {
84 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
85 break;
86 default:
87 return false;
88 }
89 break;
90 default:
91 return false;
92 }
93 return true;
94}
95
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000096extern "C"
97{
98
99void __stdcall glActiveTexture(GLenum texture)
100{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000101 EVENT("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000102
103 try
104 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000105 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000106
107 if (context)
108 {
daniel@transgaming.com3f74c7a2011-05-11 15:36:51 +0000109 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
110 {
111 return error(GL_INVALID_ENUM);
112 }
113
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000114 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000115 }
116 }
117 catch(std::bad_alloc&)
118 {
119 return error(GL_OUT_OF_MEMORY);
120 }
121}
122
123void __stdcall glAttachShader(GLuint program, GLuint shader)
124{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000125 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000126
127 try
128 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000129 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000130
131 if (context)
132 {
133 gl::Program *programObject = context->getProgram(program);
134 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000135
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000136 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +0000138 if (context->getShader(program))
139 {
140 return error(GL_INVALID_OPERATION);
141 }
142 else
143 {
144 return error(GL_INVALID_VALUE);
145 }
146 }
147
148 if (!shaderObject)
149 {
150 if (context->getProgram(shader))
151 {
152 return error(GL_INVALID_OPERATION);
153 }
154 else
155 {
156 return error(GL_INVALID_VALUE);
157 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000158 }
159
160 if (!programObject->attachShader(shaderObject))
161 {
162 return error(GL_INVALID_OPERATION);
163 }
164 }
165 }
166 catch(std::bad_alloc&)
167 {
168 return error(GL_OUT_OF_MEMORY);
169 }
170}
171
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000172void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000173{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000174 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000175
176 try
177 {
178 if (index >= gl::MAX_VERTEX_ATTRIBS)
179 {
180 return error(GL_INVALID_VALUE);
181 }
182
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000183 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000184
185 if (context)
186 {
187 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000188
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000189 if (!programObject)
190 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000191 if (context->getShader(program))
192 {
193 return error(GL_INVALID_OPERATION);
194 }
195 else
196 {
197 return error(GL_INVALID_VALUE);
198 }
199 }
200
201 if (strncmp(name, "gl_", 3) == 0)
202 {
203 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000204 }
205
206 programObject->bindAttributeLocation(index, name);
207 }
208 }
209 catch(std::bad_alloc&)
210 {
211 return error(GL_OUT_OF_MEMORY);
212 }
213}
214
215void __stdcall glBindBuffer(GLenum target, GLuint buffer)
216{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000217 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000218
219 try
220 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000221 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000222
223 if (context)
224 {
225 switch (target)
226 {
227 case GL_ARRAY_BUFFER:
228 context->bindArrayBuffer(buffer);
229 return;
230 case GL_ELEMENT_ARRAY_BUFFER:
231 context->bindElementArrayBuffer(buffer);
232 return;
233 default:
234 return error(GL_INVALID_ENUM);
235 }
236 }
237 }
238 catch(std::bad_alloc&)
239 {
240 return error(GL_OUT_OF_MEMORY);
241 }
242}
243
244void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
245{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000246 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000247
248 try
249 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000250 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000251 {
252 return error(GL_INVALID_ENUM);
253 }
254
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000255 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000256
257 if (context)
258 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000259 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
260 {
261 context->bindReadFramebuffer(framebuffer);
262 }
263
264 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
265 {
266 context->bindDrawFramebuffer(framebuffer);
267 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000268 }
269 }
270 catch(std::bad_alloc&)
271 {
272 return error(GL_OUT_OF_MEMORY);
273 }
274}
275
276void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
277{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000278 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000279
280 try
281 {
282 if (target != GL_RENDERBUFFER)
283 {
284 return error(GL_INVALID_ENUM);
285 }
286
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000287 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000288
289 if (context)
290 {
291 context->bindRenderbuffer(renderbuffer);
292 }
293 }
294 catch(std::bad_alloc&)
295 {
296 return error(GL_OUT_OF_MEMORY);
297 }
298}
299
300void __stdcall glBindTexture(GLenum target, GLuint texture)
301{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000302 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000303
304 try
305 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000306 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000307
308 if (context)
309 {
310 gl::Texture *textureObject = context->getTexture(texture);
311
312 if (textureObject && textureObject->getTarget() != target && texture != 0)
313 {
314 return error(GL_INVALID_OPERATION);
315 }
316
317 switch (target)
318 {
319 case GL_TEXTURE_2D:
320 context->bindTexture2D(texture);
321 return;
322 case GL_TEXTURE_CUBE_MAP:
323 context->bindTextureCubeMap(texture);
324 return;
325 default:
326 return error(GL_INVALID_ENUM);
327 }
328 }
329 }
330 catch(std::bad_alloc&)
331 {
332 return error(GL_OUT_OF_MEMORY);
333 }
334}
335
336void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
337{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000338 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000339 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000340
341 try
342 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000343 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000344
345 if (context)
346 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000347 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000348 }
349 }
350 catch(std::bad_alloc&)
351 {
352 return error(GL_OUT_OF_MEMORY);
353 }
354}
355
356void __stdcall glBlendEquation(GLenum mode)
357{
358 glBlendEquationSeparate(mode, mode);
359}
360
361void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
362{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000363 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000364
365 try
366 {
367 switch (modeRGB)
368 {
369 case GL_FUNC_ADD:
370 case GL_FUNC_SUBTRACT:
371 case GL_FUNC_REVERSE_SUBTRACT:
372 break;
373 default:
374 return error(GL_INVALID_ENUM);
375 }
376
377 switch (modeAlpha)
378 {
379 case GL_FUNC_ADD:
380 case GL_FUNC_SUBTRACT:
381 case GL_FUNC_REVERSE_SUBTRACT:
382 break;
383 default:
384 return error(GL_INVALID_ENUM);
385 }
386
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000387 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000388
389 if (context)
390 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000391 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000392 }
393 }
394 catch(std::bad_alloc&)
395 {
396 return error(GL_OUT_OF_MEMORY);
397 }
398}
399
400void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
401{
402 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
403}
404
405void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
406{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000407 EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000408 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000409
410 try
411 {
412 switch (srcRGB)
413 {
414 case GL_ZERO:
415 case GL_ONE:
416 case GL_SRC_COLOR:
417 case GL_ONE_MINUS_SRC_COLOR:
418 case GL_DST_COLOR:
419 case GL_ONE_MINUS_DST_COLOR:
420 case GL_SRC_ALPHA:
421 case GL_ONE_MINUS_SRC_ALPHA:
422 case GL_DST_ALPHA:
423 case GL_ONE_MINUS_DST_ALPHA:
424 case GL_CONSTANT_COLOR:
425 case GL_ONE_MINUS_CONSTANT_COLOR:
426 case GL_CONSTANT_ALPHA:
427 case GL_ONE_MINUS_CONSTANT_ALPHA:
428 case GL_SRC_ALPHA_SATURATE:
429 break;
430 default:
431 return error(GL_INVALID_ENUM);
432 }
433
434 switch (dstRGB)
435 {
436 case GL_ZERO:
437 case GL_ONE:
438 case GL_SRC_COLOR:
439 case GL_ONE_MINUS_SRC_COLOR:
440 case GL_DST_COLOR:
441 case GL_ONE_MINUS_DST_COLOR:
442 case GL_SRC_ALPHA:
443 case GL_ONE_MINUS_SRC_ALPHA:
444 case GL_DST_ALPHA:
445 case GL_ONE_MINUS_DST_ALPHA:
446 case GL_CONSTANT_COLOR:
447 case GL_ONE_MINUS_CONSTANT_COLOR:
448 case GL_CONSTANT_ALPHA:
449 case GL_ONE_MINUS_CONSTANT_ALPHA:
450 break;
451 default:
452 return error(GL_INVALID_ENUM);
453 }
454
455 switch (srcAlpha)
456 {
457 case GL_ZERO:
458 case GL_ONE:
459 case GL_SRC_COLOR:
460 case GL_ONE_MINUS_SRC_COLOR:
461 case GL_DST_COLOR:
462 case GL_ONE_MINUS_DST_COLOR:
463 case GL_SRC_ALPHA:
464 case GL_ONE_MINUS_SRC_ALPHA:
465 case GL_DST_ALPHA:
466 case GL_ONE_MINUS_DST_ALPHA:
467 case GL_CONSTANT_COLOR:
468 case GL_ONE_MINUS_CONSTANT_COLOR:
469 case GL_CONSTANT_ALPHA:
470 case GL_ONE_MINUS_CONSTANT_ALPHA:
471 case GL_SRC_ALPHA_SATURATE:
472 break;
473 default:
474 return error(GL_INVALID_ENUM);
475 }
476
477 switch (dstAlpha)
478 {
479 case GL_ZERO:
480 case GL_ONE:
481 case GL_SRC_COLOR:
482 case GL_ONE_MINUS_SRC_COLOR:
483 case GL_DST_COLOR:
484 case GL_ONE_MINUS_DST_COLOR:
485 case GL_SRC_ALPHA:
486 case GL_ONE_MINUS_SRC_ALPHA:
487 case GL_DST_ALPHA:
488 case GL_ONE_MINUS_DST_ALPHA:
489 case GL_CONSTANT_COLOR:
490 case GL_ONE_MINUS_CONSTANT_COLOR:
491 case GL_CONSTANT_ALPHA:
492 case GL_ONE_MINUS_CONSTANT_ALPHA:
493 break;
494 default:
495 return error(GL_INVALID_ENUM);
496 }
497
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000498 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
499 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
500
501 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
502 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
503
504 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000505 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000506 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
507 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000508 }
509
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000510 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000511
512 if (context)
513 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000514 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000515 }
516 }
517 catch(std::bad_alloc&)
518 {
519 return error(GL_OUT_OF_MEMORY);
520 }
521}
522
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000523void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000524{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000525 EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000526 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000527
528 try
529 {
530 if (size < 0)
531 {
532 return error(GL_INVALID_VALUE);
533 }
534
535 switch (usage)
536 {
537 case GL_STREAM_DRAW:
538 case GL_STATIC_DRAW:
539 case GL_DYNAMIC_DRAW:
540 break;
541 default:
542 return error(GL_INVALID_ENUM);
543 }
544
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000545 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000546
547 if (context)
548 {
549 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000550
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000551 switch (target)
552 {
553 case GL_ARRAY_BUFFER:
554 buffer = context->getArrayBuffer();
555 break;
556 case GL_ELEMENT_ARRAY_BUFFER:
557 buffer = context->getElementArrayBuffer();
558 break;
559 default:
560 return error(GL_INVALID_ENUM);
561 }
562
563 if (!buffer)
564 {
565 return error(GL_INVALID_OPERATION);
566 }
567
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000568 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000569 }
570 }
571 catch(std::bad_alloc&)
572 {
573 return error(GL_OUT_OF_MEMORY);
574 }
575}
576
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000577void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000578{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000579 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000580 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000581
582 try
583 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000584 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000585 {
586 return error(GL_INVALID_VALUE);
587 }
588
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000589 if (data == NULL)
590 {
591 return;
592 }
593
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000594 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000595
596 if (context)
597 {
598 gl::Buffer *buffer;
599
600 switch (target)
601 {
602 case GL_ARRAY_BUFFER:
603 buffer = context->getArrayBuffer();
604 break;
605 case GL_ELEMENT_ARRAY_BUFFER:
606 buffer = context->getElementArrayBuffer();
607 break;
608 default:
609 return error(GL_INVALID_ENUM);
610 }
611
612 if (!buffer)
613 {
614 return error(GL_INVALID_OPERATION);
615 }
616
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000617 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000618 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000619 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000620 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000621
622 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000623 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000624 }
625 catch(std::bad_alloc&)
626 {
627 return error(GL_OUT_OF_MEMORY);
628 }
629}
630
631GLenum __stdcall glCheckFramebufferStatus(GLenum target)
632{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000633 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000634
635 try
636 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000637 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000638 {
639 return error(GL_INVALID_ENUM, 0);
640 }
641
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000642 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000643
644 if (context)
645 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000646 gl::Framebuffer *framebuffer = NULL;
647 if (target == GL_READ_FRAMEBUFFER_ANGLE)
648 {
649 framebuffer = context->getReadFramebuffer();
650 }
651 else
652 {
653 framebuffer = context->getDrawFramebuffer();
654 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000655
656 return framebuffer->completeness();
657 }
658 }
659 catch(std::bad_alloc&)
660 {
661 return error(GL_OUT_OF_MEMORY, 0);
662 }
663
664 return 0;
665}
666
667void __stdcall glClear(GLbitfield mask)
668{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000669 EVENT("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000670
671 try
672 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000673 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000674
675 if (context)
676 {
677 context->clear(mask);
678 }
679 }
680 catch(std::bad_alloc&)
681 {
682 return error(GL_OUT_OF_MEMORY);
683 }
684}
685
686void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
687{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000688 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000689 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000690
691 try
692 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000693 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000694
695 if (context)
696 {
697 context->setClearColor(red, green, blue, alpha);
698 }
699 }
700 catch(std::bad_alloc&)
701 {
702 return error(GL_OUT_OF_MEMORY);
703 }
704}
705
706void __stdcall glClearDepthf(GLclampf depth)
707{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000708 EVENT("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000709
710 try
711 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000712 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000713
714 if (context)
715 {
716 context->setClearDepth(depth);
717 }
718 }
719 catch(std::bad_alloc&)
720 {
721 return error(GL_OUT_OF_MEMORY);
722 }
723}
724
725void __stdcall glClearStencil(GLint s)
726{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000727 EVENT("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000728
729 try
730 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000731 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000732
733 if (context)
734 {
735 context->setClearStencil(s);
736 }
737 }
738 catch(std::bad_alloc&)
739 {
740 return error(GL_OUT_OF_MEMORY);
741 }
742}
743
744void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
745{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000746 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000747 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748
749 try
750 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000751 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000752
753 if (context)
754 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000755 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000756 }
757 }
758 catch(std::bad_alloc&)
759 {
760 return error(GL_OUT_OF_MEMORY);
761 }
762}
763
764void __stdcall glCompileShader(GLuint shader)
765{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000766 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000767
768 try
769 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000770 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000771
772 if (context)
773 {
774 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000775
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000776 if (!shaderObject)
777 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000778 if (context->getProgram(shader))
779 {
780 return error(GL_INVALID_OPERATION);
781 }
782 else
783 {
784 return error(GL_INVALID_VALUE);
785 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000786 }
787
788 shaderObject->compile();
789 }
790 }
791 catch(std::bad_alloc&)
792 {
793 return error(GL_OUT_OF_MEMORY);
794 }
795}
796
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000797void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
798 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000799{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000800 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000801 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000802 target, level, internalformat, width, height, border, imageSize, data);
803
804 try
805 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000806 if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000807 {
808 return error(GL_INVALID_VALUE);
809 }
810
daniel@transgaming.com01868132010-08-24 19:21:17 +0000811 switch (internalformat)
812 {
813 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
814 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +0000815 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
816 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +0000817 break;
818 default:
819 return error(GL_INVALID_ENUM);
820 }
821
822 if (border != 0)
823 {
824 return error(GL_INVALID_VALUE);
825 }
826
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000827 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000828
829 if (context)
830 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000831 if (level > context->getMaximumTextureLevel())
832 {
833 return error(GL_INVALID_VALUE);
834 }
835
836 switch (target)
837 {
838 case GL_TEXTURE_2D:
839 if (width > (context->getMaximumTextureDimension() >> level) ||
840 height > (context->getMaximumTextureDimension() >> level))
841 {
842 return error(GL_INVALID_VALUE);
843 }
844 break;
845 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
846 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
847 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
848 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
849 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
850 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
851 if (width != height)
852 {
853 return error(GL_INVALID_VALUE);
854 }
855
856 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
857 height > (context->getMaximumCubeTextureDimension() >> level))
858 {
859 return error(GL_INVALID_VALUE);
860 }
861 break;
862 default:
863 return error(GL_INVALID_ENUM);
864 }
865
gman@chromium.org50c526d2011-08-10 05:19:44 +0000866 switch (internalformat) {
867 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
868 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
869 if (!context->supportsDXT1Textures())
870 {
871 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
872 }
873 break;
874 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
875 if (!context->supportsDXT3Textures())
876 {
877 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
878 }
879 break;
880 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
881 if (!context->supportsDXT5Textures())
882 {
883 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
884 }
885 break;
886 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000887 }
888
889 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
890 {
891 return error(GL_INVALID_VALUE);
892 }
893
894 if (target == GL_TEXTURE_2D)
895 {
896 gl::Texture2D *texture = context->getTexture2D();
897
898 if (!texture)
899 {
900 return error(GL_INVALID_OPERATION);
901 }
902
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +0000903 if (texture->isImmutable())
904 {
905 return error(GL_INVALID_OPERATION);
906 }
907
daniel@transgaming.com01868132010-08-24 19:21:17 +0000908 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
909 }
910 else
911 {
912 gl::TextureCubeMap *texture = context->getTextureCubeMap();
913
914 if (!texture)
915 {
916 return error(GL_INVALID_OPERATION);
917 }
918
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +0000919 if (texture->isImmutable())
920 {
921 return error(GL_INVALID_OPERATION);
922 }
923
daniel@transgaming.com01868132010-08-24 19:21:17 +0000924 switch (target)
925 {
926 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
927 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
928 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
929 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
930 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
931 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
932 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
933 break;
934 default: UNREACHABLE();
935 }
936 }
937 }
938
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000939 }
940 catch(std::bad_alloc&)
941 {
942 return error(GL_OUT_OF_MEMORY);
943 }
944}
945
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000946void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
947 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000948{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000949 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000950 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000951 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000952 target, level, xoffset, yoffset, width, height, format, imageSize, data);
953
954 try
955 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000956 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000957 {
958 return error(GL_INVALID_ENUM);
959 }
960
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +0000961 if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000962 {
963 return error(GL_INVALID_VALUE);
964 }
965
daniel@transgaming.com01868132010-08-24 19:21:17 +0000966 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000967 {
daniel@transgaming.com01868132010-08-24 19:21:17 +0000968 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
969 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +0000970 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
971 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +0000972 break;
973 default:
974 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +0000975 }
976
daniel@transgaming.com01868132010-08-24 19:21:17 +0000977 if (width == 0 || height == 0 || data == NULL)
978 {
979 return;
980 }
981
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000982 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com01868132010-08-24 19:21:17 +0000983
984 if (context)
985 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000986 if (level > context->getMaximumTextureLevel())
987 {
988 return error(GL_INVALID_VALUE);
989 }
990
gman@chromium.org50c526d2011-08-10 05:19:44 +0000991 switch (format) {
992 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
993 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
994 if (!context->supportsDXT1Textures())
995 {
996 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
997 }
998 break;
999 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1000 if (!context->supportsDXT3Textures())
1001 {
1002 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1003 }
1004 break;
1005 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1006 if (!context->supportsDXT5Textures())
1007 {
1008 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
1009 }
1010 break;
1011 default: UNREACHABLE();
daniel@transgaming.com01868132010-08-24 19:21:17 +00001012 }
1013
1014 if (imageSize != gl::ComputeCompressedSize(width, height, format))
1015 {
1016 return error(GL_INVALID_VALUE);
1017 }
1018
1019 if (xoffset % 4 != 0 || yoffset % 4 != 0)
1020 {
1021 return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
gman@chromium.org50c526d2011-08-10 05:19:44 +00001022 // does not exist unless DXT textures are supported.
daniel@transgaming.com01868132010-08-24 19:21:17 +00001023 }
1024
1025 if (target == GL_TEXTURE_2D)
1026 {
1027 gl::Texture2D *texture = context->getTexture2D();
1028
1029 if (!texture)
1030 {
1031 return error(GL_INVALID_OPERATION);
1032 }
1033
1034 if (!texture->isCompressed())
1035 {
1036 return error(GL_INVALID_OPERATION);
1037 }
1038
daniel@transgaming.comf1286442011-11-29 19:42:23 +00001039 if ((width % 4 != 0 && width != texture->getWidth(0)) ||
1040 (height % 4 != 0 && height != texture->getHeight(0)))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001041 {
1042 return error(GL_INVALID_OPERATION);
1043 }
1044
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00001045 if (xoffset + width > texture->getWidth(level) ||
1046 yoffset + height > texture->getHeight(level))
1047 {
1048 return error(GL_INVALID_VALUE);
1049 }
1050
daniel@transgaming.com01868132010-08-24 19:21:17 +00001051 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
1052 }
1053 else if (gl::IsCubemapTextureTarget(target))
1054 {
1055 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1056
1057 if (!texture)
1058 {
1059 return error(GL_INVALID_OPERATION);
1060 }
1061
1062 if (!texture->isCompressed())
1063 {
1064 return error(GL_INVALID_OPERATION);
1065 }
1066
daniel@transgaming.comf1286442011-11-29 19:42:23 +00001067 if ((width % 4 != 0 && width != texture->getWidth(0)) ||
1068 (height % 4 != 0 && height != texture->getHeight(0)))
daniel@transgaming.com01868132010-08-24 19:21:17 +00001069 {
1070 return error(GL_INVALID_OPERATION);
1071 }
1072
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00001073 if (xoffset + width > texture->getWidth(level) ||
1074 yoffset + height > texture->getHeight(level))
1075 {
1076 return error(GL_INVALID_VALUE);
1077 }
1078
daniel@transgaming.com01868132010-08-24 19:21:17 +00001079 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
1080 }
1081 else
1082 {
1083 UNREACHABLE();
1084 }
1085 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001086 }
1087 catch(std::bad_alloc&)
1088 {
1089 return error(GL_OUT_OF_MEMORY);
1090 }
1091}
1092
1093void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1094{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001095 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001096 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001097 target, level, internalformat, x, y, width, height, border);
1098
1099 try
1100 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00001101 if (!validImageSize(level, width, height))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001102 {
1103 return error(GL_INVALID_VALUE);
1104 }
1105
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001106 if (border != 0)
1107 {
1108 return error(GL_INVALID_VALUE);
1109 }
1110
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001111 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001112
1113 if (context)
1114 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00001115 if (level > context->getMaximumTextureLevel())
1116 {
1117 return error(GL_INVALID_VALUE);
1118 }
1119
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001120 switch (target)
1121 {
1122 case GL_TEXTURE_2D:
1123 if (width > (context->getMaximumTextureDimension() >> level) ||
1124 height > (context->getMaximumTextureDimension() >> level))
1125 {
1126 return error(GL_INVALID_VALUE);
1127 }
1128 break;
1129 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1130 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1131 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1132 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1133 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1134 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1135 if (width != height)
1136 {
1137 return error(GL_INVALID_VALUE);
1138 }
1139
1140 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1141 height > (context->getMaximumCubeTextureDimension() >> level))
1142 {
1143 return error(GL_INVALID_VALUE);
1144 }
1145 break;
1146 default:
1147 return error(GL_INVALID_ENUM);
1148 }
1149
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001150 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001151
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001152 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1153 {
1154 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1155 }
1156
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001157 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1158 {
1159 return error(GL_INVALID_OPERATION);
1160 }
1161
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001162 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001163 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001164
1165 // [OpenGL ES 2.0.24] table 3.9
1166 switch (internalformat)
1167 {
1168 case GL_ALPHA:
1169 if (colorbufferFormat != GL_ALPHA &&
1170 colorbufferFormat != GL_RGBA &&
1171 colorbufferFormat != GL_RGBA4 &&
1172 colorbufferFormat != GL_RGB5_A1 &&
1173 colorbufferFormat != GL_RGBA8_OES)
1174 {
1175 return error(GL_INVALID_OPERATION);
1176 }
1177 break;
1178 case GL_LUMINANCE:
1179 case GL_RGB:
1180 if (colorbufferFormat != GL_RGB &&
1181 colorbufferFormat != GL_RGB565 &&
1182 colorbufferFormat != GL_RGB8_OES &&
1183 colorbufferFormat != GL_RGBA &&
1184 colorbufferFormat != GL_RGBA4 &&
1185 colorbufferFormat != GL_RGB5_A1 &&
1186 colorbufferFormat != GL_RGBA8_OES)
1187 {
1188 return error(GL_INVALID_OPERATION);
1189 }
1190 break;
1191 case GL_LUMINANCE_ALPHA:
1192 case GL_RGBA:
1193 if (colorbufferFormat != GL_RGBA &&
1194 colorbufferFormat != GL_RGBA4 &&
1195 colorbufferFormat != GL_RGB5_A1 &&
1196 colorbufferFormat != GL_RGBA8_OES)
1197 {
1198 return error(GL_INVALID_OPERATION);
1199 }
1200 break;
1201 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1202 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001203 if (context->supportsDXT1Textures())
1204 {
1205 return error(GL_INVALID_OPERATION);
1206 }
1207 else
1208 {
1209 return error(GL_INVALID_ENUM);
1210 }
1211 break;
1212 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1213 if (context->supportsDXT3Textures())
1214 {
1215 return error(GL_INVALID_OPERATION);
1216 }
1217 else
1218 {
1219 return error(GL_INVALID_ENUM);
1220 }
1221 break;
1222 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1223 if (context->supportsDXT5Textures())
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001224 {
1225 return error(GL_INVALID_OPERATION);
1226 }
1227 else
1228 {
1229 return error(GL_INVALID_ENUM);
1230 }
1231 break;
1232 default:
1233 return error(GL_INVALID_ENUM);
1234 }
1235
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001236 if (target == GL_TEXTURE_2D)
1237 {
1238 gl::Texture2D *texture = context->getTexture2D();
1239
1240 if (!texture)
1241 {
1242 return error(GL_INVALID_OPERATION);
1243 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001244
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001245 if (texture->isImmutable())
1246 {
1247 return error(GL_INVALID_OPERATION);
1248 }
1249
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001250 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001251 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001252 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001253 {
1254 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1255
1256 if (!texture)
1257 {
1258 return error(GL_INVALID_OPERATION);
1259 }
1260
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00001261 if (texture->isImmutable())
1262 {
1263 return error(GL_INVALID_OPERATION);
1264 }
1265
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001266 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001267 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001268 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001269 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001270 }
1271 catch(std::bad_alloc&)
1272 {
1273 return error(GL_OUT_OF_MEMORY);
1274 }
1275}
1276
1277void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1278{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001279 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001280 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001281 target, level, xoffset, yoffset, x, y, width, height);
1282
1283 try
1284 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001285 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001286 {
1287 return error(GL_INVALID_ENUM);
1288 }
1289
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001290 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001291 {
1292 return error(GL_INVALID_VALUE);
1293 }
1294
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001295 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1296 {
1297 return error(GL_INVALID_VALUE);
1298 }
1299
1300 if (width == 0 || height == 0)
1301 {
1302 return;
1303 }
1304
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001305 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001306
1307 if (context)
1308 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001309 if (level > context->getMaximumTextureLevel())
1310 {
1311 return error(GL_INVALID_VALUE);
1312 }
1313
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001314 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001315
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001316 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1317 {
1318 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1319 }
1320
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001321 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1322 {
1323 return error(GL_INVALID_OPERATION);
1324 }
1325
daniel@transgaming.comd14558a2011-11-09 17:46:18 +00001326 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001327 GLenum colorbufferFormat = source->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001328 gl::Texture *texture = NULL;
1329
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001330 if (target == GL_TEXTURE_2D)
1331 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001332 texture = context->getTexture2D();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001333 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001334 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001335 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001336 texture = context->getTextureCubeMap();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001337 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001338 else UNREACHABLE();
1339
1340 if (!texture)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001341 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001342 return error(GL_INVALID_OPERATION);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001343 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001344
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00001345 if (xoffset + width > texture->getWidth(level) ||
1346 yoffset + height > texture->getHeight(level))
1347 {
1348 return error(GL_INVALID_VALUE);
1349 }
1350
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00001351 GLenum textureFormat = texture->getInternalFormat();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001352
1353 // [OpenGL ES 2.0.24] table 3.9
1354 switch (textureFormat)
1355 {
1356 case GL_ALPHA:
1357 if (colorbufferFormat != GL_ALPHA &&
1358 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_LUMINANCE:
1367 case GL_RGB:
1368 if (colorbufferFormat != GL_RGB &&
1369 colorbufferFormat != GL_RGB565 &&
1370 colorbufferFormat != GL_RGB8_OES &&
1371 colorbufferFormat != GL_RGBA &&
1372 colorbufferFormat != GL_RGBA4 &&
1373 colorbufferFormat != GL_RGB5_A1 &&
1374 colorbufferFormat != GL_RGBA8_OES)
1375 {
1376 return error(GL_INVALID_OPERATION);
1377 }
1378 break;
1379 case GL_LUMINANCE_ALPHA:
1380 case GL_RGBA:
1381 if (colorbufferFormat != GL_RGBA &&
1382 colorbufferFormat != GL_RGBA4 &&
1383 colorbufferFormat != GL_RGB5_A1 &&
1384 colorbufferFormat != GL_RGBA8_OES)
1385 {
1386 return error(GL_INVALID_OPERATION);
1387 }
1388 break;
1389 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1390 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00001391 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1392 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001393 return error(GL_INVALID_OPERATION);
1394 default:
1395 return error(GL_INVALID_OPERATION);
1396 }
1397
apatrick@chromium.orgb31f5322011-01-19 19:02:52 +00001398 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001399 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001400 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001401
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001402 catch(std::bad_alloc&)
1403 {
1404 return error(GL_OUT_OF_MEMORY);
1405 }
1406}
1407
1408GLuint __stdcall glCreateProgram(void)
1409{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001410 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001411
1412 try
1413 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001414 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001415
1416 if (context)
1417 {
1418 return context->createProgram();
1419 }
1420 }
1421 catch(std::bad_alloc&)
1422 {
1423 return error(GL_OUT_OF_MEMORY, 0);
1424 }
1425
1426 return 0;
1427}
1428
1429GLuint __stdcall glCreateShader(GLenum type)
1430{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001431 EVENT("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001432
1433 try
1434 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001435 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001436
1437 if (context)
1438 {
1439 switch (type)
1440 {
1441 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001442 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001443 return context->createShader(type);
1444 default:
1445 return error(GL_INVALID_ENUM, 0);
1446 }
1447 }
1448 }
1449 catch(std::bad_alloc&)
1450 {
1451 return error(GL_OUT_OF_MEMORY, 0);
1452 }
1453
1454 return 0;
1455}
1456
1457void __stdcall glCullFace(GLenum mode)
1458{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001459 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001460
1461 try
1462 {
1463 switch (mode)
1464 {
1465 case GL_FRONT:
1466 case GL_BACK:
1467 case GL_FRONT_AND_BACK:
1468 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001469 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001470
1471 if (context)
1472 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001473 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001474 }
1475 }
1476 break;
1477 default:
1478 return error(GL_INVALID_ENUM);
1479 }
1480 }
1481 catch(std::bad_alloc&)
1482 {
1483 return error(GL_OUT_OF_MEMORY);
1484 }
1485}
1486
1487void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1488{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001489 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001490
1491 try
1492 {
1493 if (n < 0)
1494 {
1495 return error(GL_INVALID_VALUE);
1496 }
1497
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001498 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001499
1500 if (context)
1501 {
1502 for (int i = 0; i < n; i++)
1503 {
1504 context->deleteBuffer(buffers[i]);
1505 }
1506 }
1507 }
1508 catch(std::bad_alloc&)
1509 {
1510 return error(GL_OUT_OF_MEMORY);
1511 }
1512}
1513
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001514void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1515{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001516 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001517
1518 try
1519 {
1520 if (n < 0)
1521 {
1522 return error(GL_INVALID_VALUE);
1523 }
1524
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001525 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001526
1527 if (context)
1528 {
1529 for (int i = 0; i < n; i++)
1530 {
1531 context->deleteFence(fences[i]);
1532 }
1533 }
1534 }
1535 catch(std::bad_alloc&)
1536 {
1537 return error(GL_OUT_OF_MEMORY);
1538 }
1539}
1540
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001541void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1542{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001543 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001544
1545 try
1546 {
1547 if (n < 0)
1548 {
1549 return error(GL_INVALID_VALUE);
1550 }
1551
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001552 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001553
1554 if (context)
1555 {
1556 for (int i = 0; i < n; i++)
1557 {
1558 if (framebuffers[i] != 0)
1559 {
1560 context->deleteFramebuffer(framebuffers[i]);
1561 }
1562 }
1563 }
1564 }
1565 catch(std::bad_alloc&)
1566 {
1567 return error(GL_OUT_OF_MEMORY);
1568 }
1569}
1570
1571void __stdcall glDeleteProgram(GLuint program)
1572{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001573 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001574
1575 try
1576 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001577 if (program == 0)
1578 {
1579 return;
1580 }
1581
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001582 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001583
1584 if (context)
1585 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001586 if (!context->getProgram(program))
1587 {
1588 if(context->getShader(program))
1589 {
1590 return error(GL_INVALID_OPERATION);
1591 }
1592 else
1593 {
1594 return error(GL_INVALID_VALUE);
1595 }
1596 }
1597
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001598 context->deleteProgram(program);
1599 }
1600 }
1601 catch(std::bad_alloc&)
1602 {
1603 return error(GL_OUT_OF_MEMORY);
1604 }
1605}
1606
1607void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1608{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001609 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001610
1611 try
1612 {
1613 if (n < 0)
1614 {
1615 return error(GL_INVALID_VALUE);
1616 }
1617
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001618 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001619
1620 if (context)
1621 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001622 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001623 {
1624 context->deleteRenderbuffer(renderbuffers[i]);
1625 }
1626 }
1627 }
1628 catch(std::bad_alloc&)
1629 {
1630 return error(GL_OUT_OF_MEMORY);
1631 }
1632}
1633
1634void __stdcall glDeleteShader(GLuint shader)
1635{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001636 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001637
1638 try
1639 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001640 if (shader == 0)
1641 {
1642 return;
1643 }
1644
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001645 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001646
1647 if (context)
1648 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001649 if (!context->getShader(shader))
1650 {
1651 if(context->getProgram(shader))
1652 {
1653 return error(GL_INVALID_OPERATION);
1654 }
1655 else
1656 {
1657 return error(GL_INVALID_VALUE);
1658 }
1659 }
1660
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001661 context->deleteShader(shader);
1662 }
1663 }
1664 catch(std::bad_alloc&)
1665 {
1666 return error(GL_OUT_OF_MEMORY);
1667 }
1668}
1669
1670void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1671{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001672 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001673
1674 try
1675 {
1676 if (n < 0)
1677 {
1678 return error(GL_INVALID_VALUE);
1679 }
1680
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001681 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001682
1683 if (context)
1684 {
1685 for (int i = 0; i < n; i++)
1686 {
1687 if (textures[i] != 0)
1688 {
1689 context->deleteTexture(textures[i]);
1690 }
1691 }
1692 }
1693 }
1694 catch(std::bad_alloc&)
1695 {
1696 return error(GL_OUT_OF_MEMORY);
1697 }
1698}
1699
1700void __stdcall glDepthFunc(GLenum func)
1701{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001702 EVENT("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001703
1704 try
1705 {
1706 switch (func)
1707 {
1708 case GL_NEVER:
1709 case GL_ALWAYS:
1710 case GL_LESS:
1711 case GL_LEQUAL:
1712 case GL_EQUAL:
1713 case GL_GREATER:
1714 case GL_GEQUAL:
1715 case GL_NOTEQUAL:
1716 break;
1717 default:
1718 return error(GL_INVALID_ENUM);
1719 }
1720
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001721 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001722
1723 if (context)
1724 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001725 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001726 }
1727 }
1728 catch(std::bad_alloc&)
1729 {
1730 return error(GL_OUT_OF_MEMORY);
1731 }
1732}
1733
1734void __stdcall glDepthMask(GLboolean flag)
1735{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001736 EVENT("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001737
1738 try
1739 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001740 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001741
1742 if (context)
1743 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001744 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001745 }
1746 }
1747 catch(std::bad_alloc&)
1748 {
1749 return error(GL_OUT_OF_MEMORY);
1750 }
1751}
1752
1753void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1754{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001755 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001756
1757 try
1758 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001759 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001760
1761 if (context)
1762 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001763 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001764 }
1765 }
1766 catch(std::bad_alloc&)
1767 {
1768 return error(GL_OUT_OF_MEMORY);
1769 }
1770}
1771
1772void __stdcall glDetachShader(GLuint program, GLuint shader)
1773{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001774 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001775
1776 try
1777 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001778 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001779
1780 if (context)
1781 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001782
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001783 gl::Program *programObject = context->getProgram(program);
1784 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001785
1786 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001787 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001788 gl::Shader *shaderByProgramHandle;
1789 shaderByProgramHandle = context->getShader(program);
1790 if (!shaderByProgramHandle)
1791 {
1792 return error(GL_INVALID_VALUE);
1793 }
1794 else
1795 {
1796 return error(GL_INVALID_OPERATION);
1797 }
1798 }
1799
1800 if (!shaderObject)
1801 {
1802 gl::Program *programByShaderHandle = context->getProgram(shader);
1803 if (!programByShaderHandle)
1804 {
1805 return error(GL_INVALID_VALUE);
1806 }
1807 else
1808 {
1809 return error(GL_INVALID_OPERATION);
1810 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001811 }
1812
1813 if (!programObject->detachShader(shaderObject))
1814 {
1815 return error(GL_INVALID_OPERATION);
1816 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001817 }
1818 }
1819 catch(std::bad_alloc&)
1820 {
1821 return error(GL_OUT_OF_MEMORY);
1822 }
1823}
1824
1825void __stdcall glDisable(GLenum cap)
1826{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001827 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001828
1829 try
1830 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001831 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001832
1833 if (context)
1834 {
1835 switch (cap)
1836 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001837 case GL_CULL_FACE: context->setCullFace(false); break;
1838 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1839 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1840 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1841 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1842 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1843 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1844 case GL_BLEND: context->setBlend(false); break;
1845 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001846 default:
1847 return error(GL_INVALID_ENUM);
1848 }
1849 }
1850 }
1851 catch(std::bad_alloc&)
1852 {
1853 return error(GL_OUT_OF_MEMORY);
1854 }
1855}
1856
1857void __stdcall glDisableVertexAttribArray(GLuint index)
1858{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001859 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001860
1861 try
1862 {
1863 if (index >= gl::MAX_VERTEX_ATTRIBS)
1864 {
1865 return error(GL_INVALID_VALUE);
1866 }
1867
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001868 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001869
1870 if (context)
1871 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001872 context->setEnableVertexAttribArray(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001873 }
1874 }
1875 catch(std::bad_alloc&)
1876 {
1877 return error(GL_OUT_OF_MEMORY);
1878 }
1879}
1880
1881void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1882{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001883 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001884
1885 try
1886 {
1887 if (count < 0 || first < 0)
1888 {
1889 return error(GL_INVALID_VALUE);
1890 }
1891
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001892 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001893
1894 if (context)
1895 {
1896 context->drawArrays(mode, first, count);
1897 }
1898 }
1899 catch(std::bad_alloc&)
1900 {
1901 return error(GL_OUT_OF_MEMORY);
1902 }
1903}
1904
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001905void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001906{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001907 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 +00001908 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001909
1910 try
1911 {
1912 if (count < 0)
1913 {
1914 return error(GL_INVALID_VALUE);
1915 }
1916
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001917 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001918
1919 if (context)
1920 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001921 switch (type)
1922 {
1923 case GL_UNSIGNED_BYTE:
1924 case GL_UNSIGNED_SHORT:
1925 break;
1926 case GL_UNSIGNED_INT:
1927 if (!context->supports32bitIndices())
1928 {
1929 return error(GL_INVALID_ENUM);
1930 }
1931 break;
1932 default:
1933 return error(GL_INVALID_ENUM);
1934 }
1935
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001936 context->drawElements(mode, count, type, indices);
1937 }
1938 }
1939 catch(std::bad_alloc&)
1940 {
1941 return error(GL_OUT_OF_MEMORY);
1942 }
1943}
1944
1945void __stdcall glEnable(GLenum cap)
1946{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001947 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001948
1949 try
1950 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001951 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001952
1953 if (context)
1954 {
1955 switch (cap)
1956 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001957 case GL_CULL_FACE: context->setCullFace(true); break;
1958 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1959 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1960 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1961 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1962 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1963 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1964 case GL_BLEND: context->setBlend(true); break;
1965 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001966 default:
1967 return error(GL_INVALID_ENUM);
1968 }
1969 }
1970 }
1971 catch(std::bad_alloc&)
1972 {
1973 return error(GL_OUT_OF_MEMORY);
1974 }
1975}
1976
1977void __stdcall glEnableVertexAttribArray(GLuint index)
1978{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00001979 EVENT("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001980
1981 try
1982 {
1983 if (index >= gl::MAX_VERTEX_ATTRIBS)
1984 {
1985 return error(GL_INVALID_VALUE);
1986 }
1987
daniel@transgaming.com9d788502011-11-09 17:46:55 +00001988 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001989
1990 if (context)
1991 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001992 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001993 }
1994 }
1995 catch(std::bad_alloc&)
1996 {
1997 return error(GL_OUT_OF_MEMORY);
1998 }
1999}
2000
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002001void __stdcall glFinishFenceNV(GLuint fence)
2002{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002003 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002004
2005 try
2006 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002007 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002008
2009 if (context)
2010 {
2011 gl::Fence* fenceObject = context->getFence(fence);
2012
2013 if (fenceObject == NULL)
2014 {
2015 return error(GL_INVALID_OPERATION);
2016 }
2017
2018 fenceObject->finishFence();
2019 }
2020 }
2021 catch(std::bad_alloc&)
2022 {
2023 return error(GL_OUT_OF_MEMORY);
2024 }
2025}
2026
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002027void __stdcall glFinish(void)
2028{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002029 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002030
2031 try
2032 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002033 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002034
2035 if (context)
2036 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002037 context->sync(true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002038 }
2039 }
2040 catch(std::bad_alloc&)
2041 {
2042 return error(GL_OUT_OF_MEMORY);
2043 }
2044}
2045
2046void __stdcall glFlush(void)
2047{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002048 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002049
2050 try
2051 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002052 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002053
2054 if (context)
2055 {
daniel@transgaming.com0d86aa72011-10-26 02:35:10 +00002056 context->sync(false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002057 }
2058 }
2059 catch(std::bad_alloc&)
2060 {
2061 return error(GL_OUT_OF_MEMORY);
2062 }
2063}
2064
2065void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
2066{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002067 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002068 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002069
2070 try
2071 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002072 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002073 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002074 {
2075 return error(GL_INVALID_ENUM);
2076 }
2077
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002078 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002079
2080 if (context)
2081 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002082 gl::Framebuffer *framebuffer = NULL;
2083 GLuint framebufferHandle = 0;
2084 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2085 {
2086 framebuffer = context->getReadFramebuffer();
2087 framebufferHandle = context->getReadFramebufferHandle();
2088 }
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002089 else
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002090 {
2091 framebuffer = context->getDrawFramebuffer();
2092 framebufferHandle = context->getDrawFramebufferHandle();
2093 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002094
daniel@transgaming.com2fa45512011-10-04 18:43:18 +00002095 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002096 {
2097 return error(GL_INVALID_OPERATION);
2098 }
2099
2100 switch (attachment)
2101 {
2102 case GL_COLOR_ATTACHMENT0:
2103 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
2104 break;
2105 case GL_DEPTH_ATTACHMENT:
2106 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
2107 break;
2108 case GL_STENCIL_ATTACHMENT:
2109 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
2110 break;
2111 default:
2112 return error(GL_INVALID_ENUM);
2113 }
2114 }
2115 }
2116 catch(std::bad_alloc&)
2117 {
2118 return error(GL_OUT_OF_MEMORY);
2119 }
2120}
2121
2122void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
2123{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002124 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002125 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002126
2127 try
2128 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002129 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002130 {
2131 return error(GL_INVALID_ENUM);
2132 }
2133
2134 switch (attachment)
2135 {
2136 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002137 case GL_DEPTH_ATTACHMENT:
2138 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002139 break;
2140 default:
2141 return error(GL_INVALID_ENUM);
2142 }
2143
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002144 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002145
2146 if (context)
2147 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002148 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002149 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002150 textarget = GL_NONE;
2151 }
2152 else
2153 {
2154 gl::Texture *tex = context->getTexture(texture);
2155
2156 if (tex == NULL)
2157 {
2158 return error(GL_INVALID_OPERATION);
2159 }
2160
daniel@transgaming.com01868132010-08-24 19:21:17 +00002161 if (tex->isCompressed())
2162 {
2163 return error(GL_INVALID_OPERATION);
2164 }
2165
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002166 switch (textarget)
2167 {
2168 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002169 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002170 {
2171 return error(GL_INVALID_OPERATION);
2172 }
2173 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002174
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002175 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002176 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002177 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002178 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002179 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002180 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002181 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2182 {
2183 return error(GL_INVALID_OPERATION);
2184 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002185 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002186
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002187 default:
2188 return error(GL_INVALID_ENUM);
2189 }
2190
2191 if (level != 0)
2192 {
2193 return error(GL_INVALID_VALUE);
2194 }
2195 }
2196
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002197 gl::Framebuffer *framebuffer = NULL;
2198 GLuint framebufferHandle = 0;
2199 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2200 {
2201 framebuffer = context->getReadFramebuffer();
2202 framebufferHandle = context->getReadFramebufferHandle();
2203 }
2204 else
2205 {
2206 framebuffer = context->getDrawFramebuffer();
2207 framebufferHandle = context->getDrawFramebufferHandle();
2208 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002209
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002210 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002211 {
2212 return error(GL_INVALID_OPERATION);
2213 }
2214
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002215 switch (attachment)
2216 {
2217 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2218 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2219 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2220 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002221 }
2222 }
2223 catch(std::bad_alloc&)
2224 {
2225 return error(GL_OUT_OF_MEMORY);
2226 }
2227}
2228
2229void __stdcall glFrontFace(GLenum mode)
2230{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002231 EVENT("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002232
2233 try
2234 {
2235 switch (mode)
2236 {
2237 case GL_CW:
2238 case GL_CCW:
2239 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002240 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002241
2242 if (context)
2243 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002244 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002245 }
2246 }
2247 break;
2248 default:
2249 return error(GL_INVALID_ENUM);
2250 }
2251 }
2252 catch(std::bad_alloc&)
2253 {
2254 return error(GL_OUT_OF_MEMORY);
2255 }
2256}
2257
2258void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2259{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002260 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002261
2262 try
2263 {
2264 if (n < 0)
2265 {
2266 return error(GL_INVALID_VALUE);
2267 }
2268
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002269 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002270
2271 if (context)
2272 {
2273 for (int i = 0; i < n; i++)
2274 {
2275 buffers[i] = context->createBuffer();
2276 }
2277 }
2278 }
2279 catch(std::bad_alloc&)
2280 {
2281 return error(GL_OUT_OF_MEMORY);
2282 }
2283}
2284
2285void __stdcall glGenerateMipmap(GLenum target)
2286{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002287 EVENT("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002288
2289 try
2290 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002291 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002292
2293 if (context)
2294 {
2295 gl::Texture *texture;
2296
2297 switch (target)
2298 {
2299 case GL_TEXTURE_2D:
2300 texture = context->getTexture2D();
2301 break;
2302
2303 case GL_TEXTURE_CUBE_MAP:
2304 texture = context->getTextureCubeMap();
2305 break;
2306
2307 default:
2308 return error(GL_INVALID_ENUM);
2309 }
2310
daniel@transgaming.com01868132010-08-24 19:21:17 +00002311 if (texture->isCompressed())
2312 {
2313 return error(GL_INVALID_OPERATION);
2314 }
2315
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002316 texture->generateMipmaps();
2317 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002318 }
2319 catch(std::bad_alloc&)
2320 {
2321 return error(GL_OUT_OF_MEMORY);
2322 }
2323}
2324
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002325void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2326{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002327 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002328
2329 try
2330 {
2331 if (n < 0)
2332 {
2333 return error(GL_INVALID_VALUE);
2334 }
2335
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002336 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002337
2338 if (context)
2339 {
2340 for (int i = 0; i < n; i++)
2341 {
2342 fences[i] = context->createFence();
2343 }
2344 }
2345 }
2346 catch(std::bad_alloc&)
2347 {
2348 return error(GL_OUT_OF_MEMORY);
2349 }
2350}
2351
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002352void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2353{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002354 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002355
2356 try
2357 {
2358 if (n < 0)
2359 {
2360 return error(GL_INVALID_VALUE);
2361 }
2362
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002363 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002364
2365 if (context)
2366 {
2367 for (int i = 0; i < n; i++)
2368 {
2369 framebuffers[i] = context->createFramebuffer();
2370 }
2371 }
2372 }
2373 catch(std::bad_alloc&)
2374 {
2375 return error(GL_OUT_OF_MEMORY);
2376 }
2377}
2378
2379void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2380{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002381 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002382
2383 try
2384 {
2385 if (n < 0)
2386 {
2387 return error(GL_INVALID_VALUE);
2388 }
2389
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002390 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002391
2392 if (context)
2393 {
2394 for (int i = 0; i < n; i++)
2395 {
2396 renderbuffers[i] = context->createRenderbuffer();
2397 }
2398 }
2399 }
2400 catch(std::bad_alloc&)
2401 {
2402 return error(GL_OUT_OF_MEMORY);
2403 }
2404}
2405
2406void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2407{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002408 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002409
2410 try
2411 {
2412 if (n < 0)
2413 {
2414 return error(GL_INVALID_VALUE);
2415 }
2416
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002417 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002418
2419 if (context)
2420 {
2421 for (int i = 0; i < n; i++)
2422 {
2423 textures[i] = context->createTexture();
2424 }
2425 }
2426 }
2427 catch(std::bad_alloc&)
2428 {
2429 return error(GL_OUT_OF_MEMORY);
2430 }
2431}
2432
daniel@transgaming.com85423182010-04-22 13:35:27 +00002433void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002434{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002435 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
daniel@transgaming.com85423182010-04-22 13:35:27 +00002436 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002437 program, index, bufsize, length, size, type, name);
2438
2439 try
2440 {
2441 if (bufsize < 0)
2442 {
2443 return error(GL_INVALID_VALUE);
2444 }
2445
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002446 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com85423182010-04-22 13:35:27 +00002447
2448 if (context)
2449 {
2450 gl::Program *programObject = context->getProgram(program);
2451
2452 if (!programObject)
2453 {
2454 if (context->getShader(program))
2455 {
2456 return error(GL_INVALID_OPERATION);
2457 }
2458 else
2459 {
2460 return error(GL_INVALID_VALUE);
2461 }
2462 }
2463
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002464 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002465 {
2466 return error(GL_INVALID_VALUE);
2467 }
2468
2469 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2470 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002471 }
2472 catch(std::bad_alloc&)
2473 {
2474 return error(GL_OUT_OF_MEMORY);
2475 }
2476}
2477
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002478void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002479{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002480 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002481 "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 +00002482 program, index, bufsize, length, size, type, name);
2483
2484 try
2485 {
2486 if (bufsize < 0)
2487 {
2488 return error(GL_INVALID_VALUE);
2489 }
2490
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002491 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002492
2493 if (context)
2494 {
2495 gl::Program *programObject = context->getProgram(program);
2496
2497 if (!programObject)
2498 {
2499 if (context->getShader(program))
2500 {
2501 return error(GL_INVALID_OPERATION);
2502 }
2503 else
2504 {
2505 return error(GL_INVALID_VALUE);
2506 }
2507 }
2508
2509 if (index >= (GLuint)programObject->getActiveUniformCount())
2510 {
2511 return error(GL_INVALID_VALUE);
2512 }
2513
2514 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2515 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002516 }
2517 catch(std::bad_alloc&)
2518 {
2519 return error(GL_OUT_OF_MEMORY);
2520 }
2521}
2522
2523void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2524{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002525 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 +00002526 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002527
2528 try
2529 {
2530 if (maxcount < 0)
2531 {
2532 return error(GL_INVALID_VALUE);
2533 }
2534
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002535 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002536
2537 if (context)
2538 {
2539 gl::Program *programObject = context->getProgram(program);
2540
2541 if (!programObject)
2542 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002543 if (context->getShader(program))
2544 {
2545 return error(GL_INVALID_OPERATION);
2546 }
2547 else
2548 {
2549 return error(GL_INVALID_VALUE);
2550 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002551 }
2552
2553 return programObject->getAttachedShaders(maxcount, count, shaders);
2554 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002555 }
2556 catch(std::bad_alloc&)
2557 {
2558 return error(GL_OUT_OF_MEMORY);
2559 }
2560}
2561
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002562int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002563{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002564 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002565
2566 try
2567 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002568 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002569
2570 if (context)
2571 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002572
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002573 gl::Program *programObject = context->getProgram(program);
2574
2575 if (!programObject)
2576 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002577 if (context->getShader(program))
2578 {
2579 return error(GL_INVALID_OPERATION, -1);
2580 }
2581 else
2582 {
2583 return error(GL_INVALID_VALUE, -1);
2584 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002585 }
2586
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002587 if (!programObject->isLinked())
2588 {
2589 return error(GL_INVALID_OPERATION, -1);
2590 }
2591
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002592 return programObject->getAttributeLocation(name);
2593 }
2594 }
2595 catch(std::bad_alloc&)
2596 {
2597 return error(GL_OUT_OF_MEMORY, -1);
2598 }
2599
2600 return -1;
2601}
2602
2603void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2604{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002605 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002606
2607 try
2608 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002609 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002610
2611 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002612 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002613 if (!(context->getBooleanv(pname, params)))
2614 {
2615 GLenum nativeType;
2616 unsigned int numParams = 0;
2617 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2618 return error(GL_INVALID_ENUM);
2619
2620 if (numParams == 0)
2621 return; // it is known that the pname is valid, but there are no parameters to return
2622
2623 if (nativeType == GL_FLOAT)
2624 {
2625 GLfloat *floatParams = NULL;
2626 floatParams = new GLfloat[numParams];
2627
2628 context->getFloatv(pname, floatParams);
2629
2630 for (unsigned int i = 0; i < numParams; ++i)
2631 {
2632 if (floatParams[i] == 0.0f)
2633 params[i] = GL_FALSE;
2634 else
2635 params[i] = GL_TRUE;
2636 }
2637
2638 delete [] floatParams;
2639 }
2640 else if (nativeType == GL_INT)
2641 {
2642 GLint *intParams = NULL;
2643 intParams = new GLint[numParams];
2644
2645 context->getIntegerv(pname, intParams);
2646
2647 for (unsigned int i = 0; i < numParams; ++i)
2648 {
2649 if (intParams[i] == 0)
2650 params[i] = GL_FALSE;
2651 else
2652 params[i] = GL_TRUE;
2653 }
2654
2655 delete [] intParams;
2656 }
2657 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002658 }
2659 }
2660 catch(std::bad_alloc&)
2661 {
2662 return error(GL_OUT_OF_MEMORY);
2663 }
2664}
2665
2666void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2667{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002668 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 +00002669
2670 try
2671 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002672 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002673
2674 if (context)
2675 {
2676 gl::Buffer *buffer;
2677
2678 switch (target)
2679 {
2680 case GL_ARRAY_BUFFER:
2681 buffer = context->getArrayBuffer();
2682 break;
2683 case GL_ELEMENT_ARRAY_BUFFER:
2684 buffer = context->getElementArrayBuffer();
2685 break;
2686 default: return error(GL_INVALID_ENUM);
2687 }
2688
2689 if (!buffer)
2690 {
2691 // A null buffer means that "0" is bound to the requested buffer target
2692 return error(GL_INVALID_OPERATION);
2693 }
2694
2695 switch (pname)
2696 {
2697 case GL_BUFFER_USAGE:
2698 *params = buffer->usage();
2699 break;
2700 case GL_BUFFER_SIZE:
2701 *params = buffer->size();
2702 break;
2703 default: return error(GL_INVALID_ENUM);
2704 }
2705 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002706 }
2707 catch(std::bad_alloc&)
2708 {
2709 return error(GL_OUT_OF_MEMORY);
2710 }
2711}
2712
2713GLenum __stdcall glGetError(void)
2714{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002715 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002716
2717 gl::Context *context = gl::getContext();
2718
2719 if (context)
2720 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002721 if (context->isContextLost())
2722 return GL_OUT_OF_MEMORY;
2723 else
2724 return context->getError();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002725 }
2726
2727 return GL_NO_ERROR;
2728}
2729
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002730void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2731{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002732 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002733
2734 try
2735 {
2736
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002737 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002738
2739 if (context)
2740 {
2741 gl::Fence *fenceObject = context->getFence(fence);
2742
2743 if (fenceObject == NULL)
2744 {
2745 return error(GL_INVALID_OPERATION);
2746 }
2747
2748 fenceObject->getFenceiv(pname, params);
2749 }
2750 }
2751 catch(std::bad_alloc&)
2752 {
2753 return error(GL_OUT_OF_MEMORY);
2754 }
2755}
2756
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002757void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2758{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002759 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002760
2761 try
2762 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002763 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002764
2765 if (context)
2766 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002767 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002768 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002769 GLenum nativeType;
2770 unsigned int numParams = 0;
2771 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2772 return error(GL_INVALID_ENUM);
2773
2774 if (numParams == 0)
2775 return; // it is known that the pname is valid, but that there are no parameters to return.
2776
2777 if (nativeType == GL_BOOL)
2778 {
2779 GLboolean *boolParams = NULL;
2780 boolParams = new GLboolean[numParams];
2781
2782 context->getBooleanv(pname, boolParams);
2783
2784 for (unsigned int i = 0; i < numParams; ++i)
2785 {
2786 if (boolParams[i] == GL_FALSE)
2787 params[i] = 0.0f;
2788 else
2789 params[i] = 1.0f;
2790 }
2791
2792 delete [] boolParams;
2793 }
2794 else if (nativeType == GL_INT)
2795 {
2796 GLint *intParams = NULL;
2797 intParams = new GLint[numParams];
2798
2799 context->getIntegerv(pname, intParams);
2800
2801 for (unsigned int i = 0; i < numParams; ++i)
2802 {
2803 params[i] = (GLfloat)intParams[i];
2804 }
2805
2806 delete [] intParams;
2807 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002808 }
2809 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002810 }
2811 catch(std::bad_alloc&)
2812 {
2813 return error(GL_OUT_OF_MEMORY);
2814 }
2815}
2816
2817void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2818{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002819 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 +00002820 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002821
2822 try
2823 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002824 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002825
2826 if (context)
2827 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002828 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002829 {
2830 return error(GL_INVALID_ENUM);
2831 }
2832
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002833 gl::Framebuffer *framebuffer = NULL;
2834 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2835 {
2836 if(context->getReadFramebufferHandle() == 0)
2837 {
2838 return error(GL_INVALID_OPERATION);
2839 }
2840
2841 framebuffer = context->getReadFramebuffer();
2842 }
2843 else
2844 {
2845 if (context->getDrawFramebufferHandle() == 0)
2846 {
2847 return error(GL_INVALID_OPERATION);
2848 }
2849
2850 framebuffer = context->getDrawFramebuffer();
2851 }
2852
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002853 GLenum attachmentType;
2854 GLuint attachmentHandle;
2855 switch (attachment)
2856 {
2857 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002858 attachmentType = framebuffer->getColorbufferType();
2859 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002860 break;
2861 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002862 attachmentType = framebuffer->getDepthbufferType();
2863 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002864 break;
2865 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002866 attachmentType = framebuffer->getStencilbufferType();
2867 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002868 break;
2869 default: return error(GL_INVALID_ENUM);
2870 }
2871
2872 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002873 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002874 {
2875 attachmentObjectType = attachmentType;
2876 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002877 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002878 {
2879 attachmentObjectType = GL_TEXTURE;
2880 }
2881 else UNREACHABLE();
2882
2883 switch (pname)
2884 {
2885 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2886 *params = attachmentObjectType;
2887 break;
2888 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2889 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2890 {
2891 *params = attachmentHandle;
2892 }
2893 else
2894 {
2895 return error(GL_INVALID_ENUM);
2896 }
2897 break;
2898 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2899 if (attachmentObjectType == GL_TEXTURE)
2900 {
2901 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2902 }
2903 else
2904 {
2905 return error(GL_INVALID_ENUM);
2906 }
2907 break;
2908 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2909 if (attachmentObjectType == GL_TEXTURE)
2910 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002911 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002912 {
2913 *params = attachmentType;
2914 }
2915 else
2916 {
2917 *params = 0;
2918 }
2919 }
2920 else
2921 {
2922 return error(GL_INVALID_ENUM);
2923 }
2924 break;
2925 default:
2926 return error(GL_INVALID_ENUM);
2927 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002928 }
2929 }
2930 catch(std::bad_alloc&)
2931 {
2932 return error(GL_OUT_OF_MEMORY);
2933 }
2934}
2935
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00002936GLenum __stdcall glGetGraphicsResetStatusEXT(void)
2937{
2938 EVENT("()");
2939
2940 try
2941 {
2942 gl::Context *context = gl::getContext();
2943
2944 if (context)
2945 {
2946 return context->getResetStatus();
2947 }
2948
2949 return GL_NO_ERROR;
2950 }
2951 catch(std::bad_alloc&)
2952 {
2953 return GL_OUT_OF_MEMORY;
2954 }
2955}
2956
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002957void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2958{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00002959 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002960
2961 try
2962 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00002963 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002964
2965 if (context)
2966 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002967 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002968 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002969 GLenum nativeType;
2970 unsigned int numParams = 0;
2971 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2972 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002973
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002974 if (numParams == 0)
2975 return; // it is known that pname is valid, but there are no parameters to return
2976
2977 if (nativeType == GL_BOOL)
2978 {
2979 GLboolean *boolParams = NULL;
2980 boolParams = new GLboolean[numParams];
2981
2982 context->getBooleanv(pname, boolParams);
2983
2984 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002985 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002986 if (boolParams[i] == GL_FALSE)
2987 params[i] = 0;
2988 else
2989 params[i] = 1;
2990 }
2991
2992 delete [] boolParams;
2993 }
2994 else if (nativeType == GL_FLOAT)
2995 {
2996 GLfloat *floatParams = NULL;
2997 floatParams = new GLfloat[numParams];
2998
2999 context->getFloatv(pname, floatParams);
3000
3001 for (unsigned int i = 0; i < numParams; ++i)
3002 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00003003 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 +00003004 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003005 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003006 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003007 else
3008 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 +00003009 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003010
daniel@transgaming.com777f2672010-04-07 03:25:16 +00003011 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003012 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003013 }
3014 }
3015 }
3016 catch(std::bad_alloc&)
3017 {
3018 return error(GL_OUT_OF_MEMORY);
3019 }
3020}
3021
3022void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
3023{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003024 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003025
3026 try
3027 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003028 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003029
3030 if (context)
3031 {
3032 gl::Program *programObject = context->getProgram(program);
3033
3034 if (!programObject)
3035 {
3036 return error(GL_INVALID_VALUE);
3037 }
3038
3039 switch (pname)
3040 {
3041 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003042 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003043 return;
3044 case GL_LINK_STATUS:
3045 *params = programObject->isLinked();
3046 return;
3047 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00003048 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003049 return;
3050 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003051 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003052 return;
3053 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003054 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003055 return;
3056 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003057 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003058 return;
3059 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00003060 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003061 return;
3062 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003063 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003064 return;
3065 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00003066 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003067 return;
3068 default:
3069 return error(GL_INVALID_ENUM);
3070 }
3071 }
3072 }
3073 catch(std::bad_alloc&)
3074 {
3075 return error(GL_OUT_OF_MEMORY);
3076 }
3077}
3078
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003079void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003080{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003081 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 +00003082 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003083
3084 try
3085 {
3086 if (bufsize < 0)
3087 {
3088 return error(GL_INVALID_VALUE);
3089 }
3090
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003091 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003092
3093 if (context)
3094 {
3095 gl::Program *programObject = context->getProgram(program);
3096
3097 if (!programObject)
3098 {
3099 return error(GL_INVALID_VALUE);
3100 }
3101
3102 programObject->getInfoLog(bufsize, length, infolog);
3103 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003104 }
3105 catch(std::bad_alloc&)
3106 {
3107 return error(GL_OUT_OF_MEMORY);
3108 }
3109}
3110
3111void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3112{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003113 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 +00003114
3115 try
3116 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003117 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003118
3119 if (context)
3120 {
3121 if (target != GL_RENDERBUFFER)
3122 {
3123 return error(GL_INVALID_ENUM);
3124 }
3125
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003126 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003127 {
3128 return error(GL_INVALID_OPERATION);
3129 }
3130
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003131 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003132
3133 switch (pname)
3134 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003135 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
3136 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
3137 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
3138 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
3139 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
3140 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
3141 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
3142 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
3143 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003144 case GL_RENDERBUFFER_SAMPLES_ANGLE:
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003145 if (context->getMaxSupportedSamples() != 0)
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003146 {
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00003147 *params = renderbuffer->getSamples();
3148 }
3149 else
3150 {
3151 return error(GL_INVALID_ENUM);
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003152 }
3153 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003154 default:
3155 return error(GL_INVALID_ENUM);
3156 }
3157 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003158 }
3159 catch(std::bad_alloc&)
3160 {
3161 return error(GL_OUT_OF_MEMORY);
3162 }
3163}
3164
3165void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3166{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003167 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003168
3169 try
3170 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003171 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003172
3173 if (context)
3174 {
3175 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003176
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003177 if (!shaderObject)
3178 {
3179 return error(GL_INVALID_VALUE);
3180 }
3181
3182 switch (pname)
3183 {
3184 case GL_SHADER_TYPE:
3185 *params = shaderObject->getType();
3186 return;
3187 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003188 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003189 return;
3190 case GL_COMPILE_STATUS:
3191 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3192 return;
3193 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003194 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003195 return;
3196 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003197 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003198 return;
zmo@google.coma574f782011-10-03 21:45:23 +00003199 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
3200 *params = shaderObject->getTranslatedSourceLength();
3201 return;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003202 default:
3203 return error(GL_INVALID_ENUM);
3204 }
3205 }
3206 }
3207 catch(std::bad_alloc&)
3208 {
3209 return error(GL_OUT_OF_MEMORY);
3210 }
3211}
3212
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003213void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003214{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003215 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 +00003216 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003217
3218 try
3219 {
3220 if (bufsize < 0)
3221 {
3222 return error(GL_INVALID_VALUE);
3223 }
3224
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003225 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003226
3227 if (context)
3228 {
3229 gl::Shader *shaderObject = context->getShader(shader);
3230
3231 if (!shaderObject)
3232 {
3233 return error(GL_INVALID_VALUE);
3234 }
3235
3236 shaderObject->getInfoLog(bufsize, length, infolog);
3237 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003238 }
3239 catch(std::bad_alloc&)
3240 {
3241 return error(GL_OUT_OF_MEMORY);
3242 }
3243}
3244
3245void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3246{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003247 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 +00003248 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003249
3250 try
3251 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003252 switch (shadertype)
3253 {
3254 case GL_VERTEX_SHADER:
3255 case GL_FRAGMENT_SHADER:
3256 break;
3257 default:
3258 return error(GL_INVALID_ENUM);
3259 }
3260
3261 switch (precisiontype)
3262 {
3263 case GL_LOW_FLOAT:
3264 case GL_MEDIUM_FLOAT:
3265 case GL_HIGH_FLOAT:
3266 // Assume IEEE 754 precision
3267 range[0] = 127;
3268 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003269 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003270 break;
3271 case GL_LOW_INT:
3272 case GL_MEDIUM_INT:
3273 case GL_HIGH_INT:
3274 // Some (most) hardware only supports single-precision floating-point numbers,
3275 // which can accurately represent integers up to +/-16777216
3276 range[0] = 24;
3277 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003278 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003279 break;
3280 default:
3281 return error(GL_INVALID_ENUM);
3282 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003283 }
3284 catch(std::bad_alloc&)
3285 {
3286 return error(GL_OUT_OF_MEMORY);
3287 }
3288}
3289
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003290void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003291{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003292 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 +00003293 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003294
3295 try
3296 {
3297 if (bufsize < 0)
3298 {
3299 return error(GL_INVALID_VALUE);
3300 }
3301
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003302 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003303
3304 if (context)
3305 {
3306 gl::Shader *shaderObject = context->getShader(shader);
3307
3308 if (!shaderObject)
3309 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003310 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003311 }
3312
3313 shaderObject->getSource(bufsize, length, source);
3314 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003315 }
3316 catch(std::bad_alloc&)
3317 {
3318 return error(GL_OUT_OF_MEMORY);
3319 }
3320}
3321
zmo@google.coma574f782011-10-03 21:45:23 +00003322void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3323{
3324 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3325 shader, bufsize, length, source);
3326
3327 try
3328 {
3329 if (bufsize < 0)
3330 {
3331 return error(GL_INVALID_VALUE);
3332 }
3333
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003334 gl::Context *context = gl::getNonLostContext();
zmo@google.coma574f782011-10-03 21:45:23 +00003335
3336 if (context)
3337 {
3338 gl::Shader *shaderObject = context->getShader(shader);
3339
3340 if (!shaderObject)
3341 {
3342 return error(GL_INVALID_OPERATION);
3343 }
3344
3345 shaderObject->getTranslatedSource(bufsize, length, source);
3346 }
3347 }
3348 catch(std::bad_alloc&)
3349 {
3350 return error(GL_OUT_OF_MEMORY);
3351 }
3352}
3353
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003354const GLubyte* __stdcall glGetString(GLenum name)
3355{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003356 EVENT("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003357
3358 try
3359 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003360 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003361
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003362 switch (name)
3363 {
3364 case GL_VENDOR:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003365 return (GLubyte*)"Google Inc.";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003366 case GL_RENDERER:
daniel@transgaming.comc23ff642011-08-16 20:28:45 +00003367 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003368 case GL_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003369 return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003370 case GL_SHADING_LANGUAGE_VERSION:
daniel@transgaming.coma0ce7e62011-01-25 14:47:16 +00003371 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003372 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003373 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003374 default:
3375 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3376 }
3377 }
3378 catch(std::bad_alloc&)
3379 {
3380 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3381 }
3382
3383 return NULL;
3384}
3385
3386void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3387{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003388 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 +00003389
3390 try
3391 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003392 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003393
3394 if (context)
3395 {
3396 gl::Texture *texture;
3397
3398 switch (target)
3399 {
3400 case GL_TEXTURE_2D:
3401 texture = context->getTexture2D();
3402 break;
3403 case GL_TEXTURE_CUBE_MAP:
3404 texture = context->getTextureCubeMap();
3405 break;
3406 default:
3407 return error(GL_INVALID_ENUM);
3408 }
3409
3410 switch (pname)
3411 {
3412 case GL_TEXTURE_MAG_FILTER:
3413 *params = (GLfloat)texture->getMagFilter();
3414 break;
3415 case GL_TEXTURE_MIN_FILTER:
3416 *params = (GLfloat)texture->getMinFilter();
3417 break;
3418 case GL_TEXTURE_WRAP_S:
3419 *params = (GLfloat)texture->getWrapS();
3420 break;
3421 case GL_TEXTURE_WRAP_T:
3422 *params = (GLfloat)texture->getWrapT();
3423 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003424 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3425 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
3426 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003427 case GL_TEXTURE_USAGE_ANGLE:
3428 *params = (GLfloat)texture->getUsage();
3429 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003430 default:
3431 return error(GL_INVALID_ENUM);
3432 }
3433 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003434 }
3435 catch(std::bad_alloc&)
3436 {
3437 return error(GL_OUT_OF_MEMORY);
3438 }
3439}
3440
3441void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3442{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003443 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 +00003444
3445 try
3446 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003447 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003448
3449 if (context)
3450 {
3451 gl::Texture *texture;
3452
3453 switch (target)
3454 {
3455 case GL_TEXTURE_2D:
3456 texture = context->getTexture2D();
3457 break;
3458 case GL_TEXTURE_CUBE_MAP:
3459 texture = context->getTextureCubeMap();
3460 break;
3461 default:
3462 return error(GL_INVALID_ENUM);
3463 }
3464
3465 switch (pname)
3466 {
3467 case GL_TEXTURE_MAG_FILTER:
3468 *params = texture->getMagFilter();
3469 break;
3470 case GL_TEXTURE_MIN_FILTER:
3471 *params = texture->getMinFilter();
3472 break;
3473 case GL_TEXTURE_WRAP_S:
3474 *params = texture->getWrapS();
3475 break;
3476 case GL_TEXTURE_WRAP_T:
3477 *params = texture->getWrapT();
3478 break;
daniel@transgaming.comd30bd0a2011-11-11 04:10:34 +00003479 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT:
3480 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
3481 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00003482 case GL_TEXTURE_USAGE_ANGLE:
3483 *params = texture->getUsage();
3484 break;
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003485 default:
3486 return error(GL_INVALID_ENUM);
3487 }
3488 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003489 }
3490 catch(std::bad_alloc&)
3491 {
3492 return error(GL_OUT_OF_MEMORY);
3493 }
3494}
3495
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003496void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3497{
3498 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3499 program, location, bufSize, params);
3500
3501 try
3502 {
3503 if (bufSize < 0)
3504 {
3505 return error(GL_INVALID_VALUE);
3506 }
3507
3508 gl::Context *context = gl::getNonLostContext();
3509
3510 if (context)
3511 {
3512 if (program == 0)
3513 {
3514 return error(GL_INVALID_VALUE);
3515 }
3516
3517 gl::Program *programObject = context->getProgram(program);
3518
3519 if (!programObject || !programObject->isLinked())
3520 {
3521 return error(GL_INVALID_OPERATION);
3522 }
3523
3524 if (!programObject->getUniformfv(location, &bufSize, params))
3525 {
3526 return error(GL_INVALID_OPERATION);
3527 }
3528 }
3529 }
3530 catch(std::bad_alloc&)
3531 {
3532 return error(GL_OUT_OF_MEMORY);
3533 }
3534}
3535
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003536void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3537{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003538 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003539
3540 try
3541 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003542 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003543
3544 if (context)
3545 {
3546 if (program == 0)
3547 {
3548 return error(GL_INVALID_VALUE);
3549 }
3550
3551 gl::Program *programObject = context->getProgram(program);
3552
3553 if (!programObject || !programObject->isLinked())
3554 {
3555 return error(GL_INVALID_OPERATION);
3556 }
3557
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003558 if (!programObject->getUniformfv(location, NULL, params))
3559 {
3560 return error(GL_INVALID_OPERATION);
3561 }
3562 }
3563 }
3564 catch(std::bad_alloc&)
3565 {
3566 return error(GL_OUT_OF_MEMORY);
3567 }
3568}
3569
3570void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3571{
3572 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3573 program, location, bufSize, params);
3574
3575 try
3576 {
3577 if (bufSize < 0)
3578 {
3579 return error(GL_INVALID_VALUE);
3580 }
3581
3582 gl::Context *context = gl::getNonLostContext();
3583
3584 if (context)
3585 {
3586 if (program == 0)
3587 {
3588 return error(GL_INVALID_VALUE);
3589 }
3590
3591 gl::Program *programObject = context->getProgram(program);
3592
3593 if (!programObject || !programObject->isLinked())
3594 {
3595 return error(GL_INVALID_OPERATION);
3596 }
3597
3598 if (!programObject)
3599 {
3600 return error(GL_INVALID_OPERATION);
3601 }
3602
3603 if (!programObject->getUniformiv(location, &bufSize, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003604 {
3605 return error(GL_INVALID_OPERATION);
3606 }
3607 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003608 }
3609 catch(std::bad_alloc&)
3610 {
3611 return error(GL_OUT_OF_MEMORY);
3612 }
3613}
3614
3615void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3616{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003617 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003618
3619 try
3620 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003621 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003622
3623 if (context)
3624 {
3625 if (program == 0)
3626 {
3627 return error(GL_INVALID_VALUE);
3628 }
3629
3630 gl::Program *programObject = context->getProgram(program);
3631
3632 if (!programObject || !programObject->isLinked())
3633 {
3634 return error(GL_INVALID_OPERATION);
3635 }
3636
3637 if (!programObject)
3638 {
3639 return error(GL_INVALID_OPERATION);
3640 }
3641
daniel@transgaming.com9a849122011-11-12 03:18:00 +00003642 if (!programObject->getUniformiv(location, NULL, params))
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003643 {
3644 return error(GL_INVALID_OPERATION);
3645 }
3646 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003647 }
3648 catch(std::bad_alloc&)
3649 {
3650 return error(GL_OUT_OF_MEMORY);
3651 }
3652}
3653
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003654int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003655{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003656 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003657
3658 try
3659 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003660 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003661
3662 if (strstr(name, "gl_") == name)
3663 {
3664 return -1;
3665 }
3666
3667 if (context)
3668 {
3669 gl::Program *programObject = context->getProgram(program);
3670
3671 if (!programObject)
3672 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003673 if (context->getShader(program))
3674 {
3675 return error(GL_INVALID_OPERATION, -1);
3676 }
3677 else
3678 {
3679 return error(GL_INVALID_VALUE, -1);
3680 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003681 }
3682
3683 if (!programObject->isLinked())
3684 {
3685 return error(GL_INVALID_OPERATION, -1);
3686 }
3687
daniel@transgaming.com024f1a92011-09-20 16:06:25 +00003688 return programObject->getUniformLocation(name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003689 }
3690 }
3691 catch(std::bad_alloc&)
3692 {
3693 return error(GL_OUT_OF_MEMORY, -1);
3694 }
3695
3696 return -1;
3697}
3698
3699void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3700{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003701 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003702
3703 try
3704 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003705 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003706
daniel@transgaming.come0078962010-04-15 20:45:08 +00003707 if (context)
3708 {
3709 if (index >= gl::MAX_VERTEX_ATTRIBS)
3710 {
3711 return error(GL_INVALID_VALUE);
3712 }
3713
daniel@transgaming.com83921382011-01-08 05:46:00 +00003714 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003715
daniel@transgaming.come0078962010-04-15 20:45:08 +00003716 switch (pname)
3717 {
3718 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003719 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003720 break;
3721 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003722 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003723 break;
3724 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003725 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003726 break;
3727 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003728 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003729 break;
3730 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003731 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003732 break;
3733 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003734 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003735 break;
3736 case GL_CURRENT_VERTEX_ATTRIB:
3737 for (int i = 0; i < 4; ++i)
3738 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003739 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003740 }
3741 break;
3742 default: return error(GL_INVALID_ENUM);
3743 }
3744 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003745 }
3746 catch(std::bad_alloc&)
3747 {
3748 return error(GL_OUT_OF_MEMORY);
3749 }
3750}
3751
3752void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3753{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003754 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003755
3756 try
3757 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003758 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003759
daniel@transgaming.come0078962010-04-15 20:45:08 +00003760 if (context)
3761 {
3762 if (index >= gl::MAX_VERTEX_ATTRIBS)
3763 {
3764 return error(GL_INVALID_VALUE);
3765 }
3766
daniel@transgaming.com83921382011-01-08 05:46:00 +00003767 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003768
daniel@transgaming.come0078962010-04-15 20:45:08 +00003769 switch (pname)
3770 {
3771 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003772 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003773 break;
3774 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003775 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003776 break;
3777 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003778 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003779 break;
3780 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003781 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003782 break;
3783 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003784 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003785 break;
3786 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003787 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003788 break;
3789 case GL_CURRENT_VERTEX_ATTRIB:
3790 for (int i = 0; i < 4; ++i)
3791 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003792 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003793 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3794 }
3795 break;
3796 default: return error(GL_INVALID_ENUM);
3797 }
3798 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003799 }
3800 catch(std::bad_alloc&)
3801 {
3802 return error(GL_OUT_OF_MEMORY);
3803 }
3804}
3805
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003806void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003807{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003808 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003809
3810 try
3811 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003812 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003813
daniel@transgaming.come0078962010-04-15 20:45:08 +00003814 if (context)
3815 {
3816 if (index >= gl::MAX_VERTEX_ATTRIBS)
3817 {
3818 return error(GL_INVALID_VALUE);
3819 }
3820
3821 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3822 {
3823 return error(GL_INVALID_ENUM);
3824 }
3825
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003826 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003827 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003828 }
3829 catch(std::bad_alloc&)
3830 {
3831 return error(GL_OUT_OF_MEMORY);
3832 }
3833}
3834
3835void __stdcall glHint(GLenum target, GLenum mode)
3836{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003837 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003838
3839 try
3840 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003841 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003842 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003843 case GL_FASTEST:
3844 case GL_NICEST:
3845 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003846 break;
3847 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003848 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003849 }
3850
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003851 gl::Context *context = gl::getNonLostContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003852 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003853 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003854 case GL_GENERATE_MIPMAP_HINT:
3855 if (context) context->setGenerateMipmapHint(mode);
3856 break;
3857 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3858 if (context) context->setFragmentShaderDerivativeHint(mode);
3859 break;
3860 default:
3861 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003862 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003863 }
3864 catch(std::bad_alloc&)
3865 {
3866 return error(GL_OUT_OF_MEMORY);
3867 }
3868}
3869
3870GLboolean __stdcall glIsBuffer(GLuint buffer)
3871{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003872 EVENT("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003873
3874 try
3875 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003876 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003877
3878 if (context && buffer)
3879 {
3880 gl::Buffer *bufferObject = context->getBuffer(buffer);
3881
3882 if (bufferObject)
3883 {
3884 return GL_TRUE;
3885 }
3886 }
3887 }
3888 catch(std::bad_alloc&)
3889 {
3890 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3891 }
3892
3893 return GL_FALSE;
3894}
3895
3896GLboolean __stdcall glIsEnabled(GLenum cap)
3897{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003898 EVENT("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003899
3900 try
3901 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003902 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003903
3904 if (context)
3905 {
3906 switch (cap)
3907 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003908 case GL_CULL_FACE: return context->isCullFaceEnabled();
3909 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3910 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3911 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3912 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3913 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3914 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3915 case GL_BLEND: return context->isBlendEnabled();
3916 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003917 default:
3918 return error(GL_INVALID_ENUM, false);
3919 }
3920 }
3921 }
3922 catch(std::bad_alloc&)
3923 {
3924 return error(GL_OUT_OF_MEMORY, false);
3925 }
3926
3927 return false;
3928}
3929
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003930GLboolean __stdcall glIsFenceNV(GLuint fence)
3931{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003932 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003933
3934 try
3935 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003936 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003937
3938 if (context)
3939 {
3940 gl::Fence *fenceObject = context->getFence(fence);
3941
3942 if (fenceObject == NULL)
3943 {
3944 return GL_FALSE;
3945 }
3946
3947 return fenceObject->isFence();
3948 }
3949 }
3950 catch(std::bad_alloc&)
3951 {
3952 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3953 }
3954
3955 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003956}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003957
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003958GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3959{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003960 EVENT("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003961
3962 try
3963 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003964 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003965
3966 if (context && framebuffer)
3967 {
3968 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3969
3970 if (framebufferObject)
3971 {
3972 return GL_TRUE;
3973 }
3974 }
3975 }
3976 catch(std::bad_alloc&)
3977 {
3978 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3979 }
3980
3981 return GL_FALSE;
3982}
3983
3984GLboolean __stdcall glIsProgram(GLuint program)
3985{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00003986 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003987
3988 try
3989 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00003990 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003991
3992 if (context && program)
3993 {
3994 gl::Program *programObject = context->getProgram(program);
3995
3996 if (programObject)
3997 {
3998 return GL_TRUE;
3999 }
4000 }
4001 }
4002 catch(std::bad_alloc&)
4003 {
4004 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4005 }
4006
4007 return GL_FALSE;
4008}
4009
4010GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
4011{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004012 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004013
4014 try
4015 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004016 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004017
4018 if (context && renderbuffer)
4019 {
4020 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4021
4022 if (renderbufferObject)
4023 {
4024 return GL_TRUE;
4025 }
4026 }
4027 }
4028 catch(std::bad_alloc&)
4029 {
4030 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4031 }
4032
4033 return GL_FALSE;
4034}
4035
4036GLboolean __stdcall glIsShader(GLuint shader)
4037{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004038 EVENT("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004039
4040 try
4041 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004042 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004043
4044 if (context && shader)
4045 {
4046 gl::Shader *shaderObject = context->getShader(shader);
4047
4048 if (shaderObject)
4049 {
4050 return GL_TRUE;
4051 }
4052 }
4053 }
4054 catch(std::bad_alloc&)
4055 {
4056 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4057 }
4058
4059 return GL_FALSE;
4060}
4061
4062GLboolean __stdcall glIsTexture(GLuint texture)
4063{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004064 EVENT("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004065
4066 try
4067 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004068 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004069
4070 if (context && texture)
4071 {
4072 gl::Texture *textureObject = context->getTexture(texture);
4073
4074 if (textureObject)
4075 {
4076 return GL_TRUE;
4077 }
4078 }
4079 }
4080 catch(std::bad_alloc&)
4081 {
4082 return error(GL_OUT_OF_MEMORY, GL_FALSE);
4083 }
4084
4085 return GL_FALSE;
4086}
4087
4088void __stdcall glLineWidth(GLfloat width)
4089{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004090 EVENT("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004091
4092 try
4093 {
4094 if (width <= 0.0f)
4095 {
4096 return error(GL_INVALID_VALUE);
4097 }
4098
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004099 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00004100
4101 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004102 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004103 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004104 }
4105 }
4106 catch(std::bad_alloc&)
4107 {
4108 return error(GL_OUT_OF_MEMORY);
4109 }
4110}
4111
4112void __stdcall glLinkProgram(GLuint program)
4113{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004114 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004115
4116 try
4117 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004118 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004119
4120 if (context)
4121 {
4122 gl::Program *programObject = context->getProgram(program);
4123
4124 if (!programObject)
4125 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00004126 if (context->getShader(program))
4127 {
4128 return error(GL_INVALID_OPERATION);
4129 }
4130 else
4131 {
4132 return error(GL_INVALID_VALUE);
4133 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004134 }
4135
4136 programObject->link();
4137 }
4138 }
4139 catch(std::bad_alloc&)
4140 {
4141 return error(GL_OUT_OF_MEMORY);
4142 }
4143}
4144
4145void __stdcall glPixelStorei(GLenum pname, GLint param)
4146{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004147 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004148
4149 try
4150 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004151 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004152
4153 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004154 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004155 switch (pname)
4156 {
4157 case GL_UNPACK_ALIGNMENT:
4158 if (param != 1 && param != 2 && param != 4 && param != 8)
4159 {
4160 return error(GL_INVALID_VALUE);
4161 }
4162
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004163 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004164 break;
4165
4166 case GL_PACK_ALIGNMENT:
4167 if (param != 1 && param != 2 && param != 4 && param != 8)
4168 {
4169 return error(GL_INVALID_VALUE);
4170 }
4171
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004172 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004173 break;
4174
bsalomon@google.com56d46ab2011-11-23 14:53:10 +00004175 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4176 context->setPackReverseRowOrder(param != 0);
4177 break;
4178
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004179 default:
4180 return error(GL_INVALID_ENUM);
4181 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004182 }
4183 }
4184 catch(std::bad_alloc&)
4185 {
4186 return error(GL_OUT_OF_MEMORY);
4187 }
4188}
4189
4190void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
4191{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004192 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004193
4194 try
4195 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004196 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.comaede6302010-04-29 03:35:48 +00004197
4198 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004199 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004200 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004201 }
4202 }
4203 catch(std::bad_alloc&)
4204 {
4205 return error(GL_OUT_OF_MEMORY);
4206 }
4207}
4208
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004209void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4210 GLenum format, GLenum type, GLsizei bufSize,
4211 GLvoid *data)
4212{
4213 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4214 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
4215 x, y, width, height, format, type, bufSize, data);
4216
4217 try
4218 {
4219 if (width < 0 || height < 0 || bufSize < 0)
4220 {
4221 return error(GL_INVALID_VALUE);
4222 }
4223
4224 if (!validReadFormatType(format, type))
4225 {
4226 return error(GL_INVALID_OPERATION);
4227 }
4228
4229 gl::Context *context = gl::getNonLostContext();
4230
4231 if (context)
4232 {
4233 context->readPixels(x, y, width, height, format, type, &bufSize, data);
4234 }
4235 }
4236 catch(std::bad_alloc&)
4237 {
4238 return error(GL_OUT_OF_MEMORY);
4239 }
4240}
4241
4242void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
4243 GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004244{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004245 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004246 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004247 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004248
4249 try
4250 {
4251 if (width < 0 || height < 0)
4252 {
4253 return error(GL_INVALID_VALUE);
4254 }
4255
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004256 if (!validReadFormatType(format, type))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004257 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004258 return error(GL_INVALID_OPERATION);
4259 }
4260
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004261 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004262
4263 if (context)
4264 {
daniel@transgaming.comb7915a52011-11-12 03:14:20 +00004265 context->readPixels(x, y, width, height, format, type, NULL, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004266 }
4267 }
4268 catch(std::bad_alloc&)
4269 {
4270 return error(GL_OUT_OF_MEMORY);
4271 }
4272}
4273
4274void __stdcall glReleaseShaderCompiler(void)
4275{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004276 EVENT("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004277
4278 try
4279 {
4280 gl::Shader::releaseCompiler();
4281 }
4282 catch(std::bad_alloc&)
4283 {
4284 return error(GL_OUT_OF_MEMORY);
4285 }
4286}
4287
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004288void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004289{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004290 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 +00004291 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004292
4293 try
4294 {
4295 switch (target)
4296 {
4297 case GL_RENDERBUFFER:
4298 break;
4299 default:
4300 return error(GL_INVALID_ENUM);
4301 }
4302
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004303 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004304 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004305 return error(GL_INVALID_ENUM);
4306 }
4307
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004308 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004309 {
4310 return error(GL_INVALID_VALUE);
4311 }
4312
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004313 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004314
4315 if (context)
4316 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004317 if (width > context->getMaximumRenderbufferDimension() ||
4318 height > context->getMaximumRenderbufferDimension() ||
4319 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004320 {
4321 return error(GL_INVALID_VALUE);
4322 }
4323
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004324 GLuint handle = context->getRenderbufferHandle();
4325 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004326 {
4327 return error(GL_INVALID_OPERATION);
4328 }
4329
4330 switch (internalformat)
4331 {
4332 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004333 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004334 break;
4335 case GL_RGBA4:
4336 case GL_RGB5_A1:
4337 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004338 case GL_RGB8_OES:
4339 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004340 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004341 break;
4342 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004343 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004344 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004345 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004346 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004347 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004348 default:
4349 return error(GL_INVALID_ENUM);
4350 }
4351 }
4352 }
4353 catch(std::bad_alloc&)
4354 {
4355 return error(GL_OUT_OF_MEMORY);
4356 }
4357}
4358
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004359void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4360{
4361 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4362}
4363
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004364void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4365{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004366 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004367
4368 try
4369 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004370 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004371
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004372 if (context)
4373 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004374 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004375 }
4376 }
4377 catch(std::bad_alloc&)
4378 {
4379 return error(GL_OUT_OF_MEMORY);
4380 }
4381}
4382
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004383void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4384{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004385 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004386
4387 try
4388 {
4389 if (condition != GL_ALL_COMPLETED_NV)
4390 {
4391 return error(GL_INVALID_ENUM);
4392 }
4393
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004394 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004395
4396 if (context)
4397 {
4398 gl::Fence *fenceObject = context->getFence(fence);
4399
4400 if (fenceObject == NULL)
4401 {
4402 return error(GL_INVALID_OPERATION);
4403 }
4404
4405 fenceObject->setFence(condition);
4406 }
4407 }
4408 catch(std::bad_alloc&)
4409 {
4410 return error(GL_OUT_OF_MEMORY);
4411 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004412}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004413
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004414void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4415{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004416 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 +00004417
4418 try
4419 {
4420 if (width < 0 || height < 0)
4421 {
4422 return error(GL_INVALID_VALUE);
4423 }
4424
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004425 gl::Context* context = gl::getNonLostContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004426
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004427 if (context)
4428 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004429 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004430 }
4431 }
4432 catch(std::bad_alloc&)
4433 {
4434 return error(GL_OUT_OF_MEMORY);
4435 }
4436}
4437
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004438void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004439{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004440 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004441 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004442 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004443
4444 try
4445 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004446 // No binary shader formats are supported.
4447 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004448 }
4449 catch(std::bad_alloc&)
4450 {
4451 return error(GL_OUT_OF_MEMORY);
4452 }
4453}
4454
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004455void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004456{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004457 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 +00004458 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004459
4460 try
4461 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004462 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004463 {
4464 return error(GL_INVALID_VALUE);
4465 }
4466
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004467 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004468
4469 if (context)
4470 {
4471 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004472
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004473 if (!shaderObject)
4474 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004475 if (context->getProgram(shader))
4476 {
4477 return error(GL_INVALID_OPERATION);
4478 }
4479 else
4480 {
4481 return error(GL_INVALID_VALUE);
4482 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004483 }
4484
4485 shaderObject->setSource(count, string, length);
4486 }
4487 }
4488 catch(std::bad_alloc&)
4489 {
4490 return error(GL_OUT_OF_MEMORY);
4491 }
4492}
4493
4494void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4495{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004496 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004497}
4498
4499void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4500{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004501 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 +00004502
4503 try
4504 {
4505 switch (face)
4506 {
4507 case GL_FRONT:
4508 case GL_BACK:
4509 case GL_FRONT_AND_BACK:
4510 break;
4511 default:
4512 return error(GL_INVALID_ENUM);
4513 }
4514
4515 switch (func)
4516 {
4517 case GL_NEVER:
4518 case GL_ALWAYS:
4519 case GL_LESS:
4520 case GL_LEQUAL:
4521 case GL_EQUAL:
4522 case GL_GEQUAL:
4523 case GL_GREATER:
4524 case GL_NOTEQUAL:
4525 break;
4526 default:
4527 return error(GL_INVALID_ENUM);
4528 }
4529
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004530 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004531
4532 if (context)
4533 {
4534 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4535 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004536 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004537 }
4538
4539 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4540 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004541 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004542 }
4543 }
4544 }
4545 catch(std::bad_alloc&)
4546 {
4547 return error(GL_OUT_OF_MEMORY);
4548 }
4549}
4550
4551void __stdcall glStencilMask(GLuint mask)
4552{
4553 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4554}
4555
4556void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4557{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004558 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004559
4560 try
4561 {
4562 switch (face)
4563 {
4564 case GL_FRONT:
4565 case GL_BACK:
4566 case GL_FRONT_AND_BACK:
4567 break;
4568 default:
4569 return error(GL_INVALID_ENUM);
4570 }
4571
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004572 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004573
4574 if (context)
4575 {
4576 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4577 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004578 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004579 }
4580
4581 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4582 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004583 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004584 }
4585 }
4586 }
4587 catch(std::bad_alloc&)
4588 {
4589 return error(GL_OUT_OF_MEMORY);
4590 }
4591}
4592
4593void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4594{
4595 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4596}
4597
4598void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4599{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004600 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 +00004601 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004602
4603 try
4604 {
4605 switch (face)
4606 {
4607 case GL_FRONT:
4608 case GL_BACK:
4609 case GL_FRONT_AND_BACK:
4610 break;
4611 default:
4612 return error(GL_INVALID_ENUM);
4613 }
4614
4615 switch (fail)
4616 {
4617 case GL_ZERO:
4618 case GL_KEEP:
4619 case GL_REPLACE:
4620 case GL_INCR:
4621 case GL_DECR:
4622 case GL_INVERT:
4623 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004624 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004625 break;
4626 default:
4627 return error(GL_INVALID_ENUM);
4628 }
4629
4630 switch (zfail)
4631 {
4632 case GL_ZERO:
4633 case GL_KEEP:
4634 case GL_REPLACE:
4635 case GL_INCR:
4636 case GL_DECR:
4637 case GL_INVERT:
4638 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004639 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004640 break;
4641 default:
4642 return error(GL_INVALID_ENUM);
4643 }
4644
4645 switch (zpass)
4646 {
4647 case GL_ZERO:
4648 case GL_KEEP:
4649 case GL_REPLACE:
4650 case GL_INCR:
4651 case GL_DECR:
4652 case GL_INVERT:
4653 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004654 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004655 break;
4656 default:
4657 return error(GL_INVALID_ENUM);
4658 }
4659
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004660 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004661
4662 if (context)
4663 {
4664 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4665 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004666 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004667 }
4668
4669 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4670 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004671 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004672 }
4673 }
4674 }
4675 catch(std::bad_alloc&)
4676 {
4677 return error(GL_OUT_OF_MEMORY);
4678 }
4679}
4680
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004681GLboolean __stdcall glTestFenceNV(GLuint fence)
4682{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004683 EVENT("(GLuint fence = %d)", fence);
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004684
4685 try
4686 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004687 gl::Context *context = gl::getNonLostContext();
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004688
4689 if (context)
4690 {
4691 gl::Fence *fenceObject = context->getFence(fence);
4692
4693 if (fenceObject == NULL)
4694 {
4695 return error(GL_INVALID_OPERATION, GL_TRUE);
4696 }
4697
4698 return fenceObject->testFence();
4699 }
4700 }
4701 catch(std::bad_alloc&)
4702 {
4703 error(GL_OUT_OF_MEMORY);
4704 }
4705
4706 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004707}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004708
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004709void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4710 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004711{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004712 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 +00004713 "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 +00004714 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004715
4716 try
4717 {
daniel@transgaming.com4f9ef0d2011-05-30 23:51:19 +00004718 if (!validImageSize(level, width, height))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004719 {
4720 return error(GL_INVALID_VALUE);
4721 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004722
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004723 if (internalformat != format)
4724 {
4725 return error(GL_INVALID_OPERATION);
4726 }
4727
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004728 switch (format)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004729 {
4730 case GL_ALPHA:
4731 case GL_LUMINANCE:
4732 case GL_LUMINANCE_ALPHA:
4733 switch (type)
4734 {
4735 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004736 case GL_FLOAT:
4737 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004738 break;
4739 default:
4740 return error(GL_INVALID_ENUM);
4741 }
4742 break;
4743 case GL_RGB:
4744 switch (type)
4745 {
4746 case GL_UNSIGNED_BYTE:
4747 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004748 case GL_FLOAT:
4749 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004750 break;
4751 default:
4752 return error(GL_INVALID_ENUM);
4753 }
4754 break;
4755 case GL_RGBA:
4756 switch (type)
4757 {
4758 case GL_UNSIGNED_BYTE:
4759 case GL_UNSIGNED_SHORT_4_4_4_4:
4760 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004761 case GL_FLOAT:
4762 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004763 break;
4764 default:
4765 return error(GL_INVALID_ENUM);
4766 }
4767 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004768 case GL_BGRA_EXT:
4769 switch (type)
4770 {
4771 case GL_UNSIGNED_BYTE:
4772 break;
4773 default:
4774 return error(GL_INVALID_ENUM);
4775 }
4776 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004777 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4778 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
gman@chromium.org50c526d2011-08-10 05:19:44 +00004779 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4780 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
daniel@transgaming.com01868132010-08-24 19:21:17 +00004781 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004782 default:
4783 return error(GL_INVALID_VALUE);
4784 }
4785
4786 if (border != 0)
4787 {
4788 return error(GL_INVALID_VALUE);
4789 }
4790
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004791 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004792
4793 if (context)
4794 {
daniel@transgaming.com32b11442011-11-19 02:42:48 +00004795 if (level > context->getMaximumTextureLevel())
4796 {
4797 return error(GL_INVALID_VALUE);
4798 }
4799
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004800 switch (target)
4801 {
4802 case GL_TEXTURE_2D:
4803 if (width > (context->getMaximumTextureDimension() >> level) ||
4804 height > (context->getMaximumTextureDimension() >> level))
4805 {
4806 return error(GL_INVALID_VALUE);
4807 }
4808 break;
4809 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4810 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4811 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4812 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4813 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4814 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4815 if (width != height)
4816 {
4817 return error(GL_INVALID_VALUE);
4818 }
4819
4820 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4821 height > (context->getMaximumCubeTextureDimension() >> level))
4822 {
4823 return error(GL_INVALID_VALUE);
4824 }
4825 break;
4826 default:
4827 return error(GL_INVALID_ENUM);
4828 }
4829
gman@chromium.org50c526d2011-08-10 05:19:44 +00004830 switch (format) {
4831 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
4832 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4833 if (context->supportsDXT1Textures())
daniel@transgaming.com01868132010-08-24 19:21:17 +00004834 {
4835 return error(GL_INVALID_OPERATION);
4836 }
4837 else
4838 {
4839 return error(GL_INVALID_ENUM);
4840 }
gman@chromium.org50c526d2011-08-10 05:19:44 +00004841 break;
4842 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
4843 if (context->supportsDXT3Textures())
4844 {
4845 return error(GL_INVALID_OPERATION);
4846 }
4847 else
4848 {
4849 return error(GL_INVALID_ENUM);
4850 }
4851 break;
4852 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
4853 if (context->supportsDXT5Textures())
4854 {
4855 return error(GL_INVALID_OPERATION);
4856 }
4857 else
4858 {
4859 return error(GL_INVALID_ENUM);
4860 }
4861 break;
4862 default:
4863 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004864 }
4865
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004866 if (type == GL_FLOAT)
4867 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004868 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004869 {
4870 return error(GL_INVALID_ENUM);
4871 }
4872 }
4873 else if (type == GL_HALF_FLOAT_OES)
4874 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00004875 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004876 {
4877 return error(GL_INVALID_ENUM);
4878 }
4879 }
4880
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004881 if (target == GL_TEXTURE_2D)
4882 {
4883 gl::Texture2D *texture = context->getTexture2D();
4884
4885 if (!texture)
4886 {
4887 return error(GL_INVALID_OPERATION);
4888 }
4889
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004890 if (texture->isImmutable())
4891 {
4892 return error(GL_INVALID_OPERATION);
4893 }
4894
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004895 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004896 }
4897 else
4898 {
4899 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4900
4901 if (!texture)
4902 {
4903 return error(GL_INVALID_OPERATION);
4904 }
4905
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00004906 if (texture->isImmutable())
4907 {
4908 return error(GL_INVALID_OPERATION);
4909 }
4910
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004911 switch (target)
4912 {
4913 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004914 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004915 break;
4916 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004917 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004918 break;
4919 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004920 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004921 break;
4922 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004923 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004924 break;
4925 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004926 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004927 break;
4928 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com8a0a2db2011-03-21 16:38:20 +00004929 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004930 break;
4931 default: UNREACHABLE();
4932 }
4933 }
4934 }
4935 }
4936 catch(std::bad_alloc&)
4937 {
4938 return error(GL_OUT_OF_MEMORY);
4939 }
4940}
4941
4942void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4943{
4944 glTexParameteri(target, pname, (GLint)param);
4945}
4946
4947void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4948{
4949 glTexParameteri(target, pname, (GLint)*params);
4950}
4951
4952void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4953{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00004954 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004955
4956 try
4957 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00004958 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004959
4960 if (context)
4961 {
4962 gl::Texture *texture;
4963
4964 switch (target)
4965 {
4966 case GL_TEXTURE_2D:
4967 texture = context->getTexture2D();
4968 break;
4969 case GL_TEXTURE_CUBE_MAP:
4970 texture = context->getTextureCubeMap();
4971 break;
4972 default:
4973 return error(GL_INVALID_ENUM);
4974 }
4975
4976 switch (pname)
4977 {
4978 case GL_TEXTURE_WRAP_S:
4979 if (!texture->setWrapS((GLenum)param))
4980 {
4981 return error(GL_INVALID_ENUM);
4982 }
4983 break;
4984 case GL_TEXTURE_WRAP_T:
4985 if (!texture->setWrapT((GLenum)param))
4986 {
4987 return error(GL_INVALID_ENUM);
4988 }
4989 break;
4990 case GL_TEXTURE_MIN_FILTER:
4991 if (!texture->setMinFilter((GLenum)param))
4992 {
4993 return error(GL_INVALID_ENUM);
4994 }
4995 break;
4996 case GL_TEXTURE_MAG_FILTER:
4997 if (!texture->setMagFilter((GLenum)param))
4998 {
4999 return error(GL_INVALID_ENUM);
5000 }
5001 break;
daniel@transgaming.com7d18c172011-11-11 04:18:21 +00005002 case GL_TEXTURE_USAGE_ANGLE:
5003 if (!texture->setUsage((GLenum)param))
5004 {
5005 return error(GL_INVALID_ENUM);
5006 }
5007 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005008 default:
5009 return error(GL_INVALID_ENUM);
5010 }
5011 }
5012 }
5013 catch(std::bad_alloc&)
5014 {
5015 return error(GL_OUT_OF_MEMORY);
5016 }
5017}
5018
5019void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
5020{
5021 glTexParameteri(target, pname, *params);
5022}
5023
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005024void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
5025{
5026 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
5027 target, levels, internalformat, width, height);
5028
5029 try
5030 {
5031 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
5032 {
5033 return error(GL_INVALID_ENUM);
5034 }
5035
5036 if (width < 1 || height < 1 || levels < 1)
5037 {
5038 return error(GL_INVALID_VALUE);
5039 }
5040
5041 if (target == GL_TEXTURE_CUBE_MAP && width != height)
5042 {
5043 return error(GL_INVALID_VALUE);
5044 }
5045
daniel@transgaming.com45b888a2011-11-16 03:56:39 +00005046 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005047 {
5048 return error(GL_INVALID_OPERATION);
5049 }
5050
5051 GLenum format = gl::ExtractFormat(internalformat);
5052 GLenum type = gl::ExtractType(internalformat);
5053
5054 if (format == GL_NONE || type == GL_NONE)
5055 {
5056 return error(GL_INVALID_ENUM);
5057 }
5058
5059 gl::Context *context = gl::getNonLostContext();
5060
5061 if (context)
5062 {
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005063 switch (target)
5064 {
5065 case GL_TEXTURE_2D:
5066 if (width > context->getMaximumTextureDimension() ||
5067 height > context->getMaximumTextureDimension())
5068 {
5069 return error(GL_INVALID_VALUE);
5070 }
5071 break;
5072 case GL_TEXTURE_CUBE_MAP:
5073 if (width > context->getMaximumCubeTextureDimension() ||
5074 height > context->getMaximumCubeTextureDimension())
5075 {
5076 return error(GL_INVALID_VALUE);
5077 }
5078 break;
5079 default:
5080 return error(GL_INVALID_ENUM);
5081 }
5082
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005083 if (levels != 1 && !context->supportsNonPower2Texture())
5084 {
5085 if (!gl::isPow2(width) || !gl::isPow2(height))
5086 {
5087 return error(GL_INVALID_OPERATION);
5088 }
5089 }
5090
daniel@transgaming.come1077362011-11-11 04:16:50 +00005091 switch (internalformat)
5092 {
5093 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
5094 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
5095 if (!context->supportsDXT1Textures())
5096 {
5097 return error(GL_INVALID_ENUM);
5098 }
5099 break;
5100 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
5101 if (!context->supportsDXT3Textures())
5102 {
5103 return error(GL_INVALID_ENUM);
5104 }
5105 break;
5106 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
5107 if (!context->supportsDXT5Textures())
5108 {
5109 return error(GL_INVALID_ENUM);
5110 }
5111 break;
daniel@transgaming.comff941aa2011-11-11 04:17:09 +00005112 case GL_RGBA32F_EXT:
5113 case GL_RGB32F_EXT:
5114 case GL_ALPHA32F_EXT:
5115 case GL_LUMINANCE32F_EXT:
5116 case GL_LUMINANCE_ALPHA32F_EXT:
5117 if (!context->supportsFloat32Textures())
5118 {
5119 return error(GL_INVALID_ENUM);
5120 }
5121 break;
5122 case GL_RGBA16F_EXT:
5123 case GL_RGB16F_EXT:
5124 case GL_ALPHA16F_EXT:
5125 case GL_LUMINANCE16F_EXT:
5126 case GL_LUMINANCE_ALPHA16F_EXT:
5127 if (!context->supportsFloat16Textures())
5128 {
5129 return error(GL_INVALID_ENUM);
5130 }
5131 break;
daniel@transgaming.come1077362011-11-11 04:16:50 +00005132 }
5133
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00005134 if (target == GL_TEXTURE_2D)
5135 {
5136 gl::Texture2D *texture = context->getTexture2D();
5137
5138 if (!texture || texture->id() == 0)
5139 {
5140 return error(GL_INVALID_OPERATION);
5141 }
5142
5143 if (texture->isImmutable())
5144 {
5145 return error(GL_INVALID_OPERATION);
5146 }
5147
5148 texture->storage(levels, internalformat, width, height);
5149 }
5150 else if (target == GL_TEXTURE_CUBE_MAP)
5151 {
5152 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5153
5154 if (!texture || texture->id() == 0)
5155 {
5156 return error(GL_INVALID_OPERATION);
5157 }
5158
5159 if (texture->isImmutable())
5160 {
5161 return error(GL_INVALID_OPERATION);
5162 }
5163
5164 texture->storage(levels, internalformat, width);
5165 }
5166 else UNREACHABLE();
5167 }
5168 }
5169 catch(std::bad_alloc&)
5170 {
5171 return error(GL_OUT_OF_MEMORY);
5172 }
5173}
5174
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005175void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5176 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005177{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005178 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005179 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005180 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005181 target, level, xoffset, yoffset, width, height, format, type, pixels);
5182
5183 try
5184 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005185 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005186 {
5187 return error(GL_INVALID_ENUM);
5188 }
5189
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005190 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005191 {
5192 return error(GL_INVALID_VALUE);
5193 }
5194
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005195 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5196 {
5197 return error(GL_INVALID_VALUE);
5198 }
5199
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005200 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005201 {
5202 return error(GL_INVALID_ENUM);
5203 }
5204
5205 if (width == 0 || height == 0 || pixels == NULL)
5206 {
5207 return;
5208 }
5209
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005210 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005211
5212 if (context)
5213 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00005214 if (level > context->getMaximumTextureLevel())
5215 {
5216 return error(GL_INVALID_VALUE);
5217 }
5218
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005219 if (format == GL_FLOAT)
5220 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005221 if (!context->supportsFloat32Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005222 {
5223 return error(GL_INVALID_ENUM);
5224 }
5225 }
5226 else if (format == GL_HALF_FLOAT_OES)
5227 {
daniel@transgaming.combbeffbb2011-11-09 17:46:11 +00005228 if (!context->supportsFloat16Textures())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005229 {
5230 return error(GL_INVALID_ENUM);
5231 }
5232 }
5233
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005234 if (target == GL_TEXTURE_2D)
5235 {
5236 gl::Texture2D *texture = context->getTexture2D();
5237
5238 if (!texture)
5239 {
5240 return error(GL_INVALID_OPERATION);
5241 }
5242
daniel@transgaming.com01868132010-08-24 19:21:17 +00005243 if (texture->isCompressed())
5244 {
5245 return error(GL_INVALID_OPERATION);
5246 }
5247
daniel@transgaming.comd2fd4f22011-02-01 18:49:11 +00005248 if (format != texture->getInternalFormat())
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00005249 {
5250 return error(GL_INVALID_OPERATION);
5251 }
5252
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005253 if (xoffset + width > texture->getWidth(level) ||
5254 yoffset + height > texture->getHeight(level))
5255 {
5256 return error(GL_INVALID_VALUE);
5257 }
5258
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005259 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005260 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00005261 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005262 {
5263 gl::TextureCubeMap *texture = context->getTextureCubeMap();
5264
5265 if (!texture)
5266 {
5267 return error(GL_INVALID_OPERATION);
5268 }
5269
daniel@transgaming.com21f05d72011-11-29 19:42:28 +00005270 if (texture->isCompressed())
5271 {
5272 return error(GL_INVALID_OPERATION);
5273 }
5274
5275 if (format != texture->getInternalFormat())
5276 {
5277 return error(GL_INVALID_OPERATION);
5278 }
5279
5280 if (xoffset + width > texture->getWidth(level) ||
5281 yoffset + height > texture->getHeight(level))
5282 {
5283 return error(GL_INVALID_VALUE);
5284 }
5285
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005286 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00005287 }
5288 else
5289 {
5290 UNREACHABLE();
5291 }
5292 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005293 }
5294 catch(std::bad_alloc&)
5295 {
5296 return error(GL_OUT_OF_MEMORY);
5297 }
5298}
5299
5300void __stdcall glUniform1f(GLint location, GLfloat x)
5301{
5302 glUniform1fv(location, 1, &x);
5303}
5304
5305void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
5306{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005307 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005308
5309 try
5310 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005311 if (count < 0)
5312 {
5313 return error(GL_INVALID_VALUE);
5314 }
5315
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005316 if (location == -1)
5317 {
5318 return;
5319 }
5320
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005321 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005322
5323 if (context)
5324 {
5325 gl::Program *program = context->getCurrentProgram();
5326
5327 if (!program)
5328 {
5329 return error(GL_INVALID_OPERATION);
5330 }
5331
5332 if (!program->setUniform1fv(location, count, v))
5333 {
5334 return error(GL_INVALID_OPERATION);
5335 }
5336 }
5337 }
5338 catch(std::bad_alloc&)
5339 {
5340 return error(GL_OUT_OF_MEMORY);
5341 }
5342}
5343
5344void __stdcall glUniform1i(GLint location, GLint x)
5345{
5346 glUniform1iv(location, 1, &x);
5347}
5348
5349void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
5350{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005351 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005352
5353 try
5354 {
5355 if (count < 0)
5356 {
5357 return error(GL_INVALID_VALUE);
5358 }
5359
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005360 if (location == -1)
5361 {
5362 return;
5363 }
5364
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005365 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005366
5367 if (context)
5368 {
5369 gl::Program *program = context->getCurrentProgram();
5370
5371 if (!program)
5372 {
5373 return error(GL_INVALID_OPERATION);
5374 }
5375
5376 if (!program->setUniform1iv(location, count, v))
5377 {
5378 return error(GL_INVALID_OPERATION);
5379 }
5380 }
5381 }
5382 catch(std::bad_alloc&)
5383 {
5384 return error(GL_OUT_OF_MEMORY);
5385 }
5386}
5387
5388void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
5389{
5390 GLfloat xy[2] = {x, y};
5391
5392 glUniform2fv(location, 1, (GLfloat*)&xy);
5393}
5394
5395void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
5396{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005397 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005398
5399 try
5400 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005401 if (count < 0)
5402 {
5403 return error(GL_INVALID_VALUE);
5404 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005405
5406 if (location == -1)
5407 {
5408 return;
5409 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005410
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005411 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005412
5413 if (context)
5414 {
5415 gl::Program *program = context->getCurrentProgram();
5416
5417 if (!program)
5418 {
5419 return error(GL_INVALID_OPERATION);
5420 }
5421
5422 if (!program->setUniform2fv(location, count, v))
5423 {
5424 return error(GL_INVALID_OPERATION);
5425 }
5426 }
5427 }
5428 catch(std::bad_alloc&)
5429 {
5430 return error(GL_OUT_OF_MEMORY);
5431 }
5432}
5433
5434void __stdcall glUniform2i(GLint location, GLint x, GLint y)
5435{
5436 GLint xy[4] = {x, y};
5437
5438 glUniform2iv(location, 1, (GLint*)&xy);
5439}
5440
5441void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
5442{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005443 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005444
5445 try
5446 {
5447 if (count < 0)
5448 {
5449 return error(GL_INVALID_VALUE);
5450 }
5451
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005452 if (location == -1)
5453 {
5454 return;
5455 }
5456
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005457 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005458
5459 if (context)
5460 {
5461 gl::Program *program = context->getCurrentProgram();
5462
5463 if (!program)
5464 {
5465 return error(GL_INVALID_OPERATION);
5466 }
5467
5468 if (!program->setUniform2iv(location, count, v))
5469 {
5470 return error(GL_INVALID_OPERATION);
5471 }
5472 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005473 }
5474 catch(std::bad_alloc&)
5475 {
5476 return error(GL_OUT_OF_MEMORY);
5477 }
5478}
5479
5480void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5481{
5482 GLfloat xyz[3] = {x, y, z};
5483
5484 glUniform3fv(location, 1, (GLfloat*)&xyz);
5485}
5486
5487void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5488{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005489 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005490
5491 try
5492 {
5493 if (count < 0)
5494 {
5495 return error(GL_INVALID_VALUE);
5496 }
5497
5498 if (location == -1)
5499 {
5500 return;
5501 }
5502
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005503 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005504
5505 if (context)
5506 {
5507 gl::Program *program = context->getCurrentProgram();
5508
5509 if (!program)
5510 {
5511 return error(GL_INVALID_OPERATION);
5512 }
5513
5514 if (!program->setUniform3fv(location, count, v))
5515 {
5516 return error(GL_INVALID_OPERATION);
5517 }
5518 }
5519 }
5520 catch(std::bad_alloc&)
5521 {
5522 return error(GL_OUT_OF_MEMORY);
5523 }
5524}
5525
5526void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5527{
5528 GLint xyz[3] = {x, y, z};
5529
5530 glUniform3iv(location, 1, (GLint*)&xyz);
5531}
5532
5533void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5534{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005535 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005536
5537 try
5538 {
5539 if (count < 0)
5540 {
5541 return error(GL_INVALID_VALUE);
5542 }
5543
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005544 if (location == -1)
5545 {
5546 return;
5547 }
5548
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005549 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005550
5551 if (context)
5552 {
5553 gl::Program *program = context->getCurrentProgram();
5554
5555 if (!program)
5556 {
5557 return error(GL_INVALID_OPERATION);
5558 }
5559
5560 if (!program->setUniform3iv(location, count, v))
5561 {
5562 return error(GL_INVALID_OPERATION);
5563 }
5564 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005565 }
5566 catch(std::bad_alloc&)
5567 {
5568 return error(GL_OUT_OF_MEMORY);
5569 }
5570}
5571
5572void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5573{
5574 GLfloat xyzw[4] = {x, y, z, w};
5575
5576 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5577}
5578
5579void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5580{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005581 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005582
5583 try
5584 {
5585 if (count < 0)
5586 {
5587 return error(GL_INVALID_VALUE);
5588 }
5589
5590 if (location == -1)
5591 {
5592 return;
5593 }
5594
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005595 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005596
5597 if (context)
5598 {
5599 gl::Program *program = context->getCurrentProgram();
5600
5601 if (!program)
5602 {
5603 return error(GL_INVALID_OPERATION);
5604 }
5605
5606 if (!program->setUniform4fv(location, count, v))
5607 {
5608 return error(GL_INVALID_OPERATION);
5609 }
5610 }
5611 }
5612 catch(std::bad_alloc&)
5613 {
5614 return error(GL_OUT_OF_MEMORY);
5615 }
5616}
5617
5618void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5619{
5620 GLint xyzw[4] = {x, y, z, w};
5621
5622 glUniform4iv(location, 1, (GLint*)&xyzw);
5623}
5624
5625void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5626{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005627 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005628
5629 try
5630 {
5631 if (count < 0)
5632 {
5633 return error(GL_INVALID_VALUE);
5634 }
5635
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005636 if (location == -1)
5637 {
5638 return;
5639 }
5640
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005641 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005642
5643 if (context)
5644 {
5645 gl::Program *program = context->getCurrentProgram();
5646
5647 if (!program)
5648 {
5649 return error(GL_INVALID_OPERATION);
5650 }
5651
5652 if (!program->setUniform4iv(location, count, v))
5653 {
5654 return error(GL_INVALID_OPERATION);
5655 }
5656 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005657 }
5658 catch(std::bad_alloc&)
5659 {
5660 return error(GL_OUT_OF_MEMORY);
5661 }
5662}
5663
5664void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5665{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005666 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005667 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005668
5669 try
5670 {
5671 if (count < 0 || transpose != GL_FALSE)
5672 {
5673 return error(GL_INVALID_VALUE);
5674 }
5675
5676 if (location == -1)
5677 {
5678 return;
5679 }
5680
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005681 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005682
5683 if (context)
5684 {
5685 gl::Program *program = context->getCurrentProgram();
5686
5687 if (!program)
5688 {
5689 return error(GL_INVALID_OPERATION);
5690 }
5691
5692 if (!program->setUniformMatrix2fv(location, count, value))
5693 {
5694 return error(GL_INVALID_OPERATION);
5695 }
5696 }
5697 }
5698 catch(std::bad_alloc&)
5699 {
5700 return error(GL_OUT_OF_MEMORY);
5701 }
5702}
5703
5704void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5705{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005706 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005707 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005708
5709 try
5710 {
5711 if (count < 0 || transpose != GL_FALSE)
5712 {
5713 return error(GL_INVALID_VALUE);
5714 }
5715
5716 if (location == -1)
5717 {
5718 return;
5719 }
5720
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005721 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005722
5723 if (context)
5724 {
5725 gl::Program *program = context->getCurrentProgram();
5726
5727 if (!program)
5728 {
5729 return error(GL_INVALID_OPERATION);
5730 }
5731
5732 if (!program->setUniformMatrix3fv(location, count, value))
5733 {
5734 return error(GL_INVALID_OPERATION);
5735 }
5736 }
5737 }
5738 catch(std::bad_alloc&)
5739 {
5740 return error(GL_OUT_OF_MEMORY);
5741 }
5742}
5743
5744void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5745{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005746 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005747 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005748
5749 try
5750 {
5751 if (count < 0 || transpose != GL_FALSE)
5752 {
5753 return error(GL_INVALID_VALUE);
5754 }
5755
5756 if (location == -1)
5757 {
5758 return;
5759 }
5760
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005761 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005762
5763 if (context)
5764 {
5765 gl::Program *program = context->getCurrentProgram();
5766
5767 if (!program)
5768 {
5769 return error(GL_INVALID_OPERATION);
5770 }
5771
5772 if (!program->setUniformMatrix4fv(location, count, value))
5773 {
5774 return error(GL_INVALID_OPERATION);
5775 }
5776 }
5777 }
5778 catch(std::bad_alloc&)
5779 {
5780 return error(GL_OUT_OF_MEMORY);
5781 }
5782}
5783
5784void __stdcall glUseProgram(GLuint program)
5785{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005786 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005787
5788 try
5789 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005790 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005791
5792 if (context)
5793 {
5794 gl::Program *programObject = context->getProgram(program);
5795
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005796 if (!programObject && program != 0)
5797 {
5798 if (context->getShader(program))
5799 {
5800 return error(GL_INVALID_OPERATION);
5801 }
5802 else
5803 {
5804 return error(GL_INVALID_VALUE);
5805 }
5806 }
5807
5808 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005809 {
5810 return error(GL_INVALID_OPERATION);
5811 }
5812
5813 context->useProgram(program);
5814 }
5815 }
5816 catch(std::bad_alloc&)
5817 {
5818 return error(GL_OUT_OF_MEMORY);
5819 }
5820}
5821
5822void __stdcall glValidateProgram(GLuint program)
5823{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005824 EVENT("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005825
5826 try
5827 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005828 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005829
5830 if (context)
5831 {
5832 gl::Program *programObject = context->getProgram(program);
5833
5834 if (!programObject)
5835 {
5836 if (context->getShader(program))
5837 {
5838 return error(GL_INVALID_OPERATION);
5839 }
5840 else
5841 {
5842 return error(GL_INVALID_VALUE);
5843 }
5844 }
5845
5846 programObject->validate();
5847 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005848 }
5849 catch(std::bad_alloc&)
5850 {
5851 return error(GL_OUT_OF_MEMORY);
5852 }
5853}
5854
5855void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5856{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005857 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005858
5859 try
5860 {
5861 if (index >= gl::MAX_VERTEX_ATTRIBS)
5862 {
5863 return error(GL_INVALID_VALUE);
5864 }
5865
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005866 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005867
5868 if (context)
5869 {
5870 GLfloat vals[4] = { x, 0, 0, 1 };
5871 context->setVertexAttrib(index, vals);
5872 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005873 }
5874 catch(std::bad_alloc&)
5875 {
5876 return error(GL_OUT_OF_MEMORY);
5877 }
5878}
5879
5880void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5881{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005882 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005883
5884 try
5885 {
5886 if (index >= gl::MAX_VERTEX_ATTRIBS)
5887 {
5888 return error(GL_INVALID_VALUE);
5889 }
5890
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005891 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005892
5893 if (context)
5894 {
5895 GLfloat vals[4] = { values[0], 0, 0, 1 };
5896 context->setVertexAttrib(index, vals);
5897 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005898 }
5899 catch(std::bad_alloc&)
5900 {
5901 return error(GL_OUT_OF_MEMORY);
5902 }
5903}
5904
5905void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5906{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005907 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005908
5909 try
5910 {
5911 if (index >= gl::MAX_VERTEX_ATTRIBS)
5912 {
5913 return error(GL_INVALID_VALUE);
5914 }
5915
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005916 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005917
5918 if (context)
5919 {
5920 GLfloat vals[4] = { x, y, 0, 1 };
5921 context->setVertexAttrib(index, vals);
5922 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005923 }
5924 catch(std::bad_alloc&)
5925 {
5926 return error(GL_OUT_OF_MEMORY);
5927 }
5928}
5929
5930void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5931{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005932 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005933
5934 try
5935 {
5936 if (index >= gl::MAX_VERTEX_ATTRIBS)
5937 {
5938 return error(GL_INVALID_VALUE);
5939 }
5940
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005941 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005942
5943 if (context)
5944 {
5945 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5946 context->setVertexAttrib(index, vals);
5947 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005948 }
5949 catch(std::bad_alloc&)
5950 {
5951 return error(GL_OUT_OF_MEMORY);
5952 }
5953}
5954
5955void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5956{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005957 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 +00005958
5959 try
5960 {
5961 if (index >= gl::MAX_VERTEX_ATTRIBS)
5962 {
5963 return error(GL_INVALID_VALUE);
5964 }
5965
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005966 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005967
5968 if (context)
5969 {
5970 GLfloat vals[4] = { x, y, z, 1 };
5971 context->setVertexAttrib(index, vals);
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
5980void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5981{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00005982 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005983
5984 try
5985 {
5986 if (index >= gl::MAX_VERTEX_ATTRIBS)
5987 {
5988 return error(GL_INVALID_VALUE);
5989 }
5990
daniel@transgaming.com9d788502011-11-09 17:46:55 +00005991 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005992
5993 if (context)
5994 {
5995 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5996 context->setVertexAttrib(index, vals);
5997 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005998 }
5999 catch(std::bad_alloc&)
6000 {
6001 return error(GL_OUT_OF_MEMORY);
6002 }
6003}
6004
6005void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6006{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006007 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 +00006008
6009 try
6010 {
6011 if (index >= gl::MAX_VERTEX_ATTRIBS)
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.come4b08c82010-04-20 18:53:06 +00006017
6018 if (context)
6019 {
6020 GLfloat vals[4] = { x, y, z, w };
6021 context->setVertexAttrib(index, vals);
6022 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006023 }
6024 catch(std::bad_alloc&)
6025 {
6026 return error(GL_OUT_OF_MEMORY);
6027 }
6028}
6029
6030void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
6031{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006032 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006033
6034 try
6035 {
6036 if (index >= gl::MAX_VERTEX_ATTRIBS)
6037 {
6038 return error(GL_INVALID_VALUE);
6039 }
6040
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006041 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00006042
6043 if (context)
6044 {
6045 context->setVertexAttrib(index, values);
6046 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006047 }
6048 catch(std::bad_alloc&)
6049 {
6050 return error(GL_OUT_OF_MEMORY);
6051 }
6052}
6053
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006054void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006055{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006056 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006057 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006058 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006059
6060 try
6061 {
6062 if (index >= gl::MAX_VERTEX_ATTRIBS)
6063 {
6064 return error(GL_INVALID_VALUE);
6065 }
6066
6067 if (size < 1 || size > 4)
6068 {
6069 return error(GL_INVALID_VALUE);
6070 }
6071
6072 switch (type)
6073 {
6074 case GL_BYTE:
6075 case GL_UNSIGNED_BYTE:
6076 case GL_SHORT:
6077 case GL_UNSIGNED_SHORT:
6078 case GL_FIXED:
6079 case GL_FLOAT:
6080 break;
6081 default:
6082 return error(GL_INVALID_ENUM);
6083 }
6084
6085 if (stride < 0)
6086 {
6087 return error(GL_INVALID_VALUE);
6088 }
6089
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006090 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006091
6092 if (context)
6093 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00006094 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006095 }
6096 }
6097 catch(std::bad_alloc&)
6098 {
6099 return error(GL_OUT_OF_MEMORY);
6100 }
6101}
6102
6103void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
6104{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006105 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 +00006106
6107 try
6108 {
6109 if (width < 0 || height < 0)
6110 {
6111 return error(GL_INVALID_VALUE);
6112 }
6113
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006114 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006115
6116 if (context)
6117 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00006118 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006119 }
6120 }
6121 catch(std::bad_alloc&)
6122 {
6123 return error(GL_OUT_OF_MEMORY);
6124 }
6125}
6126
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006127void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6128 GLbitfield mask, GLenum filter)
6129{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006130 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006131 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6132 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6133 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6134
6135 try
6136 {
6137 switch (filter)
6138 {
6139 case GL_NEAREST:
6140 break;
6141 default:
6142 return error(GL_INVALID_ENUM);
6143 }
6144
6145 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6146 {
6147 return error(GL_INVALID_VALUE);
6148 }
6149
6150 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6151 {
6152 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6153 return error(GL_INVALID_OPERATION);
6154 }
6155
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006156 gl::Context *context = gl::getNonLostContext();
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00006157
6158 if (context)
6159 {
6160 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
6161 {
6162 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6163 return error(GL_INVALID_OPERATION);
6164 }
6165
6166 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6167 }
6168 }
6169 catch(std::bad_alloc&)
6170 {
6171 return error(GL_OUT_OF_MEMORY);
6172 }
6173}
6174
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006175void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6176 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006177{
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +00006178 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00006179 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00006180 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006181 target, level, internalformat, width, height, depth, border, format, type, pixels);
6182
6183 try
6184 {
6185 UNIMPLEMENTED(); // FIXME
6186 }
6187 catch(std::bad_alloc&)
6188 {
6189 return error(GL_OUT_OF_MEMORY);
6190 }
6191}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006192
6193__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
6194{
6195 struct Extension
6196 {
6197 const char *name;
6198 __eglMustCastToProperFunctionPointerType address;
6199 };
6200
6201 static const Extension glExtensions[] =
6202 {
6203 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00006204 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.com1fe96c92011-01-14 15:08:44 +00006205 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00006206 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
6207 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
6208 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
6209 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
6210 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
6211 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
6212 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
zmo@google.coma574f782011-10-03 21:45:23 +00006213 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
daniel@transgaming.com0bd1f2f2011-11-11 04:19:03 +00006214 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
daniel@transgaming.com709ed112011-11-12 03:18:10 +00006215 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
6216 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
6217 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
6218 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00006219 };
6220
6221 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6222 {
6223 if (strcmp(procname, glExtensions[ext].name) == 0)
6224 {
6225 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6226 }
6227 }
6228
6229 return NULL;
6230}
6231
daniel@transgaming.com17f548c2011-11-09 17:47:02 +00006232// Non-public functions used by EGL
6233
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006234bool __stdcall glBindTexImage(egl::Surface *surface)
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006235{
6236 EVENT("(egl::Surface* surface = 0x%0.8p)",
6237 surface);
6238
6239 try
6240 {
daniel@transgaming.com9d788502011-11-09 17:46:55 +00006241 gl::Context *context = gl::getNonLostContext();
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006242
6243 if (context)
6244 {
6245 gl::Texture2D *textureObject = context->getTexture2D();
6246
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006247 if (textureObject->isImmutable())
6248 {
6249 return false;
6250 }
6251
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006252 if (textureObject)
6253 {
6254 textureObject->bindTexImage(surface);
6255 }
6256 }
6257 }
6258 catch(std::bad_alloc&)
6259 {
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006260 return error(GL_OUT_OF_MEMORY, false);
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006261 }
daniel@transgaming.com64a0fb22011-11-11 04:10:40 +00006262
6263 return true;
jbauman@chromium.orgae345802011-03-30 22:04:25 +00006264}
6265
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00006266}