OSDN Git Service

0e6c92acef5abd4847ad9dacfea36ba3b18934e5
[android-x86/external-swiftshader.git] / src / Radiance / libRAD / libRAD.cpp
1 // SwiftShader Software Renderer\r
2 //\r
3 // Copyright(c) 2005-2013 TransGaming Inc.\r
4 //\r
5 // All rights reserved. No part of this software may be copied, distributed, transmitted,\r
6 // transcribed, stored in a retrieval system, translated into any human or computer\r
7 // language by any means, or disclosed to third parties without the explicit written\r
8 // agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express\r
9 // or implied, including but not limited to any patent rights, are granted to you.\r
10 //\r
11 // libRAD.cpp: Implements the exported OpenGL ES 2.0 functions.\r
12 \r
13 #include "main.h"\r
14 #include "mathutil.h"\r
15 #include "utilities.h"\r
16 #include "Buffer.h"\r
17 #include "Context.h"\r
18 #include "Fence.h"\r
19 #include "Framebuffer.h"\r
20 #include "Program.h"\r
21 #include "Renderbuffer.h"\r
22 #include "Shader.h"\r
23 #include "Texture.h"\r
24 #include "Query.h"\r
25 #include "common/debug.h"\r
26 #include "Common/Version.h"\r
27 #include "Main/Register.hpp"\r
28 \r
29 #define GL_APICALL\r
30 #include <GLES2/gl2.h>\r
31 #include <GLES2/gl2ext.h>\r
32 #include <RAD/rad.h>\r
33 \r
34 #include <exception>\r
35 #include <limits>\r
36 \r
37 static bool validImageSize(GLint level, GLsizei width, GLsizei height)\r
38 {\r
39     if(level < 0 || level >= rad::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)\r
40     {\r
41         return false;\r
42     }\r
43 \r
44     return true;\r
45 }\r
46 \r
47 static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, rad::Texture *texture)\r
48 {\r
49     if(!texture)\r
50     {\r
51         return error(GL_INVALID_OPERATION, false);\r
52     }\r
53 \r
54     if(compressed != texture->isCompressed(target, level))\r
55     {\r
56         return error(GL_INVALID_OPERATION, false);\r
57     }\r
58 \r
59     if(format != GL_NONE && format != texture->getFormat(target, level))\r
60     {\r
61         return error(GL_INVALID_OPERATION, false);\r
62     }\r
63 \r
64     if(compressed)\r
65     {\r
66         if((width % 4 != 0 && width != texture->getWidth(target, 0)) || \r
67            (height % 4 != 0 && height != texture->getHeight(target, 0)))\r
68         {\r
69             return error(GL_INVALID_OPERATION, false);\r
70         }\r
71     }\r
72 \r
73     if(xoffset + width > texture->getWidth(target, level) ||\r
74        yoffset + height > texture->getHeight(target, level))\r
75     {\r
76         return error(GL_INVALID_VALUE, false);\r
77     }\r
78 \r
79     return true;\r
80 }\r
81 \r
82 // Check for combinations of format and type that are valid for ReadPixels\r
83 static bool validReadFormatType(GLenum format, GLenum type)\r
84 {\r
85     switch(format)\r
86     {\r
87     case GL_RGBA:\r
88         switch (type)\r
89         {\r
90         case GL_UNSIGNED_BYTE:\r
91             break;\r
92         default:\r
93             return false;\r
94         }\r
95         break;\r
96     case GL_BGRA_EXT:\r
97         switch (type)\r
98         {\r
99         case GL_UNSIGNED_BYTE:\r
100         case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:\r
101         case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:\r
102             break;\r
103         default:\r
104             return false;\r
105         }\r
106         break;\r
107     case rad::IMPLEMENTATION_COLOR_READ_FORMAT:\r
108         switch (type)\r
109         {\r
110         case rad::IMPLEMENTATION_COLOR_READ_TYPE:\r
111             break;\r
112         default:\r
113             return false;\r
114         }\r
115         break;\r
116     default:\r
117         return false;\r
118     }\r
119 \r
120     return true;\r
121 }\r
122 \r
123 extern "C"\r
124 {\r
125 \r
126 void GL_APIENTRY glActiveTexture(GLenum texture)\r
127 {\r
128     TRACE("(GLenum texture = 0x%X)", texture);\r
129 \r
130     try\r
131     {\r
132         rad::Context *context = rad::getContext();\r
133 \r
134         if(context)\r
135         {\r
136             if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + rad::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)\r
137             {\r
138                 return error(GL_INVALID_ENUM);\r
139             }\r
140 \r
141             context->setActiveSampler(texture - GL_TEXTURE0);\r
142         }\r
143     }\r
144     catch(std::bad_alloc&)\r
145     {\r
146         return error(GL_OUT_OF_MEMORY);\r
147     }\r
148 }\r
149 \r
150 void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)\r
151 {\r
152     TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);\r
153 \r
154     try\r
155     {\r
156         rad::Context *context = rad::getContext();\r
157 \r
158         if(context)\r
159         {\r
160             rad::Program *programObject = context->getProgram(program);\r
161             rad::Shader *shaderObject = context->getShader(shader);\r
162 \r
163             if(!programObject)\r
164             {\r
165                 if(context->getShader(program))\r
166                 {\r
167                     return error(GL_INVALID_OPERATION);\r
168                 }\r
169                 else\r
170                 {\r
171                     return error(GL_INVALID_VALUE);\r
172                 }\r
173             }\r
174 \r
175             if(!shaderObject)\r
176             {\r
177                 if(context->getProgram(shader))\r
178                 {\r
179                     return error(GL_INVALID_OPERATION);\r
180                 }\r
181                 else\r
182                 {\r
183                     return error(GL_INVALID_VALUE);\r
184                 }\r
185             }\r
186 \r
187             if(!programObject->attachShader(shaderObject))\r
188             {\r
189                 return error(GL_INVALID_OPERATION);\r
190             }\r
191         }\r
192     }\r
193     catch(std::bad_alloc&)\r
194     {\r
195         return error(GL_OUT_OF_MEMORY);\r
196     }\r
197 }\r
198 \r
199 void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint id)\r
200 {\r
201     TRACE("(GLenum target = 0x%X, GLuint %d)", target, id);\r
202 \r
203     try\r
204     {\r
205         switch(target)\r
206         {\r
207         case GL_ANY_SAMPLES_PASSED_EXT: \r
208         case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:\r
209             break;\r
210         default: \r
211             return error(GL_INVALID_ENUM);\r
212         }\r
213 \r
214         if(id == 0)\r
215         {\r
216             return error(GL_INVALID_OPERATION);\r
217         }\r
218 \r
219         rad::Context *context = rad::getContext();\r
220 \r
221         if(context)\r
222         {\r
223             context->beginQuery(target, id);\r
224         }\r
225     }\r
226     catch(std::bad_alloc&)\r
227     {\r
228         return error(GL_OUT_OF_MEMORY);\r
229     }\r
230 }\r
231 \r
232 void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)\r
233 {\r
234     TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);\r
235 \r
236     try\r
237     {\r
238         if(index >= rad::MAX_VERTEX_ATTRIBS)\r
239         {\r
240             return error(GL_INVALID_VALUE);\r
241         }\r
242 \r
243         rad::Context *context = rad::getContext();\r
244 \r
245         if(context)\r
246         {\r
247             rad::Program *programObject = context->getProgram(program);\r
248 \r
249             if(!programObject)\r
250             {\r
251                 if(context->getShader(program))\r
252                 {\r
253                     return error(GL_INVALID_OPERATION);\r
254                 }\r
255                 else\r
256                 {\r
257                     return error(GL_INVALID_VALUE);\r
258                 }\r
259             }\r
260 \r
261             if(strncmp(name, "gl_", 3) == 0)\r
262             {\r
263                 return error(GL_INVALID_OPERATION);\r
264             }\r
265 \r
266             programObject->bindAttributeLocation(index, name);\r
267         }\r
268     }\r
269     catch(std::bad_alloc&)\r
270     {\r
271         return error(GL_OUT_OF_MEMORY);\r
272     }\r
273 }\r
274 \r
275 void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)\r
276 {\r
277     TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);\r
278 \r
279     try\r
280     {\r
281         rad::Context *context = rad::getContext();\r
282 \r
283         if(context)\r
284         {\r
285             switch(target)\r
286             {\r
287               case GL_ARRAY_BUFFER:\r
288                 context->bindArrayBuffer(buffer);\r
289                 return;\r
290               case GL_ELEMENT_ARRAY_BUFFER:\r
291                 context->bindElementArrayBuffer(buffer);\r
292                 return;\r
293               default:\r
294                 return error(GL_INVALID_ENUM);\r
295             }\r
296         }\r
297     }\r
298     catch(std::bad_alloc&)\r
299     {\r
300         return error(GL_OUT_OF_MEMORY);\r
301     }\r
302 }\r
303 \r
304 void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)\r
305 {\r
306     TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);\r
307 \r
308     try\r
309     {\r
310         if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)\r
311         {\r
312             return error(GL_INVALID_ENUM);\r
313         }\r
314 \r
315         rad::Context *context = rad::getContext();\r
316 \r
317         if(context)\r
318         {\r
319             if(target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)\r
320             {\r
321                 context->bindReadFramebuffer(framebuffer);\r
322             }\r
323             \r
324             if(target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)\r
325             {\r
326                 context->bindDrawFramebuffer(framebuffer);\r
327             }\r
328         }\r
329     }\r
330     catch(std::bad_alloc&)\r
331     {\r
332         return error(GL_OUT_OF_MEMORY);\r
333     }\r
334 }\r
335 \r
336 void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)\r
337 {\r
338     TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);\r
339 \r
340     try\r
341     {\r
342         if(target != GL_RENDERBUFFER)\r
343         {\r
344             return error(GL_INVALID_ENUM);\r
345         }\r
346 \r
347         rad::Context *context = rad::getContext();\r
348 \r
349         if(context)\r
350         {\r
351                         if (renderbuffer != 0 && !context->getRenderbuffer(renderbuffer))
352                         {
353                                 // [OpenGL ES 2.0.25] Section 4.4.3 page 112\r
354                                 // [OpenGL ES 3.0.2] Section 4.4.2 page 201\r
355                                 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of\r
356                                 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.\r
357                                 return error(GL_INVALID_OPERATION);
358                         }\r
359 \r
360             context->bindRenderbuffer(renderbuffer);\r
361         }\r
362     }\r
363     catch(std::bad_alloc&)\r
364     {\r
365         return error(GL_OUT_OF_MEMORY);\r
366     }\r
367 }\r
368 \r
369 void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)\r
370 {\r
371     TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);\r
372 \r
373     try\r
374     {\r
375         rad::Context *context = rad::getContext();\r
376 \r
377         if(context)\r
378         {\r
379             rad::Texture *textureObject = context->getTexture(texture);\r
380 \r
381             if(textureObject && textureObject->getTarget() != target && texture != 0)\r
382             {\r
383                 return error(GL_INVALID_OPERATION);\r
384             }\r
385 \r
386             switch(target)\r
387             {\r
388             case GL_TEXTURE_2D:\r
389                 context->bindTexture2D(texture);\r
390                 return;\r
391             case GL_TEXTURE_CUBE_MAP:\r
392                 context->bindTextureCubeMap(texture);\r
393                 return;\r
394             case GL_TEXTURE_EXTERNAL_OES:\r
395                 context->bindTextureExternal(texture);\r
396                 return;\r
397             default:\r
398                 return error(GL_INVALID_ENUM);\r
399             }\r
400         }\r
401     }\r
402     catch(std::bad_alloc&)\r
403     {\r
404         return error(GL_OUT_OF_MEMORY);\r
405     }\r
406 }\r
407 \r
408 void GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)\r
409 {\r
410     TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",\r
411           red, green, blue, alpha);\r
412 \r
413     try\r
414     {\r
415         rad::Context* context = rad::getContext();\r
416 \r
417         if(context)\r
418         {\r
419             context->setBlendColor(rad::clamp01(red), rad::clamp01(green), rad::clamp01(blue), rad::clamp01(alpha));\r
420         }\r
421     }\r
422     catch(std::bad_alloc&)\r
423     {\r
424         return error(GL_OUT_OF_MEMORY);\r
425     }\r
426 }\r
427 \r
428 void GL_APIENTRY glBlendEquation(GLenum mode)\r
429 {\r
430     glBlendEquationSeparate(mode, mode);\r
431 }\r
432 \r
433 void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)\r
434 {\r
435     TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);\r
436 \r
437     try\r
438     {\r
439         switch(modeRGB)\r
440         {\r
441         case GL_FUNC_ADD:\r
442         case GL_FUNC_SUBTRACT:\r
443         case GL_FUNC_REVERSE_SUBTRACT:\r
444         case GL_MIN_EXT:\r
445         case GL_MAX_EXT:\r
446             break;\r
447         default:\r
448             return error(GL_INVALID_ENUM);\r
449         }\r
450 \r
451         switch(modeAlpha)\r
452         {\r
453         case GL_FUNC_ADD:\r
454         case GL_FUNC_SUBTRACT:\r
455         case GL_FUNC_REVERSE_SUBTRACT:\r
456         case GL_MIN_EXT:\r
457         case GL_MAX_EXT:\r
458             break;\r
459         default:\r
460             return error(GL_INVALID_ENUM);\r
461         }\r
462 \r
463         rad::Context *context = rad::getContext();\r
464 \r
465         if(context)\r
466         {\r
467             context->setBlendEquation(modeRGB, modeAlpha);\r
468         }\r
469     }\r
470     catch(std::bad_alloc&)\r
471     {\r
472         return error(GL_OUT_OF_MEMORY);\r
473     }\r
474 }\r
475 \r
476 void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)\r
477 {\r
478     glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);\r
479 }\r
480 \r
481 void GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)\r
482 {\r
483     TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",\r
484           srcRGB, dstRGB, srcAlpha, dstAlpha);\r
485 \r
486     try\r
487     {\r
488         switch(srcRGB)\r
489         {\r
490           case GL_ZERO:\r
491           case GL_ONE:\r
492           case GL_SRC_COLOR:\r
493           case GL_ONE_MINUS_SRC_COLOR:\r
494           case GL_DST_COLOR:\r
495           case GL_ONE_MINUS_DST_COLOR:\r
496           case GL_SRC_ALPHA:\r
497           case GL_ONE_MINUS_SRC_ALPHA:\r
498           case GL_DST_ALPHA:\r
499           case GL_ONE_MINUS_DST_ALPHA:\r
500           case GL_CONSTANT_COLOR:\r
501           case GL_ONE_MINUS_CONSTANT_COLOR:\r
502           case GL_CONSTANT_ALPHA:\r
503           case GL_ONE_MINUS_CONSTANT_ALPHA:\r
504           case GL_SRC_ALPHA_SATURATE:\r
505             break;\r
506           default:\r
507             return error(GL_INVALID_ENUM);\r
508         }\r
509 \r
510         switch(dstRGB)\r
511         {\r
512           case GL_ZERO:\r
513           case GL_ONE:\r
514           case GL_SRC_COLOR:\r
515           case GL_ONE_MINUS_SRC_COLOR:\r
516           case GL_DST_COLOR:\r
517           case GL_ONE_MINUS_DST_COLOR:\r
518           case GL_SRC_ALPHA:\r
519           case GL_ONE_MINUS_SRC_ALPHA:\r
520           case GL_DST_ALPHA:\r
521           case GL_ONE_MINUS_DST_ALPHA:\r
522           case GL_CONSTANT_COLOR:\r
523           case GL_ONE_MINUS_CONSTANT_COLOR:\r
524           case GL_CONSTANT_ALPHA:\r
525           case GL_ONE_MINUS_CONSTANT_ALPHA:\r
526             break;\r
527           default:\r
528             return error(GL_INVALID_ENUM);\r
529         }\r
530 \r
531         switch(srcAlpha)\r
532         {\r
533           case GL_ZERO:\r
534           case GL_ONE:\r
535           case GL_SRC_COLOR:\r
536           case GL_ONE_MINUS_SRC_COLOR:\r
537           case GL_DST_COLOR:\r
538           case GL_ONE_MINUS_DST_COLOR:\r
539           case GL_SRC_ALPHA:\r
540           case GL_ONE_MINUS_SRC_ALPHA:\r
541           case GL_DST_ALPHA:\r
542           case GL_ONE_MINUS_DST_ALPHA:\r
543           case GL_CONSTANT_COLOR:\r
544           case GL_ONE_MINUS_CONSTANT_COLOR:\r
545           case GL_CONSTANT_ALPHA:\r
546           case GL_ONE_MINUS_CONSTANT_ALPHA:\r
547           case GL_SRC_ALPHA_SATURATE:\r
548             break;\r
549           default:\r
550             return error(GL_INVALID_ENUM);\r
551         }\r
552 \r
553         switch(dstAlpha)\r
554         {\r
555           case GL_ZERO:\r
556           case GL_ONE:\r
557           case GL_SRC_COLOR:\r
558           case GL_ONE_MINUS_SRC_COLOR:\r
559           case GL_DST_COLOR:\r
560           case GL_ONE_MINUS_DST_COLOR:\r
561           case GL_SRC_ALPHA:\r
562           case GL_ONE_MINUS_SRC_ALPHA:\r
563           case GL_DST_ALPHA:\r
564           case GL_ONE_MINUS_DST_ALPHA:\r
565           case GL_CONSTANT_COLOR:\r
566           case GL_ONE_MINUS_CONSTANT_COLOR:\r
567           case GL_CONSTANT_ALPHA:\r
568           case GL_ONE_MINUS_CONSTANT_ALPHA:\r
569             break;\r
570           default:\r
571             return error(GL_INVALID_ENUM);\r
572         }\r
573 \r
574         rad::Context *context = rad::getContext();\r
575 \r
576         if(context)\r
577         {\r
578             context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);\r
579         }\r
580     }\r
581     catch(std::bad_alloc&)\r
582     {\r
583         return error(GL_OUT_OF_MEMORY);\r
584     }\r
585 }\r
586 \r
587 void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)\r
588 {\r
589     TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",\r
590           target, size, data, usage);\r
591 \r
592     try\r
593     {\r
594         if(size < 0)\r
595         {\r
596             return error(GL_INVALID_VALUE);\r
597         }\r
598 \r
599         switch(usage)\r
600         {\r
601           case GL_STREAM_DRAW:\r
602           case GL_STATIC_DRAW:\r
603           case GL_DYNAMIC_DRAW:\r
604             break;\r
605           default:\r
606             return error(GL_INVALID_ENUM);\r
607         }\r
608 \r
609         rad::Context *context = rad::getContext();\r
610 \r
611         if(context)\r
612         {\r
613             rad::Buffer *buffer;\r
614 \r
615             switch(target)\r
616             {\r
617               case GL_ARRAY_BUFFER:\r
618                 buffer = context->getArrayBuffer();\r
619                 break;\r
620               case GL_ELEMENT_ARRAY_BUFFER:\r
621                 buffer = context->getElementArrayBuffer();\r
622                 break;\r
623               default:\r
624                 return error(GL_INVALID_ENUM);\r
625             }\r
626 \r
627             if(!buffer)\r
628             {\r
629                 return error(GL_INVALID_OPERATION);\r
630             }\r
631 \r
632             buffer->bufferData(data, size, usage);\r
633         }\r
634     }\r
635     catch(std::bad_alloc&)\r
636     {\r
637         return error(GL_OUT_OF_MEMORY);\r
638     }\r
639 }\r
640 \r
641 void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)\r
642 {\r
643     TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",\r
644           target, offset, size, data);\r
645 \r
646     try\r
647     {\r
648         if(size < 0 || offset < 0)\r
649         {\r
650             return error(GL_INVALID_VALUE);\r
651         }\r
652 \r
653         if(data == NULL)\r
654         {\r
655             return;\r
656         }\r
657 \r
658         rad::Context *context = rad::getContext();\r
659 \r
660         if(context)\r
661         {\r
662             rad::Buffer *buffer;\r
663 \r
664             switch(target)\r
665             {\r
666               case GL_ARRAY_BUFFER:\r
667                 buffer = context->getArrayBuffer();\r
668                 break;\r
669               case GL_ELEMENT_ARRAY_BUFFER:\r
670                 buffer = context->getElementArrayBuffer();\r
671                 break;\r
672               default:\r
673                 return error(GL_INVALID_ENUM);\r
674             }\r
675 \r
676             if(!buffer)\r
677             {\r
678                 return error(GL_INVALID_OPERATION);\r
679             }\r
680 \r
681             if((size_t)size + offset > buffer->size())\r
682             {\r
683                 return error(GL_INVALID_VALUE);\r
684             }\r
685 \r
686             buffer->bufferSubData(data, size, offset);\r
687         }\r
688     }\r
689     catch(std::bad_alloc&)\r
690     {\r
691         return error(GL_OUT_OF_MEMORY);\r
692     }\r
693 }\r
694 \r
695 GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)\r
696 {\r
697     TRACE("(GLenum target = 0x%X)", target);\r
698 \r
699     try\r
700     {\r
701         if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)\r
702         {\r
703             return error(GL_INVALID_ENUM, 0);\r
704         }\r
705 \r
706         rad::Context *context = rad::getContext();\r
707 \r
708         if(context)\r
709         {\r
710             rad::Framebuffer *framebuffer = NULL;\r
711             if(target == GL_READ_FRAMEBUFFER_ANGLE)\r
712             {\r
713                 framebuffer = context->getReadFramebuffer();\r
714             }\r
715             else\r
716             {\r
717                 framebuffer = context->getDrawFramebuffer();\r
718             }\r
719 \r
720             return framebuffer->completeness();\r
721         }\r
722     }\r
723     catch(std::bad_alloc&)\r
724     {\r
725         return error(GL_OUT_OF_MEMORY, 0);\r
726     }\r
727 \r
728     return 0;\r
729 }\r
730 \r
731 void GL_APIENTRY glClear(GLbitfield mask)\r
732 {\r
733     TRACE("(GLbitfield mask = %X)", mask);\r
734 \r
735     try\r
736     {\r
737                 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)\r
738                 {\r
739                         return error(GL_INVALID_VALUE);\r
740                 }\r
741 \r
742         rad::Context *context = rad::getContext();\r
743 \r
744         if(context)\r
745         {\r
746             context->clear(mask);\r
747         }\r
748     }\r
749     catch(std::bad_alloc&)\r
750     {\r
751         return error(GL_OUT_OF_MEMORY);\r
752     }\r
753 }\r
754 \r
755 void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)\r
756 {\r
757     TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",\r
758           red, green, blue, alpha);\r
759 \r
760     try\r
761     {\r
762         rad::Context *context = rad::getContext();\r
763 \r
764         if(context)\r
765         {\r
766             context->setClearColor(red, green, blue, alpha);\r
767         }\r
768     }\r
769     catch(std::bad_alloc&)\r
770     {\r
771         return error(GL_OUT_OF_MEMORY);\r
772     }\r
773 }\r
774 \r
775 void GL_APIENTRY glClearDepthf(GLclampf depth)\r
776 {\r
777     TRACE("(GLclampf depth = %f)", depth);\r
778 \r
779     try\r
780     {\r
781         rad::Context *context = rad::getContext();\r
782 \r
783         if(context)\r
784         {\r
785             context->setClearDepth(depth);\r
786         }\r
787     }\r
788     catch(std::bad_alloc&)\r
789     {\r
790         return error(GL_OUT_OF_MEMORY);\r
791     }\r
792 }\r
793 \r
794 void GL_APIENTRY glClearStencil(GLint s)\r
795 {\r
796     TRACE("(GLint s = %d)", s);\r
797 \r
798     try\r
799     {\r
800         rad::Context *context = rad::getContext();\r
801 \r
802         if(context)\r
803         {\r
804             context->setClearStencil(s);\r
805         }\r
806     }\r
807     catch(std::bad_alloc&)\r
808     {\r
809         return error(GL_OUT_OF_MEMORY);\r
810     }\r
811 }\r
812 \r
813 void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)\r
814 {\r
815     TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",\r
816           red, green, blue, alpha);\r
817 \r
818     try\r
819     {\r
820         rad::Context *context = rad::getContext();\r
821 \r
822         if(context)\r
823         {\r
824             context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);\r
825         }\r
826     }\r
827     catch(std::bad_alloc&)\r
828     {\r
829         return error(GL_OUT_OF_MEMORY);\r
830     }\r
831 }\r
832 \r
833 void GL_APIENTRY glCompileShader(GLuint shader)\r
834 {\r
835     TRACE("(GLuint shader = %d)", shader);\r
836 \r
837     try\r
838     {\r
839         rad::Context *context = rad::getContext();\r
840 \r
841         if(context)\r
842         {\r
843             rad::Shader *shaderObject = context->getShader(shader);\r
844 \r
845             if(!shaderObject)\r
846             {\r
847                 if(context->getProgram(shader))\r
848                 {\r
849                     return error(GL_INVALID_OPERATION);\r
850                 }\r
851                 else\r
852                 {\r
853                     return error(GL_INVALID_VALUE);\r
854                 }\r
855             }\r
856 \r
857             shaderObject->compile();\r
858         }\r
859     }\r
860     catch(std::bad_alloc&)\r
861     {\r
862         return error(GL_OUT_OF_MEMORY);\r
863     }\r
864 }\r
865 \r
866 void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, \r
867                                         GLint border, GLsizei imageSize, const GLvoid* data)\r
868 {\r
869     TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " \r
870           "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",\r
871           target, level, internalformat, width, height, border, imageSize, data);\r
872 \r
873     try\r
874     {\r
875         if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)\r
876         {\r
877             return error(GL_INVALID_VALUE);\r
878         }\r
879 \r
880         switch(internalformat)\r
881         {\r
882         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:\r
883         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:\r
884                 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:\r
885                 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:\r
886                         if(!S3TC_SUPPORT)\r
887             {\r
888                 return error(GL_INVALID_ENUM);\r
889             }\r
890             break;\r
891                 case GL_DEPTH_COMPONENT:\r
892                 case GL_DEPTH_COMPONENT16:\r
893                 case GL_DEPTH_COMPONENT32_OES:\r
894                 case GL_DEPTH_STENCIL_OES:\r
895                 case GL_DEPTH24_STENCIL8_OES:\r
896                         return error(GL_INVALID_OPERATION);\r
897         default:\r
898             return error(GL_INVALID_ENUM);\r
899         }\r
900 \r
901         if(border != 0)\r
902         {\r
903             return error(GL_INVALID_VALUE);\r
904         }\r
905 \r
906         rad::Context *context = rad::getContext();\r
907 \r
908         if(context)\r
909         {\r
910                         if(level > rad::IMPLEMENTATION_MAX_TEXTURE_LEVELS)\r
911             {\r
912                 return error(GL_INVALID_VALUE);\r
913             }\r
914 \r
915             switch(target)\r
916             {\r
917               case GL_TEXTURE_2D:\r
918                 if(width > (rad::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||\r
919                     height > (rad::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))\r
920                 {\r
921                     return error(GL_INVALID_VALUE);\r
922                 }\r
923                 break;\r
924               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:\r
925               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:\r
926               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:\r
927               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:\r
928               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:\r
929               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:\r
930                 if(width != height)\r
931                 {\r
932                     return error(GL_INVALID_VALUE);\r
933                 }\r
934 \r
935                 if(width > (rad::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||\r
936                    height > (rad::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))\r
937                 {\r
938                     return error(GL_INVALID_VALUE);\r
939                 }\r
940                 break;\r
941               default:\r
942                 return error(GL_INVALID_ENUM);\r
943             }\r
944 \r
945             if(imageSize != rad::ComputeCompressedSize(width, height, internalformat))\r
946             {\r
947                 return error(GL_INVALID_VALUE);\r
948             }\r
949 \r
950             if(target == GL_TEXTURE_2D)\r
951             {\r
952                 rad::Texture2D *texture = context->getTexture2D();\r
953 \r
954                 if(!texture)\r
955                 {\r
956                     return error(GL_INVALID_OPERATION);\r
957                 }\r
958 \r
959                 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);\r
960             }\r
961             else\r
962             {\r
963                 rad::TextureCubeMap *texture = context->getTextureCubeMap();\r
964 \r
965                 if(!texture)\r
966                 {\r
967                     return error(GL_INVALID_OPERATION);\r
968                 }\r
969 \r
970                 switch(target)\r
971                 {\r
972                   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:\r
973                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:\r
974                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:\r
975                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:\r
976                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:\r
977                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:\r
978                     texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);\r
979                     break;\r
980                   default: UNREACHABLE();\r
981                 }\r
982             }\r
983         }\r
984     }\r
985     catch(std::bad_alloc&)\r
986     {\r
987         return error(GL_OUT_OF_MEMORY);\r
988     }\r
989 }\r
990 \r
991 void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,\r
992                                          GLenum format, GLsizei imageSize, const GLvoid* data)\r
993 {\r
994     TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "\r
995           "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "\r
996           "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",\r
997           target, level, xoffset, yoffset, width, height, format, imageSize, data);\r
998 \r
999     try\r
1000     {\r
1001         if(!rad::IsTextureTarget(target))\r
1002         {\r
1003             return error(GL_INVALID_ENUM);\r
1004         }\r
1005 \r
1006         if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)\r
1007         {\r
1008             return error(GL_INVALID_VALUE);\r
1009         }\r
1010 \r
1011         switch(format)\r
1012         {\r
1013         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:\r
1014         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:\r
1015                 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:\r
1016                 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:\r
1017                         if(!S3TC_SUPPORT)\r
1018             {\r
1019                 return error(GL_INVALID_ENUM);\r
1020             }\r
1021             break;\r
1022         default:\r
1023             return error(GL_INVALID_ENUM);\r
1024         }\r
1025 \r
1026         if(width == 0 || height == 0 || data == NULL)\r
1027         {\r
1028             return;\r
1029         }\r
1030 \r
1031         rad::Context *context = rad::getContext();\r
1032 \r
1033         if(context)\r
1034         {\r
1035             if(level > rad::IMPLEMENTATION_MAX_TEXTURE_LEVELS)\r
1036             {\r
1037                 return error(GL_INVALID_VALUE);\r
1038             }\r
1039 \r
1040             if(imageSize != rad::ComputeCompressedSize(width, height, format))\r
1041             {\r
1042                 return error(GL_INVALID_VALUE);\r
1043             }\r
1044 \r
1045             if(xoffset % 4 != 0 || yoffset % 4 != 0)\r
1046             {\r
1047                                 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported\r
1048                 return error(GL_INVALID_OPERATION);\r
1049             }\r
1050 \r
1051             if(target == GL_TEXTURE_2D)\r
1052             {\r
1053                 rad::Texture2D *texture = context->getTexture2D();\r
1054 \r
1055                 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))\r
1056                                 {\r
1057                                         texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);\r
1058                                 }\r
1059             }\r
1060             else if(rad::IsCubemapTextureTarget(target))\r
1061             {\r
1062                 rad::TextureCubeMap *texture = context->getTextureCubeMap();\r
1063 \r
1064                 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))\r
1065                                 {\r
1066                                         texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);\r
1067                                 }\r
1068             }\r
1069             else\r
1070             {\r
1071                 UNREACHABLE();\r
1072             }\r
1073         }\r
1074     }\r
1075     catch(std::bad_alloc&)\r
1076     {\r
1077         return error(GL_OUT_OF_MEMORY);\r
1078     }\r
1079 }\r
1080 \r
1081 void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)\r
1082 {\r
1083     TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "\r
1084           "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",\r
1085           target, level, internalformat, x, y, width, height, border);\r
1086 \r
1087     try\r
1088     {\r
1089         if(!validImageSize(level, width, height))\r
1090         {\r
1091             return error(GL_INVALID_VALUE);\r
1092         }\r
1093 \r
1094         if(border != 0)\r
1095         {\r
1096             return error(GL_INVALID_VALUE);\r
1097         }\r
1098 \r
1099         rad::Context *context = rad::getContext();\r
1100 \r
1101         if(context)\r
1102         {\r
1103             switch(target)\r
1104             {\r
1105               case GL_TEXTURE_2D:\r
1106                 if(width > (rad::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||\r
1107                    height > (rad::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))\r
1108                 {\r
1109                     return error(GL_INVALID_VALUE);\r
1110                 }\r
1111                 break;\r
1112               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:\r
1113               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:\r
1114               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:\r
1115               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:\r
1116               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:\r
1117               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:\r
1118                 if(width != height)\r
1119                 {\r
1120                     return error(GL_INVALID_VALUE);\r
1121                 }\r
1122 \r
1123                 if(width > (rad::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||\r
1124                    height > (rad::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))\r
1125                 {\r
1126                     return error(GL_INVALID_VALUE);\r
1127                 }\r
1128                 break;\r
1129               default:\r
1130                 return error(GL_INVALID_ENUM);\r
1131             }\r
1132 \r
1133             rad::Framebuffer *framebuffer = context->getReadFramebuffer();\r
1134 \r
1135             if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)\r
1136             {\r
1137                 return error(GL_INVALID_FRAMEBUFFER_OPERATION);\r
1138             }\r
1139 \r
1140             if(context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)\r
1141             {\r
1142                 return error(GL_INVALID_OPERATION);\r
1143             }\r
1144 \r
1145             rad::Renderbuffer *source = framebuffer->getColorbuffer();\r
1146             GLenum colorbufferFormat = source->getFormat();\r
1147 \r
1148             // [OpenGL ES 2.0.24] table 3.9\r
1149             switch(internalformat)\r
1150             {\r
1151             case GL_ALPHA:\r
1152                 if(colorbufferFormat != GL_ALPHA &&\r
1153                    colorbufferFormat != GL_RGBA &&\r
1154                    colorbufferFormat != GL_RGBA4 &&\r
1155                    colorbufferFormat != GL_RGB5_A1 &&\r
1156                    colorbufferFormat != GL_RGBA8_OES)\r
1157                 {\r
1158                     return error(GL_INVALID_OPERATION);\r
1159                 }\r
1160                 break;\r
1161             case GL_LUMINANCE:\r
1162             case GL_RGB:\r
1163                 if(colorbufferFormat != GL_RGB &&\r
1164                    colorbufferFormat != GL_RGB565 &&\r
1165                    colorbufferFormat != GL_RGB8_OES &&\r
1166                    colorbufferFormat != GL_RGBA &&\r
1167                    colorbufferFormat != GL_RGBA4 &&\r
1168                    colorbufferFormat != GL_RGB5_A1 &&\r
1169                    colorbufferFormat != GL_RGBA8_OES)\r
1170                 {\r
1171                     return error(GL_INVALID_OPERATION);\r
1172                 }\r
1173                 break;\r
1174             case GL_LUMINANCE_ALPHA:\r
1175             case GL_RGBA:\r
1176                 if(colorbufferFormat != GL_RGBA &&\r
1177                    colorbufferFormat != GL_RGBA4 &&\r
1178                    colorbufferFormat != GL_RGB5_A1 &&\r
1179                    colorbufferFormat != GL_RGBA8_OES)\r
1180                  {\r
1181                      return error(GL_INVALID_OPERATION);\r
1182                  }\r
1183                  break;\r
1184             case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:\r
1185             case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:\r
1186                         case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:\r
1187                         case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:\r
1188                 if(S3TC_SUPPORT)\r
1189                 {\r
1190                     return error(GL_INVALID_OPERATION);\r
1191                 }\r
1192                 else\r
1193                 {\r
1194                     return error(GL_INVALID_ENUM);\r
1195                 }\r
1196                 break;\r
1197             default:\r
1198                 return error(GL_INVALID_ENUM);\r
1199             }\r
1200 \r
1201             if(target == GL_TEXTURE_2D)\r
1202             {\r
1203                 rad::Texture2D *texture = context->getTexture2D();\r
1204 \r
1205                 if(!texture)\r
1206                 {\r
1207                     return error(GL_INVALID_OPERATION);\r
1208                 }\r
1209 \r
1210                 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);\r
1211             }\r
1212             else if(rad::IsCubemapTextureTarget(target))\r
1213             {\r
1214                 rad::TextureCubeMap *texture = context->getTextureCubeMap();\r
1215 \r
1216                 if(!texture)\r
1217                 {\r
1218                     return error(GL_INVALID_OPERATION);\r
1219                 }\r
1220 \r
1221                 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);\r
1222             }\r
1223             else UNREACHABLE();\r
1224         }\r
1225     }\r
1226     catch(std::bad_alloc&)\r
1227     {\r
1228         return error(GL_OUT_OF_MEMORY);\r
1229     }\r
1230 }\r
1231 \r
1232 void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)\r
1233 {\r
1234     TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "\r
1235           "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",\r
1236           target, level, xoffset, yoffset, x, y, width, height);\r
1237 \r
1238     try\r
1239     {\r
1240         if(!rad::IsTextureTarget(target))\r
1241         {\r
1242             return error(GL_INVALID_ENUM);\r
1243         }\r
1244 \r
1245         if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)\r
1246         {\r
1247             return error(GL_INVALID_VALUE);\r
1248         }\r
1249 \r
1250         if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)\r
1251         {\r
1252             return error(GL_INVALID_VALUE);\r
1253         }\r
1254 \r
1255         if(width == 0 || height == 0)\r
1256         {\r
1257             return;\r
1258         }\r
1259 \r
1260         rad::Context *context = rad::getContext();\r
1261 \r
1262         if(context)\r
1263         {\r
1264             if(level > rad::IMPLEMENTATION_MAX_TEXTURE_LEVELS)\r
1265             {\r
1266                 return error(GL_INVALID_VALUE);\r
1267             }\r
1268 \r
1269             rad::Framebuffer *framebuffer = context->getReadFramebuffer();\r
1270 \r
1271             if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)\r
1272             {\r
1273                 return error(GL_INVALID_FRAMEBUFFER_OPERATION);\r
1274             }\r
1275 \r
1276             if(context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)\r
1277             {\r
1278                 return error(GL_INVALID_OPERATION);\r
1279             }\r
1280 \r
1281             rad::Renderbuffer *source = framebuffer->getColorbuffer();\r
1282             GLenum colorbufferFormat = source->getFormat();\r
1283             rad::Texture *texture = NULL;\r
1284 \r
1285             if(target == GL_TEXTURE_2D)\r
1286             {\r
1287                 texture = context->getTexture2D();\r
1288             }\r
1289             else if(rad::IsCubemapTextureTarget(target))\r
1290             {\r
1291                 texture = context->getTextureCubeMap();\r
1292             }\r
1293             else UNREACHABLE();\r
1294 \r
1295             if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))\r
1296                         {\r
1297                                 return;\r
1298                         }\r
1299 \r
1300             GLenum textureFormat = texture->getFormat(target, level);\r
1301 \r
1302             // [OpenGL ES 2.0.24] table 3.9\r
1303             switch(textureFormat)\r
1304             {\r
1305             case GL_ALPHA:\r
1306                 if(colorbufferFormat != GL_ALPHA &&\r
1307                    colorbufferFormat != GL_RGBA &&\r
1308                    colorbufferFormat != GL_RGBA4 &&\r
1309                    colorbufferFormat != GL_RGB5_A1 &&\r
1310                    colorbufferFormat != GL_RGBA8_OES)\r
1311                 {\r
1312                     return error(GL_INVALID_OPERATION);\r
1313                 }\r
1314                 break;\r
1315             case GL_LUMINANCE:\r
1316             case GL_RGB:\r
1317                 if(colorbufferFormat != GL_RGB &&\r
1318                    colorbufferFormat != GL_RGB565 &&\r
1319                    colorbufferFormat != GL_RGB8_OES &&\r
1320                    colorbufferFormat != GL_RGBA &&\r
1321                    colorbufferFormat != GL_RGBA4 &&\r
1322                    colorbufferFormat != GL_RGB5_A1 &&\r
1323                    colorbufferFormat != GL_RGBA8_OES)\r
1324                 {\r
1325                     return error(GL_INVALID_OPERATION);\r
1326                 }\r
1327                 break;\r
1328             case GL_LUMINANCE_ALPHA:\r
1329             case GL_RGBA:\r
1330                 if(colorbufferFormat != GL_RGBA &&\r
1331                    colorbufferFormat != GL_RGBA4 &&\r
1332                    colorbufferFormat != GL_RGB5_A1 &&\r
1333                    colorbufferFormat != GL_RGBA8_OES)\r
1334                 {\r
1335                     return error(GL_INVALID_OPERATION);\r
1336                 }\r
1337                 break;\r
1338             case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:\r
1339             case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:\r
1340                         case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:\r
1341                         case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:\r
1342                 return error(GL_INVALID_OPERATION);\r
1343                         case GL_DEPTH_COMPONENT:\r
1344                         case GL_DEPTH_STENCIL_OES:\r
1345                                 return error(GL_INVALID_OPERATION);\r
1346             default:\r
1347                 return error(GL_INVALID_OPERATION);\r
1348             }\r
1349 \r
1350             texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);\r
1351         }\r
1352     }\r
1353 \r
1354     catch(std::bad_alloc&)\r
1355     {\r
1356         return error(GL_OUT_OF_MEMORY);\r
1357     }\r
1358 }\r
1359 \r
1360 GLuint GL_APIENTRY glCreateProgram(void)\r
1361 {\r
1362     TRACE("()");\r
1363 \r
1364     try\r
1365     {\r
1366         rad::Context *context = rad::getContext();\r
1367 \r
1368         if(context)\r
1369         {\r
1370             return context->createProgram();\r
1371         }\r
1372     }\r
1373     catch(std::bad_alloc&)\r
1374     {\r
1375         return error(GL_OUT_OF_MEMORY, 0);\r
1376     }\r
1377 \r
1378     return 0;\r
1379 }\r
1380 \r
1381 GLuint GL_APIENTRY glCreateShader(GLenum type)\r
1382 {\r
1383     TRACE("(GLenum type = 0x%X)", type);\r
1384 \r
1385     try\r
1386     {\r
1387         rad::Context *context = rad::getContext();\r
1388 \r
1389         if(context)\r
1390         {\r
1391             switch(type)\r
1392             {\r
1393               case GL_FRAGMENT_SHADER:\r
1394               case GL_VERTEX_SHADER:\r
1395                 return context->createShader(type);\r
1396               default:\r
1397                 return error(GL_INVALID_ENUM, 0);\r
1398             }\r
1399         }\r
1400     }\r
1401     catch(std::bad_alloc&)\r
1402     {\r
1403         return error(GL_OUT_OF_MEMORY, 0);\r
1404     }\r
1405 \r
1406     return 0;\r
1407 }\r
1408 \r
1409 void GL_APIENTRY glCullFace(GLenum mode)\r
1410 {\r
1411     TRACE("(GLenum mode = 0x%X)", mode);\r
1412 \r
1413     try\r
1414     {\r
1415         switch(mode)\r
1416         {\r
1417           case GL_FRONT:\r
1418           case GL_BACK:\r
1419           case GL_FRONT_AND_BACK:\r
1420             {\r
1421                 rad::Context *context = rad::getContext();\r
1422 \r
1423                 if(context)\r
1424                 {\r
1425                     context->setCullMode(mode);\r
1426                 }\r
1427             }\r
1428             break;\r
1429           default:\r
1430             return error(GL_INVALID_ENUM);\r
1431         }\r
1432     }\r
1433     catch(std::bad_alloc&)\r
1434     {\r
1435         return error(GL_OUT_OF_MEMORY);\r
1436     }\r
1437 }\r
1438 \r
1439 void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)\r
1440 {\r
1441     TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);\r
1442 \r
1443     try\r
1444     {\r
1445         if(n < 0)\r
1446         {\r
1447             return error(GL_INVALID_VALUE);\r
1448         }\r
1449 \r
1450         rad::Context *context = rad::getContext();\r
1451 \r
1452         if(context)\r
1453         {\r
1454             for(int i = 0; i < n; i++)\r
1455             {\r
1456                 context->deleteBuffer(buffers[i]);\r
1457             }\r
1458         }\r
1459     }\r
1460     catch(std::bad_alloc&)\r
1461     {\r
1462         return error(GL_OUT_OF_MEMORY);\r
1463     }\r
1464 }\r
1465 \r
1466 void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)\r
1467 {\r
1468     TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);\r
1469 \r
1470     try\r
1471     {\r
1472         if(n < 0)\r
1473         {\r
1474             return error(GL_INVALID_VALUE);\r
1475         }\r
1476 \r
1477         rad::Context *context = rad::getContext();\r
1478 \r
1479         if(context)\r
1480         {\r
1481             for(int i = 0; i < n; i++)\r
1482             {\r
1483                 context->deleteFence(fences[i]);\r
1484             }\r
1485         }\r
1486     }\r
1487     catch(std::bad_alloc&)\r
1488     {\r
1489         return error(GL_OUT_OF_MEMORY);\r
1490     }\r
1491 }\r
1492 \r
1493 void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)\r
1494 {\r
1495     TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);\r
1496 \r
1497     try\r
1498     {\r
1499         if(n < 0)\r
1500         {\r
1501             return error(GL_INVALID_VALUE);\r
1502         }\r
1503 \r
1504         rad::Context *context = rad::getContext();\r
1505 \r
1506         if(context)\r
1507         {\r
1508             for(int i = 0; i < n; i++)\r
1509             {\r
1510                 if(framebuffers[i] != 0)\r
1511                 {\r
1512                     context->deleteFramebuffer(framebuffers[i]);\r
1513                 }\r
1514             }\r
1515         }\r
1516     }\r
1517     catch(std::bad_alloc&)\r
1518     {\r
1519         return error(GL_OUT_OF_MEMORY);\r
1520     }\r
1521 }\r
1522 \r
1523 void GL_APIENTRY glDeleteProgram(GLuint program)\r
1524 {\r
1525     TRACE("(GLuint program = %d)", program);\r
1526 \r
1527     try\r
1528     {\r
1529         if(program == 0)\r
1530         {\r
1531             return;\r
1532         }\r
1533 \r
1534         rad::Context *context = rad::getContext();\r
1535 \r
1536         if(context)\r
1537         {\r
1538             if(!context->getProgram(program))\r
1539             {\r
1540                 if(context->getShader(program))\r
1541                 {\r
1542                     return error(GL_INVALID_OPERATION);\r
1543                 }\r
1544                 else\r
1545                 {\r
1546                     return error(GL_INVALID_VALUE);\r
1547                 }\r
1548             }\r
1549 \r
1550             context->deleteProgram(program);\r
1551         }\r
1552     }\r
1553     catch(std::bad_alloc&)\r
1554     {\r
1555         return error(GL_OUT_OF_MEMORY);\r
1556     }\r
1557 }\r
1558 \r
1559 void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)\r
1560 {\r
1561     TRACE("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);\r
1562 \r
1563     try\r
1564     {\r
1565         if(n < 0)\r
1566         {\r
1567             return error(GL_INVALID_VALUE);\r
1568         }\r
1569 \r
1570         rad::Context *context = rad::getContext();\r
1571 \r
1572         if(context)\r
1573         {\r
1574             for(int i = 0; i < n; i++)\r
1575             {\r
1576                 context->deleteQuery(ids[i]);\r
1577             }\r
1578         }\r
1579     }\r
1580     catch(std::bad_alloc&)\r
1581     {\r
1582         return error(GL_OUT_OF_MEMORY);\r
1583     }\r
1584 }\r
1585 \r
1586 void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)\r
1587 {\r
1588     TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);\r
1589 \r
1590     try\r
1591     {\r
1592         if(n < 0)\r
1593         {\r
1594             return error(GL_INVALID_VALUE);\r
1595         }\r
1596 \r
1597         rad::Context *context = rad::getContext();\r
1598 \r
1599         if(context)\r
1600         {\r
1601             for(int i = 0; i < n; i++)\r
1602             {\r
1603                 context->deleteRenderbuffer(renderbuffers[i]);\r
1604             }\r
1605         }\r
1606     }\r
1607     catch(std::bad_alloc&)\r
1608     {\r
1609         return error(GL_OUT_OF_MEMORY);\r
1610     }\r
1611 }\r
1612 \r
1613 void GL_APIENTRY glDeleteShader(GLuint shader)\r
1614 {\r
1615     TRACE("(GLuint shader = %d)", shader);\r
1616 \r
1617     try\r
1618     {\r
1619         if(shader == 0)\r
1620         {\r
1621             return;\r
1622         }\r
1623 \r
1624         rad::Context *context = rad::getContext();\r
1625 \r
1626         if(context)\r
1627         {\r
1628             if(!context->getShader(shader))\r
1629             {\r
1630                 if(context->getProgram(shader))\r
1631                 {\r
1632                     return error(GL_INVALID_OPERATION);\r
1633                 }\r
1634                 else\r
1635                 {\r
1636                     return error(GL_INVALID_VALUE);\r
1637                 }\r
1638             }\r
1639 \r
1640             context->deleteShader(shader);\r
1641         }\r
1642     }\r
1643     catch(std::bad_alloc&)\r
1644     {\r
1645         return error(GL_OUT_OF_MEMORY);\r
1646     }\r
1647 }\r
1648 \r
1649 void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)\r
1650 {\r
1651     TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);\r
1652 \r
1653     try\r
1654     {\r
1655         if(n < 0)\r
1656         {\r
1657             return error(GL_INVALID_VALUE);\r
1658         }\r
1659 \r
1660         rad::Context *context = rad::getContext();\r
1661 \r
1662         if(context)\r
1663         {\r
1664             for(int i = 0; i < n; i++)\r
1665             {\r
1666                 if(textures[i] != 0)\r
1667                 {\r
1668                     context->deleteTexture(textures[i]);\r
1669                 }\r
1670             }\r
1671         }\r
1672     }\r
1673     catch(std::bad_alloc&)\r
1674     {\r
1675         return error(GL_OUT_OF_MEMORY);\r
1676     }\r
1677 }\r
1678 \r
1679 void GL_APIENTRY glDepthFunc(GLenum func)\r
1680 {\r
1681     TRACE("(GLenum func = 0x%X)", func);\r
1682 \r
1683     try\r
1684     {\r
1685         switch(func)\r
1686         {\r
1687           case GL_NEVER:\r
1688           case GL_ALWAYS:\r
1689           case GL_LESS:\r
1690           case GL_LEQUAL:\r
1691           case GL_EQUAL:\r
1692           case GL_GREATER:\r
1693           case GL_GEQUAL:\r
1694           case GL_NOTEQUAL:\r
1695             break;\r
1696           default:\r
1697             return error(GL_INVALID_ENUM);\r
1698         }\r
1699 \r
1700         rad::Context *context = rad::getContext();\r
1701 \r
1702         if(context)\r
1703         {\r
1704             context->setDepthFunc(func);\r
1705         }\r
1706     }\r
1707     catch(std::bad_alloc&)\r
1708     {\r
1709         return error(GL_OUT_OF_MEMORY);\r
1710     }\r
1711 }\r
1712 \r
1713 void GL_APIENTRY glDepthMask(GLboolean flag)\r
1714 {\r
1715     TRACE("(GLboolean flag = %d)", flag);\r
1716 \r
1717     try\r
1718     {\r
1719         rad::Context *context = rad::getContext();\r
1720 \r
1721         if(context)\r
1722         {\r
1723             context->setDepthMask(flag != GL_FALSE);\r
1724         }\r
1725     }\r
1726     catch(std::bad_alloc&)\r
1727     {\r
1728         return error(GL_OUT_OF_MEMORY);\r
1729     }\r
1730 }\r
1731 \r
1732 void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)\r
1733 {\r
1734     TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);\r
1735 \r
1736     try\r
1737     {\r
1738         rad::Context *context = rad::getContext();\r
1739 \r
1740         if(context)\r
1741         {\r
1742             context->setDepthRange(zNear, zFar);\r
1743         }\r
1744     }\r
1745     catch(std::bad_alloc&)\r
1746     {\r
1747         return error(GL_OUT_OF_MEMORY);\r
1748     }\r
1749 }\r
1750 \r
1751 void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)\r
1752 {\r
1753     TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);\r
1754 \r
1755     try\r
1756     {\r
1757         rad::Context *context = rad::getContext();\r
1758 \r
1759         if(context)\r
1760         {\r
1761 \r
1762             rad::Program *programObject = context->getProgram(program);\r
1763             rad::Shader *shaderObject = context->getShader(shader);\r
1764             \r
1765             if(!programObject)\r
1766             {\r
1767                 rad::Shader *shaderByProgramHandle;\r
1768                 shaderByProgramHandle = context->getShader(program);\r
1769                 if(!shaderByProgramHandle)\r
1770                 {\r
1771                     return error(GL_INVALID_VALUE);\r
1772                 }\r
1773                 else\r
1774                 {\r
1775                     return error(GL_INVALID_OPERATION);\r
1776                 }\r
1777             }\r
1778 \r
1779             if(!shaderObject)\r
1780             {\r
1781                 rad::Program *programByShaderHandle = context->getProgram(shader);\r
1782                 if(!programByShaderHandle)\r
1783                 {\r
1784                     return error(GL_INVALID_VALUE);\r
1785                 }\r
1786                 else\r
1787                 {\r
1788                     return error(GL_INVALID_OPERATION);\r
1789                 }\r
1790             }\r
1791 \r
1792             if(!programObject->detachShader(shaderObject))\r
1793             {\r
1794                 return error(GL_INVALID_OPERATION);\r
1795             }\r
1796         }\r
1797     }\r
1798     catch(std::bad_alloc&)\r
1799     {\r
1800         return error(GL_OUT_OF_MEMORY);\r
1801     }\r
1802 }\r
1803 \r
1804 void GL_APIENTRY glDisable(GLenum cap)\r
1805 {\r
1806     TRACE("(GLenum cap = 0x%X)", cap);\r
1807 \r
1808     try\r
1809     {\r
1810         rad::Context *context = rad::getContext();\r
1811 \r
1812         if(context)\r
1813         {\r
1814             switch(cap)\r
1815             {\r
1816               case GL_CULL_FACE:                context->setCullFace(false);              break;\r
1817               case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFill(false);     break;\r
1818               case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;\r
1819               case GL_SAMPLE_COVERAGE:          context->setSampleCoverage(false);        break;\r
1820               case GL_SCISSOR_TEST:             context->setScissorTest(false);           break;\r
1821               case GL_STENCIL_TEST:             context->setStencilTest(false);           break;\r
1822               case GL_DEPTH_TEST:               context->setDepthTest(false);             break;\r
1823               case GL_BLEND:                    context->setBlend(false);                 break;\r
1824               case GL_DITHER:                   context->setDither(false);                break;\r
1825               default:\r
1826                 return error(GL_INVALID_ENUM);\r
1827             }\r
1828         }\r
1829     }\r
1830     catch(std::bad_alloc&)\r
1831     {\r
1832         return error(GL_OUT_OF_MEMORY);\r
1833     }\r
1834 }\r
1835 \r
1836 void GL_APIENTRY glDisableVertexAttribArray(GLuint index)\r
1837 {\r
1838     TRACE("(GLuint index = %d)", index);\r
1839 \r
1840     try\r
1841     {\r
1842         if(index >= rad::MAX_VERTEX_ATTRIBS)\r
1843         {\r
1844             return error(GL_INVALID_VALUE);\r
1845         }\r
1846 \r
1847         rad::Context *context = rad::getContext();\r
1848 \r
1849         if(context)\r
1850         {\r
1851             context->setEnableVertexAttribArray(index, false);\r
1852         }\r
1853     }\r
1854     catch(std::bad_alloc&)\r
1855     {\r
1856         return error(GL_OUT_OF_MEMORY);\r
1857     }\r
1858 }\r
1859 \r
1860 void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)\r
1861 {\r
1862     TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);\r
1863 \r
1864     try\r
1865     {\r
1866         if(count < 0 || first < 0)\r
1867         {\r
1868             return error(GL_INVALID_VALUE);\r
1869         }\r
1870 \r
1871         rad::Context *context = rad::getContext();\r
1872 \r
1873         if(context)\r
1874         {\r
1875             context->drawArrays(mode, first, count);\r
1876         }\r
1877     }\r
1878     catch(std::bad_alloc&)\r
1879     {\r
1880         return error(GL_OUT_OF_MEMORY);\r
1881     }\r
1882 }\r
1883 \r
1884 void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)\r
1885 {\r
1886     TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",\r
1887           mode, count, type, indices);\r
1888 \r
1889     try\r
1890     {\r
1891         if(count < 0)\r
1892         {\r
1893             return error(GL_INVALID_VALUE);\r
1894         }\r
1895 \r
1896         rad::Context *context = rad::getContext();\r
1897 \r
1898         if(context)\r
1899         {\r
1900             switch(type)\r
1901             {\r
1902               case GL_UNSIGNED_BYTE:\r
1903               case GL_UNSIGNED_SHORT:\r
1904               case GL_UNSIGNED_INT:\r
1905                 break;\r
1906               default:\r
1907                 return error(GL_INVALID_ENUM);\r
1908             }\r
1909         \r
1910             context->drawElements(mode, count, type, indices);\r
1911         }\r
1912     }\r
1913     catch(std::bad_alloc&)\r
1914     {\r
1915         return error(GL_OUT_OF_MEMORY);\r
1916     }\r
1917 }\r
1918 \r
1919 void GL_APIENTRY glEnable(GLenum cap)\r
1920 {\r
1921     TRACE("(GLenum cap = 0x%X)", cap);\r
1922 \r
1923     try\r
1924     {\r
1925         rad::Context *context = rad::getContext();\r
1926 \r
1927         if(context)\r
1928         {\r
1929             switch(cap)\r
1930             {\r
1931               case GL_CULL_FACE:                context->setCullFace(true);              break;\r
1932               case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFill(true);     break;\r
1933               case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;\r
1934               case GL_SAMPLE_COVERAGE:          context->setSampleCoverage(true);        break;\r
1935               case GL_SCISSOR_TEST:             context->setScissorTest(true);           break;\r
1936               case GL_STENCIL_TEST:             context->setStencilTest(true);           break;\r
1937               case GL_DEPTH_TEST:               context->setDepthTest(true);             break;\r
1938               case GL_BLEND:                    context->setBlend(true);                 break;\r
1939               case GL_DITHER:                   context->setDither(true);                break;\r
1940               default:\r
1941                 return error(GL_INVALID_ENUM);\r
1942             }\r
1943         }\r
1944     }\r
1945     catch(std::bad_alloc&)\r
1946     {\r
1947         return error(GL_OUT_OF_MEMORY);\r
1948     }\r
1949 }\r
1950 \r
1951 void GL_APIENTRY glEnableVertexAttribArray(GLuint index)\r
1952 {\r
1953     TRACE("(GLuint index = %d)", index);\r
1954 \r
1955     try\r
1956     {\r
1957         if(index >= rad::MAX_VERTEX_ATTRIBS)\r
1958         {\r
1959             return error(GL_INVALID_VALUE);\r
1960         }\r
1961 \r
1962         rad::Context *context = rad::getContext();\r
1963 \r
1964         if(context)\r
1965         {\r
1966             context->setEnableVertexAttribArray(index, true);\r
1967         }\r
1968     }\r
1969     catch(std::bad_alloc&)\r
1970     {\r
1971         return error(GL_OUT_OF_MEMORY);\r
1972     }\r
1973 }\r
1974 \r
1975 void GL_APIENTRY glEndQueryEXT(GLenum target)\r
1976 {\r
1977     TRACE("GLenum target = 0x%X)", target);\r
1978 \r
1979     try\r
1980     {\r
1981         switch(target)\r
1982         {\r
1983         case GL_ANY_SAMPLES_PASSED_EXT: \r
1984         case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:\r
1985             break;\r
1986         default: \r
1987             return error(GL_INVALID_ENUM);\r
1988         }\r
1989 \r
1990         rad::Context *context = rad::getContext();\r
1991 \r
1992         if(context)\r
1993         {\r
1994             context->endQuery(target);\r
1995         }\r
1996     }\r
1997     catch(std::bad_alloc&)\r
1998     {\r
1999         return error(GL_OUT_OF_MEMORY);\r
2000     }\r
2001 }\r
2002 \r
2003 void GL_APIENTRY glFinishFenceNV(GLuint fence)\r
2004 {\r
2005     TRACE("(GLuint fence = %d)", fence);\r
2006 \r
2007     try\r
2008     {\r
2009         rad::Context *context = rad::getContext();\r
2010 \r
2011         if(context)\r
2012         {\r
2013             rad::Fence* fenceObject = context->getFence(fence);\r
2014 \r
2015             if(fenceObject == NULL)\r
2016             {\r
2017                 return error(GL_INVALID_OPERATION);\r
2018             }\r
2019 \r
2020             fenceObject->finishFence();\r
2021         }\r
2022     }\r
2023     catch(std::bad_alloc&)\r
2024     {\r
2025         return error(GL_OUT_OF_MEMORY);\r
2026     }\r
2027 }\r
2028 \r
2029 void GL_APIENTRY glFinish(void)\r
2030 {\r
2031     TRACE("()");\r
2032 \r
2033     try\r
2034     {\r
2035         rad::Context *context = rad::getContext();\r
2036 \r
2037         if(context)\r
2038         {\r
2039             context->finish();\r
2040         }\r
2041     }\r
2042     catch(std::bad_alloc&)\r
2043     {\r
2044         return error(GL_OUT_OF_MEMORY);\r
2045     }\r
2046 }\r
2047 \r
2048 void GL_APIENTRY glFlush(void)\r
2049 {\r
2050     TRACE("()");\r
2051 \r
2052     try\r
2053     {\r
2054         rad::Context *context = rad::getContext();\r
2055 \r
2056         if(context)\r
2057         {\r
2058             context->flush();\r
2059         }\r
2060     }\r
2061     catch(std::bad_alloc&)\r
2062     {\r
2063         return error(GL_OUT_OF_MEMORY);\r
2064     }\r
2065 }\r
2066 \r
2067 void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)\r
2068 {\r
2069     TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "\r
2070           "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);\r
2071 \r
2072     try\r
2073     {\r
2074         if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)\r
2075             || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))\r
2076         {\r
2077             return error(GL_INVALID_ENUM);\r
2078         }\r
2079 \r
2080         rad::Context *context = rad::getContext();\r
2081 \r
2082         if(context)\r
2083         {\r
2084             rad::Framebuffer *framebuffer = NULL;\r
2085             GLuint framebufferHandle = 0;\r
2086             if(target == GL_READ_FRAMEBUFFER_ANGLE)\r
2087             {\r
2088                 framebuffer = context->getReadFramebuffer();\r
2089                 framebufferHandle = context->getReadFramebufferHandle();\r
2090             }\r
2091             else\r
2092             {\r
2093                 framebuffer = context->getDrawFramebuffer();\r
2094                 framebufferHandle = context->getDrawFramebufferHandle();\r
2095             }\r
2096 \r
2097             if(!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))\r
2098             {\r
2099                 return error(GL_INVALID_OPERATION);\r
2100             }\r
2101 \r
2102             switch(attachment)\r
2103             {\r
2104               case GL_COLOR_ATTACHMENT0:\r
2105                 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);\r
2106                 break;\r
2107               case GL_DEPTH_ATTACHMENT:\r
2108                 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);\r
2109                 break;\r
2110               case GL_STENCIL_ATTACHMENT:\r
2111                 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);\r
2112                 break;\r
2113               default:\r
2114                 return error(GL_INVALID_ENUM);\r
2115             }\r
2116         }\r
2117     }\r
2118     catch(std::bad_alloc&)\r
2119     {\r
2120         return error(GL_OUT_OF_MEMORY);\r
2121     }\r
2122 }\r
2123 \r
2124 void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)\r
2125 {\r
2126     TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "\r
2127           "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);\r
2128 \r
2129     try\r
2130     {\r
2131         if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)\r
2132         {\r
2133             return error(GL_INVALID_ENUM);\r
2134         }\r
2135 \r
2136         switch(attachment)\r
2137         {\r
2138           case GL_COLOR_ATTACHMENT0:\r
2139           case GL_DEPTH_ATTACHMENT:\r
2140           case GL_STENCIL_ATTACHMENT:\r
2141             break;\r
2142           default:\r
2143             return error(GL_INVALID_ENUM);\r
2144         }\r
2145 \r
2146         rad::Context *context = rad::getContext();\r
2147 \r
2148         if(context)\r
2149         {\r
2150             if(texture == 0)\r
2151             {\r
2152                 textarget = GL_NONE;\r
2153             }\r
2154             else\r
2155             {\r
2156                 rad::Texture *tex = context->getTexture(texture);\r
2157 \r
2158                 if(tex == NULL)\r
2159                 {\r
2160                     return error(GL_INVALID_OPERATION);\r
2161                 }\r
2162 \r
2163                 if(tex->isCompressed(textarget, level))\r
2164                 {\r
2165                     return error(GL_INVALID_OPERATION);\r
2166                 }\r
2167 \r
2168                 switch(textarget)\r
2169                 {\r
2170                   case GL_TEXTURE_2D:\r
2171                     if(tex->getTarget() != GL_TEXTURE_2D)\r
2172                     {\r
2173                         return error(GL_INVALID_OPERATION);\r
2174                     }\r
2175                     break;\r
2176 \r
2177                   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:\r
2178                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:\r
2179                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:\r
2180                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:\r
2181                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:\r
2182                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:\r
2183                     if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)\r
2184                     {\r
2185                         return error(GL_INVALID_OPERATION);\r
2186                     }\r
2187                     break;\r
2188 \r
2189                   default:\r
2190                     return error(GL_INVALID_ENUM);\r
2191                 }\r
2192 \r
2193                 if(level != 0)\r
2194                 {\r
2195                     return error(GL_INVALID_VALUE);\r
2196                 }\r
2197             }\r
2198 \r
2199             rad::Framebuffer *framebuffer = NULL;\r
2200             GLuint framebufferHandle = 0;\r
2201             if(target == GL_READ_FRAMEBUFFER_ANGLE)\r
2202             {\r
2203                 framebuffer = context->getReadFramebuffer();\r
2204                 framebufferHandle = context->getReadFramebufferHandle();\r
2205             }\r
2206             else\r
2207             {\r
2208                 framebuffer = context->getDrawFramebuffer();\r
2209                 framebufferHandle = context->getDrawFramebufferHandle();\r
2210             }\r
2211 \r
2212             if(framebufferHandle == 0 || !framebuffer)\r
2213             {\r
2214                 return error(GL_INVALID_OPERATION);\r
2215             }\r
2216 \r
2217             switch(attachment)\r
2218             {\r
2219               case GL_COLOR_ATTACHMENT0:  framebuffer->setColorbuffer(textarget, texture);   break;\r
2220               case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;\r
2221               case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;\r
2222             }\r
2223         }\r
2224     }\r
2225     catch(std::bad_alloc&)\r
2226     {\r
2227         return error(GL_OUT_OF_MEMORY);\r
2228     }\r
2229 }\r
2230 \r
2231 void GL_APIENTRY glFrontFace(GLenum mode)\r
2232 {\r
2233     TRACE("(GLenum mode = 0x%X)", mode);\r
2234 \r
2235     try\r
2236     {\r
2237         switch(mode)\r
2238         {\r
2239           case GL_CW:\r
2240           case GL_CCW:\r
2241             {\r
2242                 rad::Context *context = rad::getContext();\r
2243 \r
2244                 if(context)\r
2245                 {\r
2246                     context->setFrontFace(mode);\r
2247                 }\r
2248             }\r
2249             break;\r
2250           default:\r
2251             return error(GL_INVALID_ENUM);\r
2252         }\r
2253     }\r
2254     catch(std::bad_alloc&)\r
2255     {\r
2256         return error(GL_OUT_OF_MEMORY);\r
2257     }\r
2258 }\r
2259 \r
2260 void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)\r
2261 {\r
2262     TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);\r
2263 \r
2264     try\r
2265     {\r
2266         if(n < 0)\r
2267         {\r
2268             return error(GL_INVALID_VALUE);\r
2269         }\r
2270 \r
2271         rad::Context *context = rad::getContext();\r
2272 \r
2273         if(context)\r
2274         {\r
2275             for(int i = 0; i < n; i++)\r
2276             {\r
2277                 buffers[i] = context->createBuffer();\r
2278             }\r
2279         }\r
2280     }\r
2281     catch(std::bad_alloc&)\r
2282     {\r
2283         return error(GL_OUT_OF_MEMORY);\r
2284     }\r
2285 }\r
2286 \r
2287 void GL_APIENTRY glGenerateMipmap(GLenum target)\r
2288 {\r
2289     TRACE("(GLenum target = 0x%X)", target);\r
2290 \r
2291     try\r
2292     {\r
2293         rad::Context *context = rad::getContext();\r
2294 \r
2295         if(context)\r
2296         {\r
2297             rad::Texture *texture;\r
2298 \r
2299             switch(target)\r
2300             {\r
2301               case GL_TEXTURE_2D:\r
2302                 texture = context->getTexture2D();\r
2303                 break;\r
2304               case GL_TEXTURE_CUBE_MAP:\r
2305                 texture = context->getTextureCubeMap();\r
2306                 break;\r
2307               default:\r
2308                 return error(GL_INVALID_ENUM);\r
2309             }\r
2310 \r
2311             if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))\r
2312             {\r
2313                 return error(GL_INVALID_OPERATION);\r
2314             }\r
2315 \r
2316             texture->generateMipmaps();\r
2317         }\r
2318     }\r
2319     catch(std::bad_alloc&)\r
2320     {\r
2321         return error(GL_OUT_OF_MEMORY);\r
2322     }\r
2323 }\r
2324 \r
2325 void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)\r
2326 {\r
2327     TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);\r
2328 \r
2329     try\r
2330     {\r
2331         if(n < 0)\r
2332         {\r
2333             return error(GL_INVALID_VALUE);\r
2334         }\r
2335 \r
2336         rad::Context *context = rad::getContext();\r
2337 \r
2338         if(context)\r
2339         {\r
2340             for(int i = 0; i < n; i++)\r
2341             {\r
2342                 fences[i] = context->createFence();\r
2343             }\r
2344         }\r
2345     }\r
2346     catch(std::bad_alloc&)\r
2347     {\r
2348         return error(GL_OUT_OF_MEMORY);\r
2349     }\r
2350 }\r
2351 \r
2352 void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)\r
2353 {\r
2354     TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);\r
2355 \r
2356     try\r
2357     {\r
2358         if(n < 0)\r
2359         {\r
2360             return error(GL_INVALID_VALUE);\r
2361         }\r
2362 \r
2363         rad::Context *context = rad::getContext();\r
2364 \r
2365         if(context)\r
2366         {\r
2367             for(int i = 0; i < n; i++)\r
2368             {\r
2369                 framebuffers[i] = context->createFramebuffer();\r
2370             }\r
2371         }\r
2372     }\r
2373     catch(std::bad_alloc&)\r
2374     {\r
2375         return error(GL_OUT_OF_MEMORY);\r
2376     }\r
2377 }\r
2378 \r
2379 void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)\r
2380 {\r
2381     TRACE("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);\r
2382 \r
2383     try\r
2384     {\r
2385         if(n < 0)\r
2386         {\r
2387             return error(GL_INVALID_VALUE);\r
2388         }\r
2389 \r
2390         rad::Context *context = rad::getContext();\r
2391 \r
2392         if(context)\r
2393         {\r
2394             for(int i = 0; i < n; i++)\r
2395             {\r
2396                 ids[i] = context->createQuery();\r
2397             }\r
2398         }\r
2399     }\r
2400     catch(std::bad_alloc&)\r
2401     {\r
2402         return error(GL_OUT_OF_MEMORY);\r
2403     }\r
2404 }\r
2405 \r
2406 void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)\r
2407 {\r
2408     TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);\r
2409 \r
2410     try\r
2411     {\r
2412         if(n < 0)\r
2413         {\r
2414             return error(GL_INVALID_VALUE);\r
2415         }\r
2416 \r
2417         rad::Context *context = rad::getContext();\r
2418 \r
2419         if(context)\r
2420         {\r
2421             for(int i = 0; i < n; i++)\r
2422             {\r
2423                 renderbuffers[i] = context->createRenderbuffer();\r
2424             }\r
2425         }\r
2426     }\r
2427     catch(std::bad_alloc&)\r
2428     {\r
2429         return error(GL_OUT_OF_MEMORY);\r
2430     }\r
2431 }\r
2432 \r
2433 void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)\r
2434 {\r
2435     TRACE("(GLsizei n = %d, GLuint* textures =  0x%0.8p)", n, textures);\r
2436 \r
2437     try\r
2438     {\r
2439         if(n < 0)\r
2440         {\r
2441             return error(GL_INVALID_VALUE);\r
2442         }\r
2443 \r
2444         rad::Context *context = rad::getContext();\r
2445 \r
2446         if(context)\r
2447         {\r
2448             for(int i = 0; i < n; i++)\r
2449             {\r
2450                 textures[i] = context->createTexture();\r
2451             }\r
2452         }\r
2453     }\r
2454     catch(std::bad_alloc&)\r
2455     {\r
2456         return error(GL_OUT_OF_MEMORY);\r
2457     }\r
2458 }\r
2459 \r
2460 void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)\r
2461 {\r
2462     TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "\r
2463           "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",\r
2464           program, index, bufsize, length, size, type, name);\r
2465 \r
2466     try\r
2467     {\r
2468         if(bufsize < 0)\r
2469         {\r
2470             return error(GL_INVALID_VALUE);\r
2471         }\r
2472 \r
2473         rad::Context *context = rad::getContext();\r
2474 \r
2475         if(context)\r
2476         {\r
2477             rad::Program *programObject = context->getProgram(program);\r
2478 \r
2479             if(!programObject)\r
2480             {\r
2481                 if(context->getShader(program))\r
2482                 {\r
2483                     return error(GL_INVALID_OPERATION);\r
2484                 }\r
2485                 else\r
2486                 {\r
2487                     return error(GL_INVALID_VALUE);\r
2488                 }\r
2489             }\r
2490 \r
2491             if(index >= (GLuint)programObject->getActiveAttributeCount())\r
2492             {\r
2493                 return error(GL_INVALID_VALUE);\r
2494             }\r
2495 \r
2496             programObject->getActiveAttribute(index, bufsize, length, size, type, name);\r
2497         }\r
2498     }\r
2499     catch(std::bad_alloc&)\r
2500     {\r
2501         return error(GL_OUT_OF_MEMORY);\r
2502     }\r
2503 }\r
2504 \r
2505 void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)\r
2506 {\r
2507     TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "\r
2508           "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",\r
2509           program, index, bufsize, length, size, type, name);\r
2510 \r
2511     try\r
2512     {\r
2513         if(bufsize < 0)\r
2514         {\r
2515             return error(GL_INVALID_VALUE);\r
2516         }\r
2517 \r
2518         rad::Context *context = rad::getContext();\r
2519 \r
2520         if(context)\r
2521         {\r
2522             rad::Program *programObject = context->getProgram(program);\r
2523 \r
2524             if(!programObject)\r
2525             {\r
2526                 if(context->getShader(program))\r
2527                 {\r
2528                     return error(GL_INVALID_OPERATION);\r
2529                 }\r
2530                 else\r
2531                 {\r
2532                     return error(GL_INVALID_VALUE);\r
2533                 }\r
2534             }\r
2535 \r
2536             if(index >= (GLuint)programObject->getActiveUniformCount())\r
2537             {\r
2538                 return error(GL_INVALID_VALUE);\r
2539             }\r
2540 \r
2541             programObject->getActiveUniform(index, bufsize, length, size, type, name);\r
2542         }\r
2543     }\r
2544     catch(std::bad_alloc&)\r
2545     {\r
2546         return error(GL_OUT_OF_MEMORY);\r
2547     }\r
2548 }\r
2549 \r
2550 void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)\r
2551 {\r
2552     TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",\r
2553           program, maxcount, count, shaders);\r
2554 \r
2555     try\r
2556     {\r
2557         if(maxcount < 0)\r
2558         {\r
2559             return error(GL_INVALID_VALUE);\r
2560         }\r
2561 \r
2562         rad::Context *context = rad::getContext();\r
2563 \r
2564         if(context)\r
2565         {\r
2566             rad::Program *programObject = context->getProgram(program);\r
2567 \r
2568             if(!programObject)\r
2569             {\r
2570                 if(context->getShader(program))\r
2571                 {\r
2572                     return error(GL_INVALID_OPERATION);\r
2573                 }\r
2574                 else\r
2575                 {\r
2576                     return error(GL_INVALID_VALUE);\r
2577                 }\r
2578             }\r
2579 \r
2580             return programObject->getAttachedShaders(maxcount, count, shaders);\r
2581         }\r
2582     }\r
2583     catch(std::bad_alloc&)\r
2584     {\r
2585         return error(GL_OUT_OF_MEMORY);\r
2586     }\r
2587 }\r
2588 \r
2589 int GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)\r
2590 {\r
2591     TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);\r
2592 \r
2593     try\r
2594     {\r
2595         rad::Context *context = rad::getContext();\r
2596 \r
2597         if(context)\r
2598         {\r
2599 \r
2600             rad::Program *programObject = context->getProgram(program);\r
2601 \r
2602             if(!programObject)\r
2603             {\r
2604                 if(context->getShader(program))\r
2605                 {\r
2606                     return error(GL_INVALID_OPERATION, -1);\r
2607                 }\r
2608                 else\r
2609                 {\r
2610                     return error(GL_INVALID_VALUE, -1);\r
2611                 }\r
2612             }\r
2613 \r
2614             if(!programObject->isLinked())\r
2615             {\r
2616                 return error(GL_INVALID_OPERATION, -1);\r
2617             }\r
2618 \r
2619             return programObject->getAttributeLocation(name);\r
2620         }\r
2621     }\r
2622     catch(std::bad_alloc&)\r
2623     {\r
2624         return error(GL_OUT_OF_MEMORY, -1);\r
2625     }\r
2626 \r
2627     return -1;\r
2628 }\r
2629 \r
2630 void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)\r
2631 {\r
2632     TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)",  pname, params);\r
2633 \r
2634     try\r
2635     {\r
2636         rad::Context *context = rad::getContext();\r
2637 \r
2638         if(context)\r
2639         {\r
2640             if(!(context->getBooleanv(pname, params)))\r
2641             {\r
2642                 GLenum nativeType;\r
2643                 unsigned int numParams = 0;\r
2644                 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))\r
2645                     return error(GL_INVALID_ENUM);\r
2646 \r
2647                 if(numParams == 0)\r
2648                     return; // it is known that the pname is valid, but there are no parameters to return\r
2649 \r
2650                 if(nativeType == GL_FLOAT)\r
2651                 {\r
2652                     GLfloat *floatParams = NULL;\r
2653                     floatParams = new GLfloat[numParams];\r
2654 \r
2655                     context->getFloatv(pname, floatParams);\r
2656 \r
2657                     for(unsigned int i = 0; i < numParams; ++i)\r
2658                     {\r
2659                         if(floatParams[i] == 0.0f)\r
2660                             params[i] = GL_FALSE;\r
2661                         else\r
2662                             params[i] = GL_TRUE;\r
2663                     }\r
2664 \r
2665                     delete [] floatParams;\r
2666                 }\r
2667                 else if(nativeType == GL_INT)\r
2668                 {\r
2669                     GLint *intParams = NULL;\r
2670                     intParams = new GLint[numParams];\r
2671 \r
2672                     context->getIntegerv(pname, intParams);\r
2673 \r
2674                     for(unsigned int i = 0; i < numParams; ++i)\r
2675                     {\r
2676                         if(intParams[i] == 0)\r
2677                             params[i] = GL_FALSE;\r
2678                         else\r
2679                             params[i] = GL_TRUE;\r
2680                     }\r
2681 \r
2682                     delete [] intParams;\r
2683                 }\r
2684             }\r
2685         }\r
2686     }\r
2687     catch(std::bad_alloc&)\r
2688     {\r
2689         return error(GL_OUT_OF_MEMORY);\r
2690     }\r
2691 }\r
2692 \r
2693 void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)\r
2694 {\r
2695     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);\r
2696 \r
2697     try\r
2698     {\r
2699         rad::Context *context = rad::getContext();\r
2700 \r
2701         if(context)\r
2702         {\r
2703             rad::Buffer *buffer;\r
2704 \r
2705             switch(target)\r
2706             {\r
2707               case GL_ARRAY_BUFFER:\r
2708                 buffer = context->getArrayBuffer();\r
2709                 break;\r
2710               case GL_ELEMENT_ARRAY_BUFFER:\r
2711                 buffer = context->getElementArrayBuffer();\r
2712                 break;\r
2713               default: return error(GL_INVALID_ENUM);\r
2714             }\r
2715 \r
2716             if(!buffer)\r
2717             {\r
2718                 // A null buffer means that "0" is bound to the requested buffer target\r
2719                 return error(GL_INVALID_OPERATION);\r
2720             }\r
2721 \r
2722             switch(pname)\r
2723             {\r
2724               case GL_BUFFER_USAGE:\r
2725                 *params = buffer->usage();\r
2726                 break;\r
2727               case GL_BUFFER_SIZE:\r
2728                 *params = buffer->size();\r
2729                 break;\r
2730               default: return error(GL_INVALID_ENUM);\r
2731             }\r
2732         }\r
2733     }\r
2734     catch(std::bad_alloc&)\r
2735     {\r
2736         return error(GL_OUT_OF_MEMORY);\r
2737     }\r
2738 }\r
2739 \r
2740 GLenum GL_APIENTRY glGetError(void)\r
2741 {\r
2742     TRACE("()");\r
2743 \r
2744     rad::Context *context = rad::getContext();\r
2745 \r
2746     if(context)\r
2747     {\r
2748         return context->getError();\r
2749     }\r
2750 \r
2751     return GL_NO_ERROR;\r
2752 }\r
2753 \r
2754 void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)\r
2755 {\r
2756     TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);\r
2757 \r
2758     try\r
2759     {\r
2760         rad::Context *context = rad::getContext();\r
2761 \r
2762         if(context)\r
2763         {\r
2764             rad::Fence *fenceObject = context->getFence(fence);\r
2765 \r
2766             if(fenceObject == NULL)\r
2767             {\r
2768                 return error(GL_INVALID_OPERATION);\r
2769             }\r
2770 \r
2771             fenceObject->getFenceiv(pname, params);\r
2772         }\r
2773     }\r
2774     catch(std::bad_alloc&)\r
2775     {\r
2776         return error(GL_OUT_OF_MEMORY);\r
2777     }\r
2778 }\r
2779 \r
2780 void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)\r
2781 {\r
2782     TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);\r
2783 \r
2784     try\r
2785     {\r
2786         rad::Context *context = rad::getContext();\r
2787 \r
2788         if(context)\r
2789         {\r
2790             if(!(context->getFloatv(pname, params)))\r
2791             {\r
2792                 GLenum nativeType;\r
2793                 unsigned int numParams = 0;\r
2794                 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))\r
2795                     return error(GL_INVALID_ENUM);\r
2796 \r
2797                 if(numParams == 0)\r
2798                     return; // it is known that the pname is valid, but that there are no parameters to return.\r
2799 \r
2800                 if(nativeType == GL_BOOL)\r
2801                 {\r
2802                     GLboolean *boolParams = NULL;\r
2803                     boolParams = new GLboolean[numParams];\r
2804 \r
2805                     context->getBooleanv(pname, boolParams);\r
2806 \r
2807                     for(unsigned int i = 0; i < numParams; ++i)\r
2808                     {\r
2809                         if(boolParams[i] == GL_FALSE)\r
2810                             params[i] = 0.0f;\r
2811                         else\r
2812                             params[i] = 1.0f;\r
2813                     }\r
2814 \r
2815                     delete [] boolParams;\r
2816                 }\r
2817                 else if(nativeType == GL_INT)\r
2818                 {\r
2819                     GLint *intParams = NULL;\r
2820                     intParams = new GLint[numParams];\r
2821 \r
2822                     context->getIntegerv(pname, intParams);\r
2823 \r
2824                     for(unsigned int i = 0; i < numParams; ++i)\r
2825                     {\r
2826                         params[i] = (GLfloat)intParams[i];\r
2827                     }\r
2828 \r
2829                     delete [] intParams;\r
2830                 }\r
2831             }\r
2832         }\r
2833     }\r
2834     catch(std::bad_alloc&)\r
2835     {\r
2836         return error(GL_OUT_OF_MEMORY);\r
2837     }\r
2838 }\r
2839 \r
2840 void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)\r
2841 {\r
2842     TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",\r
2843           target, attachment, pname, params);\r
2844 \r
2845     try\r
2846     {\r
2847         rad::Context *context = rad::getContext();\r
2848 \r
2849         if(context)\r
2850         {\r
2851             if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)\r
2852             {\r
2853                 return error(GL_INVALID_ENUM);\r
2854             }\r
2855 \r
2856             rad::Framebuffer *framebuffer = NULL;\r
2857             if(target == GL_READ_FRAMEBUFFER_ANGLE)\r
2858             {\r
2859                 if(context->getReadFramebufferHandle() == 0)\r
2860                 {\r
2861                     return error(GL_INVALID_OPERATION);\r
2862                 }\r
2863 \r
2864                 framebuffer = context->getReadFramebuffer();\r
2865             }\r
2866             else \r
2867             {\r
2868                 if(context->getDrawFramebufferHandle() == 0)\r
2869                 {\r
2870                     return error(GL_INVALID_OPERATION);\r
2871                 }\r
2872 \r
2873                 framebuffer = context->getDrawFramebuffer();\r
2874             }\r
2875 \r
2876             GLenum attachmentType;\r
2877             GLuint attachmentHandle;\r
2878             switch(attachment)\r
2879             {\r
2880               case GL_COLOR_ATTACHMENT0:    \r
2881                 attachmentType = framebuffer->getColorbufferType();\r
2882                 attachmentHandle = framebuffer->getColorbufferHandle(); \r
2883                 break;\r
2884               case GL_DEPTH_ATTACHMENT:     \r
2885                 attachmentType = framebuffer->getDepthbufferType();\r
2886                 attachmentHandle = framebuffer->getDepthbufferHandle();\r
2887                 break;\r
2888               case GL_STENCIL_ATTACHMENT:   \r
2889                 attachmentType = framebuffer->getStencilbufferType();\r
2890                 attachmentHandle = framebuffer->getStencilbufferHandle();\r
2891                 break;\r
2892               default: return error(GL_INVALID_ENUM);\r
2893             }\r
2894 \r
2895             GLenum attachmentObjectType;   // Type category\r
2896             if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)\r
2897             {\r
2898                 attachmentObjectType = attachmentType;\r
2899             }\r
2900             else if(rad::IsTextureTarget(attachmentType))\r
2901             {\r
2902                 attachmentObjectType = GL_TEXTURE;\r
2903             }\r
2904             else UNREACHABLE();\r
2905 \r
2906             switch(pname)\r
2907             {\r
2908               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:\r
2909                 *params = attachmentObjectType;\r
2910                 break;\r
2911               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:\r
2912                 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)\r
2913                 {\r
2914                     *params = attachmentHandle;\r
2915                 }\r
2916                 else\r
2917                 {\r
2918                     return error(GL_INVALID_ENUM);\r
2919                 }\r
2920                 break;\r
2921               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:\r
2922                 if(attachmentObjectType == GL_TEXTURE)\r
2923                 {\r
2924                     *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0\r
2925                 }\r
2926                 else\r
2927                 {\r
2928                     return error(GL_INVALID_ENUM);\r
2929                 }\r
2930                 break;\r
2931               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:\r
2932                 if(attachmentObjectType == GL_TEXTURE)\r
2933                 {\r
2934                     if(rad::IsCubemapTextureTarget(attachmentType))\r
2935                     {\r
2936                         *params = attachmentType;\r
2937                     }\r
2938                     else\r
2939                     {\r
2940                         *params = 0;\r
2941                     }\r
2942                 }\r
2943                 else\r
2944                 {\r
2945                     return error(GL_INVALID_ENUM);\r
2946                 }\r
2947                 break;\r
2948               default:\r
2949                 return error(GL_INVALID_ENUM);\r
2950             }\r
2951         }\r
2952     }\r
2953     catch(std::bad_alloc&)\r
2954     {\r
2955         return error(GL_OUT_OF_MEMORY);\r
2956     }\r
2957 }\r
2958 \r
2959 GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void)\r
2960 {\r
2961     TRACE("()");\r
2962 \r
2963     return GL_NO_ERROR;\r
2964 }\r
2965 \r
2966 void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)\r
2967 {\r
2968     TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);\r
2969 \r
2970     try\r
2971     {\r
2972         rad::Context *context = rad::getContext();\r
2973 \r
2974         if(context)\r
2975         {\r
2976             if(!(context->getIntegerv(pname, params)))\r
2977             {\r
2978                 GLenum nativeType;\r
2979                 unsigned int numParams = 0;\r
2980                 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))\r
2981                     return error(GL_INVALID_ENUM);\r
2982 \r
2983                 if(numParams == 0)\r
2984                     return; // it is known that pname is valid, but there are no parameters to return\r
2985 \r
2986                 if(nativeType == GL_BOOL)\r
2987                 {\r
2988                     GLboolean *boolParams = NULL;\r
2989                     boolParams = new GLboolean[numParams];\r
2990 \r
2991                     context->getBooleanv(pname, boolParams);\r
2992 \r
2993                     for(unsigned int i = 0; i < numParams; ++i)\r
2994                     {\r
2995                         if(boolParams[i] == GL_FALSE)\r
2996                             params[i] = 0;\r
2997                         else\r
2998                             params[i] = 1;\r
2999                     }\r
3000 \r
3001                     delete [] boolParams;\r
3002                 }\r
3003                 else if(nativeType == GL_FLOAT)\r
3004                 {\r
3005                     GLfloat *floatParams = NULL;\r
3006                     floatParams = new GLfloat[numParams];\r
3007 \r
3008                     context->getFloatv(pname, floatParams);\r
3009 \r
3010                     for(unsigned int i = 0; i < numParams; ++i)\r
3011                     {\r
3012                         if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)\r
3013                         {\r
3014                             params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);\r
3015                         }\r
3016                         else\r
3017                             params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));\r
3018                     }\r
3019 \r
3020                     delete [] floatParams;\r
3021                 }\r
3022             }\r
3023         }\r
3024     }\r
3025     catch(std::bad_alloc&)\r
3026     {\r
3027         return error(GL_OUT_OF_MEMORY);\r
3028     }\r
3029 }\r
3030 \r
3031 void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)\r
3032 {\r
3033     TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);\r
3034 \r
3035     try\r
3036     {\r
3037         rad::Context *context = rad::getContext();\r
3038 \r
3039         if(context)\r
3040         {\r
3041             rad::Program *programObject = context->getProgram(program);\r
3042 \r
3043             if(!programObject)\r
3044             {\r
3045                 return error(GL_INVALID_VALUE);\r
3046             }\r
3047 \r
3048             switch(pname)\r
3049             {\r
3050               case GL_DELETE_STATUS:\r
3051                 *params = programObject->isFlaggedForDeletion();\r
3052                 return;\r
3053               case GL_LINK_STATUS:\r
3054                 *params = programObject->isLinked();\r
3055                 return;\r
3056               case GL_VALIDATE_STATUS:\r
3057                 *params = programObject->isValidated();\r
3058                 return;\r
3059               case GL_INFO_LOG_LENGTH:\r
3060                 *params = programObject->getInfoLogLength();\r
3061                 return;\r
3062               case GL_ATTACHED_SHADERS:\r
3063                 *params = programObject->getAttachedShadersCount();\r
3064                 return;\r
3065               case GL_ACTIVE_ATTRIBUTES:\r
3066                 *params = programObject->getActiveAttributeCount();\r
3067                 return;\r
3068               case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:\r
3069                 *params = programObject->getActiveAttributeMaxLength();\r
3070                 return;\r
3071               case GL_ACTIVE_UNIFORMS:\r
3072                 *params = programObject->getActiveUniformCount();\r
3073                 return;\r
3074               case GL_ACTIVE_UNIFORM_MAX_LENGTH:\r
3075                 *params = programObject->getActiveUniformMaxLength();\r
3076                 return;\r
3077               default:\r
3078                 return error(GL_INVALID_ENUM);\r
3079             }\r
3080         }\r
3081     }\r
3082     catch(std::bad_alloc&)\r
3083     {\r
3084         return error(GL_OUT_OF_MEMORY);\r
3085     }\r
3086 }\r
3087 \r
3088 void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)\r
3089 {\r
3090     TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",\r
3091           program, bufsize, length, infolog);\r
3092 \r
3093     try\r
3094     {\r
3095         if(bufsize < 0)\r
3096         {\r
3097             return error(GL_INVALID_VALUE);\r
3098         }\r
3099 \r
3100         rad::Context *context = rad::getContext();\r
3101 \r
3102         if(context)\r
3103         {\r
3104             rad::Program *programObject = context->getProgram(program);\r
3105 \r
3106             if(!programObject)\r
3107             {\r
3108                 return error(GL_INVALID_VALUE);\r
3109             }\r
3110 \r
3111             programObject->getInfoLog(bufsize, length, infolog);\r
3112         }\r
3113     }\r
3114     catch(std::bad_alloc&)\r
3115     {\r
3116         return error(GL_OUT_OF_MEMORY);\r
3117     }\r
3118 }\r
3119 \r
3120 void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)\r
3121 {\r
3122     TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);\r
3123 \r
3124     try\r
3125     {\r
3126         switch(pname)\r
3127         {\r
3128         case GL_CURRENT_QUERY_EXT:\r
3129             break;\r
3130         default:\r
3131             return error(GL_INVALID_ENUM);\r
3132         }\r
3133 \r
3134         rad::Context *context = rad::getContext();\r
3135 \r
3136         if(context)\r
3137         {\r
3138             params[0] = context->getActiveQuery(target);\r
3139         }\r
3140     }\r
3141     catch(std::bad_alloc&)\r
3142     {\r
3143         return error(GL_OUT_OF_MEMORY);\r
3144     }\r
3145 }\r
3146 \r
3147 void GL_APIENTRY glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)\r
3148 {\r
3149     TRACE("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);\r
3150 \r
3151     try\r
3152     {\r
3153         switch(pname)\r
3154         {\r
3155         case GL_QUERY_RESULT_EXT:\r
3156         case GL_QUERY_RESULT_AVAILABLE_EXT:\r
3157             break;\r
3158         default:\r
3159             return error(GL_INVALID_ENUM);\r
3160         }\r
3161 \r
3162         rad::Context *context = rad::getContext();\r
3163 \r
3164         if(context)\r
3165         {\r
3166             rad::Query *queryObject = context->getQuery(id, false, GL_NONE);\r
3167 \r
3168             if(!queryObject)\r
3169             {\r
3170                 return error(GL_INVALID_OPERATION);\r
3171             }\r
3172 \r
3173             if(context->getActiveQuery(queryObject->getType()) == id)\r
3174             {\r
3175                 return error(GL_INVALID_OPERATION);\r
3176             }\r
3177 \r
3178             switch(pname)\r
3179             {\r
3180             case GL_QUERY_RESULT_EXT:\r
3181                 params[0] = queryObject->getResult();\r
3182                 break;\r
3183             case GL_QUERY_RESULT_AVAILABLE_EXT:\r
3184                 params[0] = queryObject->isResultAvailable();\r
3185                 break;\r
3186             default:\r
3187                 ASSERT(false);\r
3188             }\r
3189         }\r
3190     }\r
3191     catch(std::bad_alloc&)\r
3192     {\r
3193         return error(GL_OUT_OF_MEMORY);\r
3194     }\r
3195 }\r
3196 \r
3197 void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)\r
3198 {\r
3199     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);\r
3200 \r
3201     try\r
3202     {\r
3203         rad::Context *context = rad::getContext();\r
3204 \r
3205         if(context)\r
3206         {\r
3207             if(target != GL_RENDERBUFFER)\r
3208             {\r
3209                 return error(GL_INVALID_ENUM);\r
3210             }\r
3211 \r
3212             if(context->getRenderbufferHandle() == 0)\r
3213             {\r
3214                 return error(GL_INVALID_OPERATION);\r
3215             }\r
3216 \r
3217             rad::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());\r
3218 \r
3219             switch(pname)\r
3220             {\r
3221             case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;\r
3222             case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;\r
3223             case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat();      break;\r
3224             case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;\r
3225             case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;\r
3226             case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;\r
3227             case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;\r
3228             case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;\r
3229             case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;\r
3230             case GL_RENDERBUFFER_SAMPLES_ANGLE:   *params = renderbuffer->getSamples();     break;\r
3231             default:\r
3232                 return error(GL_INVALID_ENUM);\r
3233             }\r
3234         }\r
3235     }\r
3236     catch(std::bad_alloc&)\r
3237     {\r
3238         return error(GL_OUT_OF_MEMORY);\r
3239     }\r
3240 }\r
3241 \r
3242 void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)\r
3243 {\r
3244     TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);\r
3245 \r
3246     try\r
3247     {\r
3248         rad::Context *context = rad::getContext();\r
3249 \r
3250         if(context)\r
3251         {\r
3252             rad::Shader *shaderObject = context->getShader(shader);\r
3253 \r
3254             if(!shaderObject)\r
3255             {\r
3256                 return error(GL_INVALID_VALUE);\r
3257             }\r
3258 \r
3259             switch(pname)\r
3260             {\r
3261               case GL_SHADER_TYPE:\r
3262                 *params = shaderObject->getType();\r
3263                 return;\r
3264               case GL_DELETE_STATUS:\r
3265                 *params = shaderObject->isFlaggedForDeletion();\r
3266                 return;\r
3267               case GL_COMPILE_STATUS:\r
3268                 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;\r
3269                 return;\r
3270               case GL_INFO_LOG_LENGTH:\r
3271                 *params = shaderObject->getInfoLogLength();\r
3272                 return;\r
3273               case GL_SHADER_SOURCE_LENGTH:\r
3274                 *params = shaderObject->getSourceLength();\r
3275                 return;\r
3276               default:\r
3277                 return error(GL_INVALID_ENUM);\r
3278             }\r
3279         }\r
3280     }\r
3281     catch(std::bad_alloc&)\r
3282     {\r
3283         return error(GL_OUT_OF_MEMORY);\r
3284     }\r
3285 }\r
3286 \r
3287 void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)\r
3288 {\r
3289     TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",\r
3290           shader, bufsize, length, infolog);\r
3291 \r
3292     try\r
3293     {\r
3294         if(bufsize < 0)\r
3295         {\r
3296             return error(GL_INVALID_VALUE);\r
3297         }\r
3298 \r
3299         rad::Context *context = rad::getContext();\r
3300 \r
3301         if(context)\r
3302         {\r
3303             rad::Shader *shaderObject = context->getShader(shader);\r
3304 \r
3305             if(!shaderObject)\r
3306             {\r
3307                 return error(GL_INVALID_VALUE);\r
3308             }\r
3309 \r
3310             shaderObject->getInfoLog(bufsize, length, infolog);\r
3311         }\r
3312     }\r
3313     catch(std::bad_alloc&)\r
3314     {\r
3315         return error(GL_OUT_OF_MEMORY);\r
3316     }\r
3317 }\r
3318 \r
3319 void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)\r
3320 {\r
3321     TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",\r
3322           shadertype, precisiontype, range, precision);\r
3323 \r
3324     try\r
3325     {\r
3326         switch(shadertype)\r
3327         {\r
3328           case GL_VERTEX_SHADER:\r
3329           case GL_FRAGMENT_SHADER:\r
3330             break;\r
3331           default:\r
3332             return error(GL_INVALID_ENUM);\r
3333         }\r
3334 \r
3335         switch(precisiontype)\r
3336         {\r
3337           case GL_LOW_FLOAT:\r
3338           case GL_MEDIUM_FLOAT:\r
3339           case GL_HIGH_FLOAT:\r
3340             // IEEE 754 single-precision\r
3341             range[0] = 127;\r
3342             range[1] = 127;\r
3343             *precision = 23;\r
3344             break;\r
3345           case GL_LOW_INT:\r
3346           case GL_MEDIUM_INT:\r
3347           case GL_HIGH_INT:\r
3348             // Single-precision floating-point numbers can accurately represent integers up to +/-16777216\r
3349             range[0] = 24;\r
3350             range[1] = 24;\r
3351             *precision = 0;\r
3352             break;\r
3353           default:\r
3354             return error(GL_INVALID_ENUM);\r
3355         }\r
3356     }\r
3357     catch(std::bad_alloc&)\r
3358     {\r
3359         return error(GL_OUT_OF_MEMORY);\r
3360     }\r
3361 }\r
3362 \r
3363 void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)\r
3364 {\r
3365     TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",\r
3366           shader, bufsize, length, source);\r
3367 \r
3368     try\r
3369     {\r
3370         if(bufsize < 0)\r
3371         {\r
3372             return error(GL_INVALID_VALUE);\r
3373         }\r
3374 \r
3375         rad::Context *context = rad::getContext();\r
3376 \r
3377         if(context)\r
3378         {\r
3379             rad::Shader *shaderObject = context->getShader(shader);\r
3380 \r
3381             if(!shaderObject)\r
3382             {\r
3383                 return error(GL_INVALID_OPERATION);\r
3384             }\r
3385 \r
3386             shaderObject->getSource(bufsize, length, source);\r
3387         }\r
3388     }\r
3389     catch(std::bad_alloc&)\r
3390     {\r
3391         return error(GL_OUT_OF_MEMORY);\r
3392     }\r
3393 }\r
3394 \r
3395 const GLubyte* GL_APIENTRY glGetString(GLenum name)\r
3396 {\r
3397     TRACE("(GLenum name = 0x%X)", name);\r
3398 \r
3399     try\r
3400     {\r
3401         rad::Context *context = rad::getContext();\r
3402 \r
3403         switch(name)\r
3404         {\r
3405         case GL_VENDOR:\r
3406             return (GLubyte*)"TransGaming Inc.";\r
3407         case GL_RENDERER:\r
3408             return (GLubyte*)"SwiftShader";\r
3409         case GL_VERSION:\r
3410             return (GLubyte*)"OpenGL ES 2.0 SwiftShader "VERSION_STRING;\r
3411         case GL_SHADING_LANGUAGE_VERSION:\r
3412             return (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader "VERSION_STRING;\r
3413         case GL_EXTENSIONS:\r
3414             // Keep list sorted in following order:\r
3415                 // OES extensions\r
3416                 // EXT extensions\r
3417                 // Vendor extensions\r
3418             return (GLubyte*)\r
3419                 "GL_OES_depth_texture "\r
3420                 "GL_OES_depth_texture_cube_map "\r
3421                 "GL_OES_EGL_image "\r
3422                 "GL_OES_EGL_image_external "\r
3423                 "GL_OES_element_index_uint "\r
3424                 "GL_OES_packed_depth_stencil "\r
3425                 "GL_OES_rgb8_rgba8 "\r
3426                 "GL_OES_standard_derivatives "\r
3427                 "GL_OES_texture_float "\r
3428                 "GL_OES_texture_float_linear "\r
3429                 "GL_OES_texture_half_float "\r
3430                 "GL_OES_texture_half_float_linear "\r
3431                 "GL_OES_texture_npot "\r
3432                 "GL_EXT_blend_minmax "\r
3433                 "GL_EXT_occlusion_query_boolean "\r
3434                 "GL_EXT_read_format_bgra "\r
3435                    #if (S3TC_SUPPORT)\r
3436                 "GL_EXT_texture_compression_dxt1 "\r
3437                 "GL_ANGLE_texture_compression_dxt3 "\r
3438                 "GL_ANGLE_texture_compression_dxt5 "\r
3439                    #endif\r
3440                 "GL_EXT_texture_filter_anisotropic "\r
3441                 "GL_EXT_texture_format_BGRA8888 "\r
3442                 "GL_ANGLE_framebuffer_blit "\r
3443                 "GL_ANGLE_framebuffer_multisample "\r
3444                 "GL_NV_fence";\r
3445         default:\r
3446             return error(GL_INVALID_ENUM, (GLubyte*)NULL);\r
3447         }\r
3448     }\r
3449     catch(std::bad_alloc&)\r
3450     {\r
3451         return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);\r
3452     }\r
3453 \r
3454     return NULL;\r
3455 }\r
3456 \r
3457 void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)\r
3458 {\r
3459     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);\r
3460 \r
3461     try\r
3462     {\r
3463         rad::Context *context = rad::getContext();\r
3464 \r
3465         if(context)\r
3466         {\r
3467             rad::Texture *texture;\r
3468 \r
3469             switch(target)\r
3470             {\r
3471             case GL_TEXTURE_2D:\r
3472                 texture = context->getTexture2D();\r
3473                 break;\r
3474             case GL_TEXTURE_CUBE_MAP:\r
3475                 texture = context->getTextureCubeMap();\r
3476                 break;\r
3477             case GL_TEXTURE_EXTERNAL_OES:\r
3478                 texture = context->getTextureExternal();\r
3479                 break;\r
3480             default:\r
3481                 return error(GL_INVALID_ENUM);\r
3482             }\r
3483 \r
3484             switch(pname)\r
3485             {\r
3486             case GL_TEXTURE_MAG_FILTER:\r
3487                 *params = (GLfloat)texture->getMagFilter();\r
3488                 break;\r
3489             case GL_TEXTURE_MIN_FILTER:\r
3490                 *params = (GLfloat)texture->getMinFilter();\r
3491                 break;\r
3492             case GL_TEXTURE_WRAP_S:\r
3493                 *params = (GLfloat)texture->getWrapS();\r
3494                 break;\r
3495             case GL_TEXTURE_WRAP_T:\r
3496                 *params = (GLfloat)texture->getWrapT();\r
3497                 break;\r
3498                         case GL_TEXTURE_MAX_ANISOTROPY_EXT:\r
3499                 *params = texture->getMaxAnisotropy();\r
3500                 break;\r
3501             case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:\r
3502                 *params = (GLfloat)1;\r
3503                 break;\r
3504             default:\r
3505                 return error(GL_INVALID_ENUM);\r
3506             }\r
3507         }\r
3508     }\r
3509     catch(std::bad_alloc&)\r
3510     {\r
3511         return error(GL_OUT_OF_MEMORY);\r
3512     }\r
3513 }\r
3514 \r
3515 void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)\r
3516 {\r
3517     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);\r
3518 \r
3519     try\r
3520     {\r
3521         rad::Context *context = rad::getContext();\r
3522 \r
3523         if(context)\r
3524         {\r
3525             rad::Texture *texture;\r
3526 \r
3527             switch(target)\r
3528             {\r
3529             case GL_TEXTURE_2D:\r
3530                 texture = context->getTexture2D();\r
3531                 break;\r
3532             case GL_TEXTURE_CUBE_MAP:\r
3533                 texture = context->getTextureCubeMap();\r
3534                 break;\r
3535             case GL_TEXTURE_EXTERNAL_OES:\r
3536                 texture = context->getTextureExternal();\r
3537                 break;\r
3538             default:\r
3539                 return error(GL_INVALID_ENUM);\r
3540             }\r
3541 \r
3542             switch(pname)\r
3543             {\r
3544             case GL_TEXTURE_MAG_FILTER:\r
3545                 *params = texture->getMagFilter();\r
3546                 break;\r
3547             case GL_TEXTURE_MIN_FILTER:\r
3548                 *params = texture->getMinFilter();\r
3549                 break;\r
3550             case GL_TEXTURE_WRAP_S:\r
3551                 *params = texture->getWrapS();\r
3552                 break;\r
3553             case GL_TEXTURE_WRAP_T:\r
3554                 *params = texture->getWrapT();\r
3555                 break;\r
3556                     case GL_TEXTURE_MAX_ANISOTROPY_EXT:\r
3557                 *params = (GLint)texture->getMaxAnisotropy();\r
3558                 break;\r
3559             case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:\r
3560                 *params = 1;\r
3561                 break;\r
3562             default:\r
3563                 return error(GL_INVALID_ENUM);\r
3564             }\r
3565         }\r
3566     }\r
3567     catch(std::bad_alloc&)\r
3568     {\r
3569         return error(GL_OUT_OF_MEMORY);\r
3570     }\r
3571 }\r
3572 \r
3573 void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)\r
3574 {\r
3575     TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",\r
3576           program, location, bufSize, params);\r
3577 \r
3578     try\r
3579     {\r
3580         if(bufSize < 0)\r
3581         {\r
3582             return error(GL_INVALID_VALUE);\r
3583         }\r
3584 \r
3585         rad::Context *context = rad::getContext();\r
3586 \r
3587         if(context)\r
3588         {\r
3589             if(program == 0)\r
3590             {\r
3591                 return error(GL_INVALID_VALUE);\r
3592             }\r
3593 \r
3594             rad::Program *programObject = context->getProgram(program);\r
3595 \r
3596             if(!programObject || !programObject->isLinked())\r
3597             {\r
3598                 return error(GL_INVALID_OPERATION);\r
3599             }\r
3600 \r
3601             if(!programObject->getUniformfv(location, &bufSize, params))\r
3602             {\r
3603                 return error(GL_INVALID_OPERATION);\r
3604             }\r
3605         }\r
3606     }\r
3607     catch(std::bad_alloc&)\r
3608     {\r
3609         return error(GL_OUT_OF_MEMORY);\r
3610     }\r
3611 }\r
3612 \r
3613 void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)\r
3614 {\r
3615     TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);\r
3616 \r
3617     try\r
3618     {\r
3619         rad::Context *context = rad::getContext();\r
3620 \r
3621         if(context)\r
3622         {\r
3623             if(program == 0)\r
3624             {\r
3625                 return error(GL_INVALID_VALUE);\r
3626             }\r
3627 \r
3628             rad::Program *programObject = context->getProgram(program);\r
3629 \r
3630             if(!programObject || !programObject->isLinked())\r
3631             {\r
3632                 return error(GL_INVALID_OPERATION);\r
3633             }\r
3634 \r
3635             if(!programObject->getUniformfv(location, NULL, params))\r
3636             {\r
3637                 return error(GL_INVALID_OPERATION);\r
3638             }\r
3639         }\r
3640     }\r
3641     catch(std::bad_alloc&)\r
3642     {\r
3643         return error(GL_OUT_OF_MEMORY);\r
3644     }\r
3645 }\r
3646 \r
3647 void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)\r
3648 {\r
3649     TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)", \r
3650           program, location, bufSize, params);\r
3651 \r
3652     try\r
3653     {\r
3654         if(bufSize < 0)\r
3655         {\r
3656             return error(GL_INVALID_VALUE);\r
3657         }\r
3658 \r
3659         rad::Context *context = rad::getContext();\r
3660 \r
3661         if(context)\r
3662         {\r
3663             if(program == 0)\r
3664             {\r
3665                 return error(GL_INVALID_VALUE);\r
3666             }\r
3667 \r
3668             rad::Program *programObject = context->getProgram(program);\r
3669 \r
3670             if(!programObject || !programObject->isLinked())\r
3671             {\r
3672                 return error(GL_INVALID_OPERATION);\r
3673             }\r
3674 \r
3675             if(!programObject)\r
3676             {\r
3677                 return error(GL_INVALID_OPERATION);\r
3678             }\r
3679 \r
3680             if(!programObject->getUniformiv(location, &bufSize, params))\r
3681             {\r
3682                 return error(GL_INVALID_OPERATION);\r
3683             }\r
3684         }\r
3685     }\r
3686     catch(std::bad_alloc&)\r
3687     {\r
3688         return error(GL_OUT_OF_MEMORY);\r
3689     }\r
3690 }\r
3691 \r
3692 void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)\r
3693 {\r
3694     TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);\r
3695 \r
3696     try\r
3697     {\r
3698         rad::Context *context = rad::getContext();\r
3699 \r
3700         if(context)\r
3701         {\r
3702             if(program == 0)\r
3703             {\r
3704                 return error(GL_INVALID_VALUE);\r
3705             }\r
3706 \r
3707             rad::Program *programObject = context->getProgram(program);\r
3708 \r
3709             if(!programObject || !programObject->isLinked())\r
3710             {\r
3711                 return error(GL_INVALID_OPERATION);\r
3712             }\r
3713 \r
3714             if(!programObject)\r
3715             {\r
3716                 return error(GL_INVALID_OPERATION);\r
3717             }\r
3718 \r
3719             if(!programObject->getUniformiv(location, NULL, params))\r
3720             {\r
3721                 return error(GL_INVALID_OPERATION);\r
3722             }\r
3723         }\r
3724     }\r
3725     catch(std::bad_alloc&)\r
3726     {\r
3727         return error(GL_OUT_OF_MEMORY);\r
3728     }\r
3729 }\r
3730 \r
3731 int GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)\r
3732 {\r
3733     TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);\r
3734 \r
3735     try\r
3736     {\r
3737         rad::Context *context = rad::getContext();\r
3738 \r
3739         if(strstr(name, "gl_") == name)\r
3740         {\r
3741             return -1;\r
3742         }\r
3743 \r
3744         if(context)\r
3745         {\r
3746             rad::Program *programObject = context->getProgram(program);\r
3747 \r
3748             if(!programObject)\r
3749             {\r
3750                 if(context->getShader(program))\r
3751                 {\r
3752                     return error(GL_INVALID_OPERATION, -1);\r
3753                 }\r
3754                 else\r
3755                 {\r
3756                     return error(GL_INVALID_VALUE, -1);\r
3757                 }\r
3758             }\r
3759 \r
3760             if(!programObject->isLinked())\r
3761             {\r
3762                 return error(GL_INVALID_OPERATION, -1);\r
3763             }\r
3764 \r
3765             return programObject->getUniformLocation(name);\r
3766         }\r
3767     }\r
3768     catch(std::bad_alloc&)\r
3769     {\r
3770         return error(GL_OUT_OF_MEMORY, -1);\r
3771     }\r
3772 \r
3773     return -1;\r
3774 }\r
3775 \r
3776 void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)\r
3777 {\r
3778     TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);\r
3779 \r
3780     try\r
3781     {\r
3782         rad::Context *context = rad::getContext();\r
3783 \r
3784         if(context)\r
3785         {\r
3786             if(index >= rad::MAX_VERTEX_ATTRIBS)\r
3787             {\r
3788                 return error(GL_INVALID_VALUE);\r
3789             }\r
3790 \r
3791             const rad::VertexAttribute &attribState = context->getVertexAttribState(index);\r
3792 \r
3793             switch(pname)\r
3794             {\r
3795               case GL_VERTEX_ATTRIB_ARRAY_ENABLED:\r
3796                 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);\r
3797                 break;\r
3798               case GL_VERTEX_ATTRIB_ARRAY_SIZE:\r
3799                 *params = (GLfloat)attribState.mSize;\r
3800                 break;\r
3801               case GL_VERTEX_ATTRIB_ARRAY_STRIDE:\r
3802                 *params = (GLfloat)attribState.mStride;\r
3803                 break;\r
3804               case GL_VERTEX_ATTRIB_ARRAY_TYPE:\r
3805                 *params = (GLfloat)attribState.mType;\r
3806                 break;\r
3807               case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:\r
3808                 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);\r
3809                 break;\r
3810               case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:\r
3811                 *params = (GLfloat)attribState.mBoundBuffer.id();\r
3812                 break;\r
3813               case GL_CURRENT_VERTEX_ATTRIB:\r
3814                 for(int i = 0; i < 4; ++i)\r
3815                 {\r
3816                     params[i] = attribState.mCurrentValue[i];\r
3817                 }\r
3818                 break;\r
3819               default: return error(GL_INVALID_ENUM);\r
3820             }\r
3821         }\r
3822     }\r
3823     catch(std::bad_alloc&)\r
3824     {\r
3825         return error(GL_OUT_OF_MEMORY);\r
3826     }\r
3827 }\r
3828 \r
3829 void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)\r
3830 {\r
3831     TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);\r
3832 \r
3833     try\r
3834     {\r
3835         rad::Context *context = rad::getContext();\r
3836 \r
3837         if(context)\r
3838         {\r
3839             if(index >= rad::MAX_VERTEX_ATTRIBS)\r
3840             {\r
3841                 return error(GL_INVALID_VALUE);\r
3842             }\r
3843 \r
3844             const rad::VertexAttribute &attribState = context->getVertexAttribState(index);\r
3845 \r
3846             switch(pname)\r
3847             {\r
3848               case GL_VERTEX_ATTRIB_ARRAY_ENABLED:\r
3849                 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);\r
3850                 break;\r
3851               case GL_VERTEX_ATTRIB_ARRAY_SIZE:\r
3852                 *params = attribState.mSize;\r
3853                 break;\r
3854               case GL_VERTEX_ATTRIB_ARRAY_STRIDE:\r
3855                 *params = attribState.mStride;\r
3856                 break;\r
3857               case GL_VERTEX_ATTRIB_ARRAY_TYPE:\r
3858                 *params = attribState.mType;\r
3859                 break;\r
3860               case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:\r
3861                 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);\r
3862                 break;\r
3863               case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:\r
3864                 *params = attribState.mBoundBuffer.id();\r
3865                 break;\r
3866               case GL_CURRENT_VERTEX_ATTRIB:\r
3867                 for(int i = 0; i < 4; ++i)\r
3868                 {\r
3869                     float currentValue = attribState.mCurrentValue[i];\r
3870                     params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));\r
3871                 }\r
3872                 break;\r
3873               default: return error(GL_INVALID_ENUM);\r
3874             }\r
3875         }\r
3876     }\r
3877     catch(std::bad_alloc&)\r
3878     {\r
3879         return error(GL_OUT_OF_MEMORY);\r
3880     }\r
3881 }\r
3882 \r
3883 void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)\r
3884 {\r
3885     TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);\r
3886 \r
3887     try\r
3888     {\r
3889         rad::Context *context = rad::getContext();\r
3890 \r
3891         if(context)\r
3892         {\r
3893             if(index >= rad::MAX_VERTEX_ATTRIBS)\r
3894             {\r
3895                 return error(GL_INVALID_VALUE);\r
3896             }\r
3897 \r
3898             if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)\r
3899             {\r
3900                 return error(GL_INVALID_ENUM);\r
3901             }\r
3902 \r
3903             *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));\r
3904         }\r
3905     }\r
3906     catch(std::bad_alloc&)\r
3907     {\r
3908         return error(GL_OUT_OF_MEMORY);\r
3909     }\r
3910 }\r
3911 \r
3912 void GL_APIENTRY glHint(GLenum target, GLenum mode)\r
3913 {\r
3914     TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);\r
3915 \r
3916     try\r
3917     {\r
3918         switch(mode)\r
3919         {\r
3920           case GL_FASTEST:\r
3921           case GL_NICEST:\r
3922           case GL_DONT_CARE:\r
3923             break;\r
3924           default:\r
3925             return error(GL_INVALID_ENUM); \r
3926         }\r
3927 \r
3928         rad::Context *context = rad::getContext();\r
3929         switch(target)\r
3930         {\r
3931           case GL_GENERATE_MIPMAP_HINT:\r
3932             if(context) context->setGenerateMipmapHint(mode);\r
3933             break;\r
3934           case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:\r
3935             if(context) context->setFragmentShaderDerivativeHint(mode);\r
3936             break;\r
3937           default:\r
3938             return error(GL_INVALID_ENUM);\r
3939         }\r
3940     }\r
3941     catch(std::bad_alloc&)\r
3942     {\r
3943         return error(GL_OUT_OF_MEMORY);\r
3944     }\r
3945 }\r
3946 \r
3947 GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)\r
3948 {\r
3949     TRACE("(GLuint buffer = %d)", buffer);\r
3950 \r
3951     try\r
3952     {\r
3953         rad::Context *context = rad::getContext();\r
3954 \r
3955         if(context && buffer)\r
3956         {\r
3957             rad::Buffer *bufferObject = context->getBuffer(buffer);\r
3958 \r
3959             if(bufferObject)\r
3960             {\r
3961                 return GL_TRUE;\r
3962             }\r
3963         }\r
3964     }\r
3965     catch(std::bad_alloc&)\r
3966     {\r
3967         return error(GL_OUT_OF_MEMORY, GL_FALSE);\r
3968     }\r
3969 \r
3970     return GL_FALSE;\r
3971 }\r
3972 \r
3973 GLboolean GL_APIENTRY glIsEnabled(GLenum cap)\r
3974 {\r
3975     TRACE("(GLenum cap = 0x%X)", cap);\r
3976 \r
3977     try\r
3978     {\r
3979         rad::Context *context = rad::getContext();\r
3980 \r
3981         if(context)\r
3982         {\r
3983             switch(cap)\r
3984             {\r
3985               case GL_CULL_FACE:                return context->isCullFaceEnabled();\r
3986               case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();\r
3987               case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();\r
3988               case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();\r
3989               case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();\r
3990               case GL_STENCIL_TEST:             return context->isStencilTestEnabled();\r
3991               case GL_DEPTH_TEST:               return context->isDepthTestEnabled();\r
3992               case GL_BLEND:                    return context->isBlendEnabled();\r
3993               case GL_DITHER:                   return context->isDitherEnabled();\r
3994               default:\r
3995                 return error(GL_INVALID_ENUM, false);\r
3996             }\r
3997         }\r
3998     }\r
3999     catch(std::bad_alloc&)\r
4000     {\r
4001         return error(GL_OUT_OF_MEMORY, false);\r
4002     }\r
4003 \r
4004     return false;\r
4005 }\r
4006 \r
4007 GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)\r
4008 {\r
4009     TRACE("(GLuint fence = %d)", fence);\r
4010 \r
4011     try\r
4012     {\r
4013         rad::Context *context = rad::getContext();\r
4014 \r
4015         if(context)\r
4016         {\r
4017             rad::Fence *fenceObject = context->getFence(fence);\r
4018 \r
4019             if(fenceObject == NULL)\r
4020             {\r
4021                 return GL_FALSE;\r
4022             }\r
4023 \r
4024             return fenceObject->isFence();\r
4025         }\r
4026     }\r
4027     catch(std::bad_alloc&)\r
4028     {\r
4029         return error(GL_OUT_OF_MEMORY, GL_FALSE);\r
4030     }\r
4031 \r
4032     return GL_FALSE;\r
4033 }\r
4034 \r
4035 GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)\r
4036 {\r
4037     TRACE("(GLuint framebuffer = %d)", framebuffer);\r
4038 \r
4039     try\r
4040     {\r
4041         rad::Context *context = rad::getContext();\r
4042 \r
4043         if(context && framebuffer)\r
4044         {\r
4045             rad::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);\r
4046 \r
4047             if(framebufferObject)\r
4048             {\r
4049                 return GL_TRUE;\r
4050             }\r
4051         }\r
4052     }\r
4053     catch(std::bad_alloc&)\r
4054     {\r
4055         return error(GL_OUT_OF_MEMORY, GL_FALSE);\r
4056     }\r
4057 \r
4058     return GL_FALSE;\r
4059 }\r
4060 \r
4061 GLboolean GL_APIENTRY glIsProgram(GLuint program)\r
4062 {\r
4063     TRACE("(GLuint program = %d)", program);\r
4064 \r
4065     try\r
4066     {\r
4067         rad::Context *context = rad::getContext();\r
4068 \r
4069         if(context && program)\r
4070         {\r
4071             rad::Program *programObject = context->getProgram(program);\r
4072 \r
4073             if(programObject)\r
4074             {\r
4075                 return GL_TRUE;\r
4076             }\r
4077         }\r
4078     }\r
4079     catch(std::bad_alloc&)\r
4080     {\r
4081         return error(GL_OUT_OF_MEMORY, GL_FALSE);\r
4082     }\r
4083 \r
4084     return GL_FALSE;\r
4085 }\r
4086 \r
4087 GLboolean GL_APIENTRY glIsQueryEXT(GLuint id)\r
4088 {\r
4089     TRACE("(GLuint id = %d)", id);\r
4090 \r
4091     try\r
4092     {\r
4093         if(id == 0)\r
4094         {\r
4095             return GL_FALSE;\r
4096         }\r
4097 \r
4098         rad::Context *context = rad::getContext();\r
4099 \r
4100         if(context)\r
4101         {\r
4102             rad::Query *queryObject = context->getQuery(id, false, GL_NONE);\r
4103 \r
4104             if(queryObject)\r
4105             {\r
4106                 return GL_TRUE;\r
4107             }\r
4108         }\r
4109     }\r
4110     catch(std::bad_alloc&)\r
4111     {\r
4112         return error(GL_OUT_OF_MEMORY, GL_FALSE);\r
4113     }\r
4114 \r
4115     return GL_FALSE;\r
4116 }\r
4117 \r
4118 GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)\r
4119 {\r
4120     TRACE("(GLuint renderbuffer = %d)", renderbuffer);\r
4121 \r
4122     try\r
4123     {\r
4124         rad::Context *context = rad::getContext();\r
4125 \r
4126         if(context && renderbuffer)\r
4127         {\r
4128             rad::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);\r
4129 \r
4130             if(renderbufferObject)\r
4131             {\r
4132                 return GL_TRUE;\r
4133             }\r
4134         }\r
4135     }\r
4136     catch(std::bad_alloc&)\r
4137     {\r
4138         return error(GL_OUT_OF_MEMORY, GL_FALSE);\r
4139     }\r
4140 \r
4141     return GL_FALSE;\r
4142 }\r
4143 \r
4144 GLboolean GL_APIENTRY glIsShader(GLuint shader)\r
4145 {\r
4146     TRACE("(GLuint shader = %d)", shader);\r
4147 \r
4148     try\r
4149     {\r
4150         rad::Context *context = rad::getContext();\r
4151 \r
4152         if(context && shader)\r
4153         {\r
4154             rad::Shader *shaderObject = context->getShader(shader);\r
4155 \r
4156             if(shaderObject)\r
4157             {\r
4158                 return GL_TRUE;\r
4159             }\r
4160         }\r
4161     }\r
4162     catch(std::bad_alloc&)\r
4163     {\r
4164         return error(GL_OUT_OF_MEMORY, GL_FALSE);\r
4165     }\r
4166 \r
4167     return GL_FALSE;\r
4168 }\r
4169 \r
4170 GLboolean GL_APIENTRY glIsTexture(GLuint texture)\r
4171 {\r
4172     TRACE("(GLuint texture = %d)", texture);\r
4173 \r
4174     try\r
4175     {\r
4176         rad::Context *context = rad::getContext();\r
4177 \r
4178         if(context && texture)\r
4179         {\r
4180             rad::Texture *textureObject = context->getTexture(texture);\r
4181 \r
4182             if(textureObject)\r
4183             {\r
4184                 return GL_TRUE;\r
4185             }\r
4186         }\r
4187     }\r
4188     catch(std::bad_alloc&)\r
4189     {\r
4190         return error(GL_OUT_OF_MEMORY, GL_FALSE);\r
4191     }\r
4192 \r
4193     return GL_FALSE;\r
4194 }\r
4195 \r
4196 void GL_APIENTRY glLineWidth(GLfloat width)\r
4197 {\r
4198     TRACE("(GLfloat width = %f)", width);\r
4199 \r
4200     try\r
4201     {\r
4202         if(width <= 0.0f)\r
4203         {\r
4204             return error(GL_INVALID_VALUE);\r
4205         }\r
4206 \r
4207         rad::Context *context = rad::getContext();\r
4208 \r
4209         if(context)\r
4210         {\r
4211             context->setLineWidth(width);\r
4212         }\r
4213     }\r
4214     catch(std::bad_alloc&)\r
4215     {\r
4216         return error(GL_OUT_OF_MEMORY);\r
4217     }\r
4218 }\r
4219 \r
4220 void GL_APIENTRY glLinkProgram(GLuint program)\r
4221 {\r
4222     TRACE("(GLuint program = %d)", program);\r
4223 \r
4224     try\r
4225     {\r
4226         rad::Context *context = rad::getContext();\r
4227 \r
4228         if(context)\r
4229         {\r
4230             rad::Program *programObject = context->getProgram(program);\r
4231 \r
4232             if(!programObject)\r
4233             {\r
4234                 if(context->getShader(program))\r
4235                 {\r
4236                     return error(GL_INVALID_OPERATION);\r
4237                 }\r
4238                 else\r
4239                 {\r
4240                     return error(GL_INVALID_VALUE);\r
4241                 }\r
4242             }\r
4243 \r
4244             programObject->link();\r
4245         }\r
4246     }\r
4247     catch(std::bad_alloc&)\r
4248     {\r
4249         return error(GL_OUT_OF_MEMORY);\r
4250     }\r
4251 }\r
4252 \r
4253 void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)\r
4254 {\r
4255     TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);\r
4256 \r
4257     try\r
4258     {\r
4259         rad::Context *context = rad::getContext();\r
4260 \r
4261         if(context)\r
4262         {\r
4263             switch(pname)\r
4264             {\r
4265               case GL_UNPACK_ALIGNMENT:\r
4266                 if(param != 1 && param != 2 && param != 4 && param != 8)\r
4267                 {\r
4268                     return error(GL_INVALID_VALUE);\r
4269                 }\r
4270 \r
4271                 context->setUnpackAlignment(param);\r
4272                 break;\r
4273 \r
4274               case GL_PACK_ALIGNMENT:\r
4275                 if(param != 1 && param != 2 && param != 4 && param != 8)\r
4276                 {\r
4277                     return error(GL_INVALID_VALUE);\r
4278                 }\r
4279 \r
4280                 context->setPackAlignment(param);\r
4281                 break;\r
4282 \r
4283               default:\r
4284                 return error(GL_INVALID_ENUM);\r
4285             }\r
4286         }\r
4287     }\r
4288     catch(std::bad_alloc&)\r
4289     {\r
4290         return error(GL_OUT_OF_MEMORY);\r
4291     }\r
4292 }\r
4293 \r
4294 void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)\r
4295 {\r
4296     TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);\r
4297 \r
4298     try\r
4299     {\r
4300         rad::Context *context = rad::getContext();\r
4301 \r
4302         if(context)\r
4303         {\r
4304             context->setPolygonOffsetParams(factor, units);\r
4305         }\r
4306     }\r
4307     catch(std::bad_alloc&)\r
4308     {\r
4309         return error(GL_OUT_OF_MEMORY);\r
4310     }\r
4311 }\r
4312 \r
4313 void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,\r
4314                                 GLenum format, GLenum type, GLsizei bufSize,\r
4315                                 GLvoid *data)\r
4316 {\r
4317     TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "\r
4318           "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",\r
4319           x, y, width, height, format, type, bufSize, data);\r
4320 \r
4321     try\r
4322     {\r
4323         if(width < 0 || height < 0 || bufSize < 0)\r
4324         {\r
4325             return error(GL_INVALID_VALUE);\r
4326         }\r
4327 \r
4328         if(!validReadFormatType(format, type))\r
4329         {\r
4330             return error(GL_INVALID_OPERATION);\r
4331         }\r
4332 \r
4333         rad::Context *context = rad::getContext();\r
4334 \r
4335         if(context)\r
4336         {\r
4337             context->readPixels(x, y, width, height, format, type, &bufSize, data);\r
4338         }\r
4339     }\r
4340     catch(std::bad_alloc&)\r
4341     {\r
4342         return error(GL_OUT_OF_MEMORY);\r
4343     }\r
4344 }\r
4345 \r
4346 void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)\r
4347 {\r
4348     TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "\r
4349           "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",\r
4350           x, y, width, height, format, type,  pixels);\r
4351 \r
4352     try\r
4353     {\r
4354         if(width < 0 || height < 0)\r
4355         {\r
4356             return error(GL_INVALID_VALUE);\r
4357         }\r
4358 \r
4359         if(!validReadFormatType(format, type))\r
4360         {\r
4361             return error(GL_INVALID_OPERATION);\r
4362         }\r
4363 \r
4364         rad::Context *context = rad::getContext();\r
4365 \r
4366         if(context)\r
4367         {\r
4368             context->readPixels(x, y, width, height, format, type, NULL, pixels);\r
4369         }\r
4370     }\r
4371     catch(std::bad_alloc&)\r
4372     {\r
4373         return error(GL_OUT_OF_MEMORY);\r
4374     }\r
4375 }\r
4376 \r
4377 void GL_APIENTRY glReleaseShaderCompiler(void)\r
4378 {\r
4379     TRACE("()");\r
4380 \r
4381     try\r
4382     {\r
4383         rad::Shader::releaseCompiler();\r
4384     }\r
4385     catch(std::bad_alloc&)\r
4386     {\r
4387         return error(GL_OUT_OF_MEMORY);\r
4388     }\r
4389 }\r
4390 \r
4391 void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)\r
4392 {\r
4393     TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",\r
4394           target, samples, internalformat, width, height);\r
4395 \r
4396     try\r
4397     {\r
4398         switch(target)\r
4399         {\r
4400           case GL_RENDERBUFFER:\r
4401             break;\r
4402           default:\r
4403             return error(GL_INVALID_ENUM);\r
4404         }\r
4405 \r
4406         if(!rad::IsColorRenderable(internalformat) && !rad::IsDepthRenderable(internalformat) && !rad::IsStencilRenderable(internalformat))\r
4407         {\r
4408             return error(GL_INVALID_ENUM);\r
4409         }\r
4410 \r
4411         if(width < 0 || height < 0 || samples < 0)\r
4412         {\r
4413             return error(GL_INVALID_VALUE);\r
4414         }\r
4415 \r
4416         rad::Context *context = rad::getContext();\r
4417 \r
4418         if(context)\r
4419         {\r
4420             if(width > rad::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE || \r
4421                height > rad::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||\r
4422                samples > rad::IMPLEMENTATION_MAX_SAMPLES)\r
4423             {\r
4424                 return error(GL_INVALID_VALUE);\r
4425             }\r
4426 \r
4427             GLuint handle = context->getRenderbufferHandle();\r
4428             if(handle == 0)\r
4429             {\r
4430                 return error(GL_INVALID_OPERATION);\r
4431             }\r
4432 \r
4433             switch(internalformat)\r
4434             {\r
4435               case GL_DEPTH_COMPONENT16:\r
4436                 context->setRenderbufferStorage(new rad::Depthbuffer(width, height, samples));\r
4437                 break;\r
4438               case GL_RGBA4:\r
4439               case GL_RGB5_A1:\r
4440               case GL_RGB565:\r
4441               case GL_RGB8_OES:\r
4442               case GL_RGBA8_OES:\r
4443                 context->setRenderbufferStorage(new rad::Colorbuffer(width, height, internalformat, samples));\r
4444                 break;\r
4445               case GL_STENCIL_INDEX8:\r
4446                 context->setRenderbufferStorage(new rad::Stencilbuffer(width, height, samples));\r
4447                 break;\r
4448               case GL_DEPTH24_STENCIL8_OES:\r
4449                 context->setRenderbufferStorage(new rad::DepthStencilbuffer(width, height, samples));\r
4450                 break;\r
4451               default:\r
4452                 return error(GL_INVALID_ENUM);\r
4453             }\r
4454         }\r
4455     }\r
4456     catch(std::bad_alloc&)\r
4457     {\r
4458         return error(GL_OUT_OF_MEMORY);\r
4459     }\r
4460 }\r
4461 \r
4462 void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)\r
4463 {\r
4464     glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);\r
4465 }\r
4466 \r
4467 void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)\r
4468 {\r
4469     TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);\r
4470 \r
4471     try\r
4472     {\r
4473         rad::Context* context = rad::getContext();\r
4474 \r
4475         if(context)\r
4476         {\r
4477             context->setSampleCoverageParams(rad::clamp01(value), invert == GL_TRUE);\r
4478         }\r
4479     }\r
4480     catch(std::bad_alloc&)\r
4481     {\r
4482         return error(GL_OUT_OF_MEMORY);\r
4483     }\r
4484 }\r
4485 \r
4486 void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)\r
4487 {\r
4488     TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);\r
4489 \r
4490     try\r
4491     {\r
4492         if(condition != GL_ALL_COMPLETED_NV)\r
4493         {\r
4494             return error(GL_INVALID_ENUM);\r
4495         }\r
4496 \r
4497         rad::Context *context = rad::getContext();\r
4498 \r
4499         if(context)\r
4500         {\r
4501             rad::Fence *fenceObject = context->getFence(fence);\r
4502 \r
4503             if(fenceObject == NULL)\r
4504             {\r
4505                 return error(GL_INVALID_OPERATION);\r
4506             }\r
4507 \r
4508             fenceObject->setFence(condition);    \r
4509         }\r
4510     }\r
4511     catch(std::bad_alloc&)\r
4512     {\r
4513         return error(GL_OUT_OF_MEMORY);\r
4514     }\r
4515 }\r
4516 \r
4517 void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)\r
4518 {\r
4519     TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);\r
4520 \r
4521     try\r
4522     {\r
4523         if(width < 0 || height < 0)\r
4524         {\r
4525             return error(GL_INVALID_VALUE);\r
4526         }\r
4527 \r
4528         rad::Context* context = rad::getContext();\r
4529 \r
4530         if(context)\r
4531         {\r
4532             context->setScissorParams(x, y, width, height);\r
4533         }\r
4534     }\r
4535     catch(std::bad_alloc&)\r
4536     {\r
4537         return error(GL_OUT_OF_MEMORY);\r
4538     }\r
4539 }\r
4540 \r
4541 void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)\r
4542 {\r
4543     TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "\r
4544           "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",\r
4545           n, shaders, binaryformat, binary, length);\r
4546 \r
4547     try\r
4548     {\r
4549         // No binary shader formats are supported.\r
4550         return error(GL_INVALID_ENUM);\r
4551     }\r
4552     catch(std::bad_alloc&)\r
4553     {\r
4554         return error(GL_OUT_OF_MEMORY);\r
4555     }\r
4556 }\r
4557 \r
4558 void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)\r
4559 {\r
4560     TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",\r
4561           shader, count, string, length);\r
4562 \r
4563     try\r
4564     {\r
4565         if(count < 0)\r
4566         {\r
4567             return error(GL_INVALID_VALUE);\r
4568         }\r
4569 \r
4570         rad::Context *context = rad::getContext();\r
4571 \r
4572         if(context)\r
4573         {\r
4574             rad::Shader *shaderObject = context->getShader(shader);\r
4575 \r
4576             if(!shaderObject)\r
4577             {\r
4578                 if(context->getProgram(shader))\r
4579                 {\r
4580                     return error(GL_INVALID_OPERATION);\r
4581                 }\r
4582                 else\r
4583                 {\r
4584                     return error(GL_INVALID_VALUE);\r
4585                 }\r
4586             }\r
4587 \r
4588             shaderObject->setSource(count, string, length);\r
4589         }\r
4590     }\r
4591     catch(std::bad_alloc&)\r
4592     {\r
4593         return error(GL_OUT_OF_MEMORY);\r
4594     }\r
4595 }\r
4596 \r
4597 void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)\r
4598 {\r
4599     glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);\r
4600 }\r
4601 \r
4602 void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)\r
4603 {\r
4604     TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);\r
4605 \r
4606     try\r
4607     {\r
4608         switch(face)\r
4609         {\r
4610           case GL_FRONT:\r
4611           case GL_BACK:\r
4612           case GL_FRONT_AND_BACK:\r
4613             break;\r
4614           default:\r
4615             return error(GL_INVALID_ENUM);\r
4616         }\r
4617 \r
4618         switch(func)\r
4619         {\r
4620           case GL_NEVER:\r
4621           case GL_ALWAYS:\r
4622           case GL_LESS:\r
4623           case GL_LEQUAL:\r
4624           case GL_EQUAL:\r
4625           case GL_GEQUAL:\r
4626           case GL_GREATER:\r
4627           case GL_NOTEQUAL:\r
4628             break;\r
4629           default:\r
4630             return error(GL_INVALID_ENUM);\r
4631         }\r
4632 \r
4633         rad::Context *context = rad::getContext();\r
4634 \r
4635         if(context)\r
4636         {\r
4637             if(face == GL_FRONT || face == GL_FRONT_AND_BACK)\r
4638             {\r
4639                 context->setStencilParams(func, ref, mask);\r
4640             }\r
4641 \r
4642             if(face == GL_BACK || face == GL_FRONT_AND_BACK)\r
4643             {\r
4644                 context->setStencilBackParams(func, ref, mask);\r
4645             }\r
4646         }\r
4647     }\r
4648     catch(std::bad_alloc&)\r
4649     {\r
4650         return error(GL_OUT_OF_MEMORY);\r
4651     }\r
4652 }\r
4653 \r
4654 void GL_APIENTRY glStencilMask(GLuint mask)\r
4655 {\r
4656     glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);\r
4657 }\r
4658 \r
4659 void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)\r
4660 {\r
4661     TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);\r
4662 \r
4663     try\r
4664     {\r
4665         switch(face)\r
4666         {\r
4667           case GL_FRONT:\r
4668           case GL_BACK:\r
4669           case GL_FRONT_AND_BACK:\r
4670             break;\r
4671           default:\r
4672             return error(GL_INVALID_ENUM);\r
4673         }\r
4674 \r
4675         rad::Context *context = rad::getContext();\r
4676 \r
4677         if(context)\r
4678         {\r
4679             if(face == GL_FRONT || face == GL_FRONT_AND_BACK)\r
4680             {\r
4681                 context->setStencilWritemask(mask);\r
4682             }\r
4683 \r
4684             if(face == GL_BACK || face == GL_FRONT_AND_BACK)\r
4685             {\r
4686                 context->setStencilBackWritemask(mask);\r
4687             }\r
4688         }\r
4689     }\r
4690     catch(std::bad_alloc&)\r
4691     {\r
4692         return error(GL_OUT_OF_MEMORY);\r
4693     }\r
4694 }\r
4695 \r
4696 void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)\r
4697 {\r
4698     glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);\r
4699 }\r
4700 \r
4701 void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)\r
4702 {\r
4703     TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",\r
4704           face, fail, zfail, zpass);\r
4705 \r
4706     try\r
4707     {\r
4708         switch(face)\r
4709         {\r
4710           case GL_FRONT:\r
4711           case GL_BACK:\r
4712           case GL_FRONT_AND_BACK:\r
4713             break;\r
4714           default:\r
4715             return error(GL_INVALID_ENUM);\r
4716         }\r
4717 \r
4718         switch(fail)\r
4719         {\r
4720           case GL_ZERO:\r
4721           case GL_KEEP:\r
4722           case GL_REPLACE:\r
4723           case GL_INCR:\r
4724           case GL_DECR:\r
4725           case GL_INVERT:\r
4726           case GL_INCR_WRAP:\r
4727           case GL_DECR_WRAP:\r
4728             break;\r
4729           default:\r
4730             return error(GL_INVALID_ENUM);\r
4731         }\r
4732 \r
4733         switch(zfail)\r
4734         {\r
4735           case GL_ZERO:\r
4736           case GL_KEEP:\r
4737           case GL_REPLACE:\r
4738           case GL_INCR:\r
4739           case GL_DECR:\r
4740           case GL_INVERT:\r
4741           case GL_INCR_WRAP:\r
4742           case GL_DECR_WRAP:\r
4743             break;\r
4744           default:\r
4745             return error(GL_INVALID_ENUM);\r
4746         }\r
4747 \r
4748         switch(zpass)\r
4749         {\r
4750           case GL_ZERO:\r
4751           case GL_KEEP:\r
4752           case GL_REPLACE:\r
4753           case GL_INCR:\r
4754           case GL_DECR:\r
4755           case GL_INVERT:\r
4756           case GL_INCR_WRAP:\r
4757           case GL_DECR_WRAP:\r
4758             break;\r
4759           default:\r
4760             return error(GL_INVALID_ENUM);\r
4761         }\r
4762 \r
4763         rad::Context *context = rad::getContext();\r
4764 \r
4765         if(context)\r
4766         {\r
4767             if(face == GL_FRONT || face == GL_FRONT_AND_BACK)\r
4768             {\r
4769                 context->setStencilOperations(fail, zfail, zpass);\r
4770             }\r
4771 \r
4772             if(face == GL_BACK || face == GL_FRONT_AND_BACK)\r
4773             {\r
4774                 context->setStencilBackOperations(fail, zfail, zpass);\r
4775             }\r
4776         }\r
4777     }\r
4778     catch(std::bad_alloc&)\r
4779     {\r
4780         return error(GL_OUT_OF_MEMORY);\r
4781     }\r
4782 }\r
4783 \r
4784 GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)\r
4785 {\r
4786     TRACE("(GLuint fence = %d)", fence);\r
4787 \r
4788     try\r
4789     {\r
4790         rad::Context *context = rad::getContext();\r
4791 \r
4792         if(context)\r
4793         {\r
4794             rad::Fence *fenceObject = context->getFence(fence);\r
4795 \r
4796             if(fenceObject == NULL)\r
4797             {\r
4798                 return error(GL_INVALID_OPERATION, GL_TRUE);\r
4799             }\r
4800 \r
4801             return fenceObject->testFence();\r
4802         }\r
4803     }\r
4804     catch(std::bad_alloc&)\r
4805     {\r
4806         error(GL_OUT_OF_MEMORY);\r
4807     }\r
4808     \r
4809     return GL_TRUE;\r
4810 }\r
4811 \r
4812 void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,\r
4813                               GLint border, GLenum format, GLenum type, const GLvoid* pixels)\r
4814 {\r
4815     TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "\r
4816           "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  0x%0.8p)",\r
4817           target, level, internalformat, width, height, border, format, type, pixels);\r
4818 \r
4819     try\r
4820     {\r
4821         if(!validImageSize(level, width, height))\r
4822         {\r
4823             return error(GL_INVALID_VALUE);\r
4824         }\r
4825 \r
4826         if(internalformat != format)\r
4827         {\r
4828             return error(GL_INVALID_OPERATION);\r
4829         }\r
4830 \r
4831         switch(format)\r
4832         {\r
4833         case GL_ALPHA:\r
4834         case GL_LUMINANCE:\r
4835         case GL_LUMINANCE_ALPHA:\r
4836             switch(type)\r
4837             {\r
4838             case GL_UNSIGNED_BYTE:\r
4839             case GL_FLOAT:\r
4840             case GL_HALF_FLOAT_OES:\r
4841                 break;\r
4842             default:\r
4843                 return error(GL_INVALID_ENUM);\r
4844             }\r
4845             break;\r
4846         case GL_RGB:\r
4847             switch(type)\r
4848             {\r
4849             case GL_UNSIGNED_BYTE:\r
4850             case GL_UNSIGNED_SHORT_5_6_5:\r
4851             case GL_FLOAT:\r
4852             case GL_HALF_FLOAT_OES:\r
4853                 break;\r
4854             default:\r
4855                 return error(GL_INVALID_ENUM);\r
4856             }\r
4857             break;\r
4858         case GL_RGBA:\r
4859             switch(type)\r
4860             {\r
4861             case GL_UNSIGNED_BYTE:\r
4862             case GL_UNSIGNED_SHORT_4_4_4_4:\r
4863             case GL_UNSIGNED_SHORT_5_5_5_1:\r
4864             case GL_FLOAT:\r
4865             case GL_HALF_FLOAT_OES:\r
4866                 break;\r
4867             default:\r
4868                 return error(GL_INVALID_ENUM);\r
4869             }\r
4870             break;\r
4871         case GL_BGRA_EXT:\r
4872             switch(type)\r
4873             {\r
4874             case GL_UNSIGNED_BYTE:\r
4875                 break;\r
4876             default:\r
4877                 return error(GL_INVALID_ENUM);\r
4878             }\r
4879             break;\r
4880         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:  // error cases for compressed textures are handled below\r
4881         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:\r
4882                 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:\r
4883                 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:\r
4884             break;\r
4885                 case GL_DEPTH_COMPONENT:\r
4886                         switch(type)\r
4887                         {\r
4888                         case GL_UNSIGNED_SHORT:\r
4889                         case GL_UNSIGNED_INT:\r
4890                                 break;\r
4891                         default:\r
4892                                 return error(GL_INVALID_ENUM);\r
4893                         }\r
4894                         break;\r
4895                 case GL_DEPTH_STENCIL_OES:\r
4896                         switch(type)\r
4897                         {\r
4898                         case GL_UNSIGNED_INT_24_8_OES:\r
4899                                 break;\r
4900                         default:\r
4901                                 return error(GL_INVALID_ENUM);\r
4902                         }\r
4903                         break;\r
4904         default:\r
4905             return error(GL_INVALID_VALUE);\r
4906         }\r
4907 \r
4908         if(border != 0)\r
4909         {\r
4910             return error(GL_INVALID_VALUE);\r
4911         }\r
4912 \r
4913         rad::Context *context = rad::getContext();\r
4914 \r
4915         if(context)\r
4916         {\r
4917             switch(target)\r
4918             {\r
4919               case GL_TEXTURE_2D:\r
4920                 if(width > (rad::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||\r
4921                    height > (rad::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))\r
4922                 {\r
4923                     return error(GL_INVALID_VALUE);\r
4924                 }\r
4925                 break;\r
4926               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:\r
4927               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:\r
4928               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:\r
4929               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:\r
4930               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:\r
4931               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:\r
4932                 if(width != height)\r
4933                 {\r
4934                     return error(GL_INVALID_VALUE);\r
4935                 }\r
4936 \r
4937                 if(width > (rad::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||\r
4938                    height > (rad::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))\r
4939                 {\r
4940                     return error(GL_INVALID_VALUE);\r
4941                 }\r
4942                 break;\r
4943               default:\r
4944                 return error(GL_INVALID_ENUM);\r
4945             }\r
4946 \r
4947             if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||\r
4948                format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||\r
4949                            format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE ||\r
4950                            format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE)\r
4951             {\r
4952                 if(S3TC_SUPPORT)\r
4953                 {\r
4954                     return error(GL_INVALID_OPERATION);\r
4955                 }\r
4956                 else\r
4957                 {\r
4958                     return error(GL_INVALID_ENUM);\r
4959                 }\r
4960             }\r
4961                         \r
4962             if(target == GL_TEXTURE_2D)\r
4963             {\r
4964                 rad::Texture2D *texture = context->getTexture2D();\r
4965 \r
4966                 if(!texture)\r
4967                 {\r
4968                     return error(GL_INVALID_OPERATION);\r
4969                 }\r
4970 \r
4971                 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);\r
4972             }\r
4973             else\r
4974             {\r
4975                 rad::TextureCubeMap *texture = context->getTextureCubeMap();\r
4976 \r
4977                 if(!texture)\r
4978                 {\r
4979                     return error(GL_INVALID_OPERATION);\r
4980                 }\r
4981 \r
4982                                 texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);\r
4983             }\r
4984         }\r
4985     }\r
4986     catch(std::bad_alloc&)\r
4987     {\r
4988         return error(GL_OUT_OF_MEMORY);\r
4989     }\r
4990 }\r
4991 \r
4992 void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)\r
4993 {\r
4994     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);\r
4995 \r
4996     try\r
4997     {\r
4998         rad::Context *context = rad::getContext();\r
4999 \r
5000         if(context)\r
5001         {\r
5002             rad::Texture *texture;\r
5003 \r
5004             switch(target)\r
5005             {\r
5006             case GL_TEXTURE_2D:\r
5007                 texture = context->getTexture2D();\r
5008                 break;\r
5009             case GL_TEXTURE_CUBE_MAP:\r
5010                 texture = context->getTextureCubeMap();\r
5011                 break;\r
5012             case GL_TEXTURE_EXTERNAL_OES:\r
5013                 texture = context->getTextureExternal();\r
5014                 break;\r
5015             default:\r
5016                 return error(GL_INVALID_ENUM);\r
5017             }\r
5018 \r
5019             switch(pname)\r
5020             {\r
5021             case GL_TEXTURE_WRAP_S:\r
5022                 if(!texture->setWrapS((GLenum)param))\r
5023                 {\r
5024                     return error(GL_INVALID_ENUM);\r
5025                 }\r
5026                 break;\r
5027             case GL_TEXTURE_WRAP_T:\r
5028                 if(!texture->setWrapT((GLenum)param))\r
5029                 {\r
5030                     return error(GL_INVALID_ENUM);\r
5031                 }\r
5032                 break;\r
5033             case GL_TEXTURE_MIN_FILTER:\r
5034                 if(!texture->setMinFilter((GLenum)param))\r
5035                 {\r
5036                     return error(GL_INVALID_ENUM);\r
5037                 }\r
5038                 break;\r
5039             case GL_TEXTURE_MAG_FILTER:\r
5040                 if(!texture->setMagFilter((GLenum)param))\r
5041                 {\r
5042                     return error(GL_INVALID_ENUM);\r
5043                 }\r
5044                 break;\r
5045             case GL_TEXTURE_MAX_ANISOTROPY_EXT:\r
5046                 if(!texture->setMaxAnisotropy(param))\r
5047                 {\r
5048                     return error(GL_INVALID_VALUE);\r
5049                 }\r
5050                 break;\r
5051             default:\r
5052                 return error(GL_INVALID_ENUM);\r
5053             }\r
5054         }\r
5055     }\r
5056     catch(std::bad_alloc&)\r
5057     {\r
5058         return error(GL_OUT_OF_MEMORY);\r
5059     }\r
5060 }\r
5061 \r
5062 void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)\r
5063 {\r
5064     glTexParameterf(target, pname, *params);\r
5065 }\r
5066 \r
5067 void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)\r
5068 {\r
5069     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);\r
5070 \r
5071     try\r
5072     {\r
5073         rad::Context *context = rad::getContext();\r
5074 \r
5075         if(context)\r
5076         {\r
5077             rad::Texture *texture;\r
5078 \r
5079             switch(target)\r
5080             {\r
5081             case GL_TEXTURE_2D:\r
5082                 texture = context->getTexture2D();\r
5083                 break;\r
5084             case GL_TEXTURE_CUBE_MAP:\r
5085                 texture = context->getTextureCubeMap();\r
5086                 break;\r
5087             case GL_TEXTURE_EXTERNAL_OES:\r
5088                   texture = context->getTextureExternal();\r
5089                   break;\r
5090             default:\r
5091                 return error(GL_INVALID_ENUM);\r
5092             }\r
5093 \r
5094             switch(pname)\r
5095             {\r
5096             case GL_TEXTURE_WRAP_S:\r
5097                 if(!texture->setWrapS((GLenum)param))\r
5098                 {\r
5099                     return error(GL_INVALID_ENUM);\r
5100                 }\r
5101                 break;\r
5102             case GL_TEXTURE_WRAP_T:\r
5103                 if(!texture->setWrapT((GLenum)param))\r
5104                 {\r
5105                     return error(GL_INVALID_ENUM);\r
5106                 }\r
5107                 break;\r
5108             case GL_TEXTURE_MIN_FILTER:\r
5109                 if(!texture->setMinFilter((GLenum)param))\r
5110                 {\r
5111                     return error(GL_INVALID_ENUM);\r
5112                 }\r
5113                 break;\r
5114             case GL_TEXTURE_MAG_FILTER:\r
5115                 if(!texture->setMagFilter((GLenum)param))\r
5116                 {\r
5117                     return error(GL_INVALID_ENUM);\r
5118                 }\r
5119                 break;\r
5120                         case GL_TEXTURE_MAX_ANISOTROPY_EXT:\r
5121                 if(!texture->setMaxAnisotropy((GLfloat)param))\r
5122                 {\r
5123                     return error(GL_INVALID_VALUE);\r
5124                 }\r
5125                 break;\r
5126             default:\r
5127                 return error(GL_INVALID_ENUM);\r
5128             }\r
5129         }\r
5130     }\r
5131     catch(std::bad_alloc&)\r
5132     {\r
5133         return error(GL_OUT_OF_MEMORY);\r
5134     }\r
5135 }\r
5136 \r
5137 void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)\r
5138 {\r
5139     glTexParameteri(target, pname, *params);\r
5140 }\r
5141 \r
5142 void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,\r
5143                                GLenum format, GLenum type, const GLvoid* pixels)\r
5144 {\r
5145     TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "\r
5146           "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "\r
5147           "const GLvoid* pixels = 0x%0.8p)",\r
5148            target, level, xoffset, yoffset, width, height, format, type, pixels);\r
5149 \r
5150     try\r
5151     {\r
5152         if(!rad::IsTextureTarget(target))\r
5153         {\r
5154             return error(GL_INVALID_ENUM);\r
5155         }\r
5156 \r
5157         if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)\r
5158         {\r
5159             return error(GL_INVALID_VALUE);\r
5160         }\r
5161 \r
5162         if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)\r
5163         {\r
5164             return error(GL_INVALID_VALUE);\r
5165         }\r
5166 \r
5167         if(!rad::CheckTextureFormatType(format, type))\r
5168         {\r
5169             return error(GL_INVALID_ENUM);\r
5170         }\r
5171 \r
5172         if(width == 0 || height == 0 || pixels == NULL)\r
5173         {\r
5174             return;\r
5175         }\r
5176 \r
5177         rad::Context *context = rad::getContext();\r
5178 \r
5179         if(context)\r
5180         {\r
5181             if(level > rad::IMPLEMENTATION_MAX_TEXTURE_LEVELS)\r
5182             {\r
5183                 return error(GL_INVALID_VALUE);\r
5184             }\r
5185 \r
5186             if(target == GL_TEXTURE_2D)\r
5187             {\r
5188                 rad::Texture2D *texture = context->getTexture2D();\r
5189 \r
5190                 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))\r
5191                                 {\r
5192                                         texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);\r
5193                                 }\r
5194             }\r
5195             else if(rad::IsCubemapTextureTarget(target))\r
5196             {\r
5197                 rad::TextureCubeMap *texture = context->getTextureCubeMap();\r
5198                                 \r
5199                                 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))\r
5200                                 {\r
5201                                         texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);\r
5202                                 }\r
5203             }\r
5204             else\r
5205             {\r
5206                 UNREACHABLE();\r
5207             }\r
5208         }\r
5209     }\r
5210     catch(std::bad_alloc&)\r
5211     {\r
5212         return error(GL_OUT_OF_MEMORY);\r
5213     }\r
5214 }\r
5215 \r
5216 void GL_APIENTRY glUniform1f(GLint location, GLfloat x)\r
5217 {\r
5218     glUniform1fv(location, 1, &x);\r
5219 }\r
5220 \r
5221 void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)\r
5222 {\r
5223     TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);\r
5224 \r
5225     try\r
5226     {\r
5227         if(count < 0)\r
5228         {\r
5229             return error(GL_INVALID_VALUE);\r
5230         }\r
5231 \r
5232         if(location == -1)\r
5233         {\r
5234             return;\r
5235         }\r
5236 \r
5237         rad::Context *context = rad::getContext();\r
5238 \r
5239         if(context)\r
5240         {\r
5241             rad::Program *program = context->getCurrentProgram();\r
5242 \r
5243             if(!program)\r
5244             {\r
5245                 return error(GL_INVALID_OPERATION);\r
5246             }\r
5247 \r
5248             if(!program->setUniform1fv(location, count, v))\r
5249             {\r
5250                 return error(GL_INVALID_OPERATION);\r
5251             }\r
5252         }\r
5253     }\r
5254     catch(std::bad_alloc&)\r
5255     {\r
5256         return error(GL_OUT_OF_MEMORY);\r
5257     }\r
5258 }\r
5259 \r
5260 void GL_APIENTRY glUniform1i(GLint location, GLint x)\r
5261 {\r
5262     glUniform1iv(location, 1, &x);\r
5263 }\r
5264 \r
5265 void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)\r
5266 {\r
5267     TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);\r
5268 \r
5269     try\r
5270     {\r
5271         if(count < 0)\r
5272         {\r
5273             return error(GL_INVALID_VALUE);\r
5274         }\r
5275 \r
5276         if(location == -1)\r
5277         {\r
5278             return;\r
5279         }\r
5280 \r
5281         rad::Context *context = rad::getContext();\r
5282 \r
5283         if(context)\r
5284         {\r
5285             rad::Program *program = context->getCurrentProgram();\r
5286 \r
5287             if(!program)\r
5288             {\r
5289                 return error(GL_INVALID_OPERATION);\r
5290             }\r
5291 \r
5292             if(!program->setUniform1iv(location, count, v))\r
5293             {\r
5294                 return error(GL_INVALID_OPERATION);\r
5295             }\r
5296         }\r
5297     }\r
5298     catch(std::bad_alloc&)\r
5299     {\r
5300         return error(GL_OUT_OF_MEMORY);\r
5301     }\r
5302 }\r
5303 \r
5304 void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)\r
5305 {\r
5306     GLfloat xy[2] = {x, y};\r
5307 \r
5308     glUniform2fv(location, 1, (GLfloat*)&xy);\r
5309 }\r
5310 \r
5311 void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)\r
5312 {\r
5313     TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);\r
5314 \r
5315     try\r
5316     {\r
5317         if(count < 0)\r
5318         {\r
5319             return error(GL_INVALID_VALUE);\r
5320         }\r
5321         \r
5322         if(location == -1)\r
5323         {\r
5324             return;\r
5325         }\r
5326 \r
5327         rad::Context *context = rad::getContext();\r
5328 \r
5329         if(context)\r
5330         {\r
5331             rad::Program *program = context->getCurrentProgram();\r
5332 \r
5333             if(!program)\r
5334             {\r
5335                 return error(GL_INVALID_OPERATION);\r
5336             }\r
5337 \r
5338             if(!program->setUniform2fv(location, count, v))\r
5339             {\r
5340                 return error(GL_INVALID_OPERATION);\r
5341             }\r
5342         }\r
5343     }\r
5344     catch(std::bad_alloc&)\r
5345     {\r
5346         return error(GL_OUT_OF_MEMORY);\r
5347     }\r
5348 }\r
5349 \r
5350 void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y)\r
5351 {\r
5352     GLint xy[4] = {x, y};\r
5353 \r
5354     glUniform2iv(location, 1, (GLint*)&xy);\r
5355 }\r
5356 \r
5357 void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)\r
5358 {\r
5359     TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);\r
5360 \r
5361     try\r
5362     {\r
5363         if(count < 0)\r
5364         {\r
5365             return error(GL_INVALID_VALUE);\r
5366         }\r
5367 \r
5368         if(location == -1)\r
5369         {\r
5370             return;\r
5371         }\r
5372 \r
5373         rad::Context *context = rad::getContext();\r
5374 \r
5375         if(context)\r
5376         {\r
5377             rad::Program *program = context->getCurrentProgram();\r
5378 \r
5379             if(!program)\r
5380             {\r
5381                 return error(GL_INVALID_OPERATION);\r
5382             }\r
5383 \r
5384             if(!program->setUniform2iv(location, count, v))\r
5385             {\r
5386                 return error(GL_INVALID_OPERATION);\r
5387             }\r
5388         }\r
5389     }\r
5390     catch(std::bad_alloc&)\r
5391     {\r
5392         return error(GL_OUT_OF_MEMORY);\r
5393     }\r
5394 }\r
5395 \r
5396 void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)\r
5397 {\r
5398     GLfloat xyz[3] = {x, y, z};\r
5399 \r
5400     glUniform3fv(location, 1, (GLfloat*)&xyz);\r
5401 }\r
5402 \r
5403 void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)\r
5404 {\r
5405     TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);\r
5406 \r
5407     try\r
5408     {\r
5409         if(count < 0)\r
5410         {\r
5411             return error(GL_INVALID_VALUE);\r
5412         }\r
5413 \r
5414         if(location == -1)\r
5415         {\r
5416             return;\r
5417         }\r
5418 \r
5419         rad::Context *context = rad::getContext();\r
5420 \r
5421         if(context)\r
5422         {\r
5423             rad::Program *program = context->getCurrentProgram();\r
5424 \r
5425             if(!program)\r
5426             {\r
5427                 return error(GL_INVALID_OPERATION);\r
5428             }\r
5429 \r
5430             if(!program->setUniform3fv(location, count, v))\r
5431             {\r
5432                 return error(GL_INVALID_OPERATION);\r
5433             }\r
5434         }\r
5435     }\r
5436     catch(std::bad_alloc&)\r
5437     {\r
5438         return error(GL_OUT_OF_MEMORY);\r
5439     }\r
5440 }\r
5441 \r
5442 void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)\r
5443 {\r
5444     GLint xyz[3] = {x, y, z};\r
5445 \r
5446     glUniform3iv(location, 1, (GLint*)&xyz);\r
5447 }\r
5448 \r
5449 void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)\r
5450 {\r
5451     TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);\r
5452 \r
5453     try\r
5454     {\r
5455         if(count < 0)\r
5456         {\r
5457             return error(GL_INVALID_VALUE);\r
5458         }\r
5459 \r
5460         if(location == -1)\r
5461         {\r
5462             return;\r
5463         }\r
5464 \r
5465         rad::Context *context = rad::getContext();\r
5466 \r
5467         if(context)\r
5468         {\r
5469             rad::Program *program = context->getCurrentProgram();\r
5470 \r
5471             if(!program)\r
5472             {\r
5473                 return error(GL_INVALID_OPERATION);\r
5474             }\r
5475 \r
5476             if(!program->setUniform3iv(location, count, v))\r
5477             {\r
5478                 return error(GL_INVALID_OPERATION);\r
5479             }\r
5480         }\r
5481     }\r
5482     catch(std::bad_alloc&)\r
5483     {\r
5484         return error(GL_OUT_OF_MEMORY);\r
5485     }\r
5486 }\r
5487 \r
5488 void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)\r
5489 {\r
5490     GLfloat xyzw[4] = {x, y, z, w};\r
5491 \r
5492     glUniform4fv(location, 1, (GLfloat*)&xyzw);\r
5493 }\r
5494 \r
5495 void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)\r
5496 {\r
5497     TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);\r
5498 \r
5499     try\r
5500     {\r
5501         if(count < 0)\r
5502         {\r
5503             return error(GL_INVALID_VALUE);\r
5504         }\r
5505 \r
5506         if(location == -1)\r
5507         {\r
5508             return;\r
5509         }\r
5510 \r
5511         rad::Context *context = rad::getContext();\r
5512 \r
5513         if(context)\r
5514         {\r
5515             rad::Program *program = context->getCurrentProgram();\r
5516 \r
5517             if(!program)\r
5518             {\r
5519                 return error(GL_INVALID_OPERATION);\r
5520             }\r
5521 \r
5522             if(!program->setUniform4fv(location, count, v))\r
5523             {\r
5524                 return error(GL_INVALID_OPERATION);\r
5525             }\r
5526         }\r
5527     }\r
5528     catch(std::bad_alloc&)\r
5529     {\r
5530         return error(GL_OUT_OF_MEMORY);\r
5531     }\r
5532 }\r
5533 \r
5534 void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)\r
5535 {\r
5536     GLint xyzw[4] = {x, y, z, w};\r
5537 \r
5538     glUniform4iv(location, 1, (GLint*)&xyzw);\r
5539 }\r
5540 \r
5541 void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)\r
5542 {\r
5543     TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);\r
5544 \r
5545     try\r
5546     {\r
5547         if(count < 0)\r
5548         {\r
5549             return error(GL_INVALID_VALUE);\r
5550         }\r
5551 \r
5552         if(location == -1)\r
5553         {\r
5554             return;\r
5555         }\r
5556 \r
5557         rad::Context *context = rad::getContext();\r
5558 \r
5559         if(context)\r
5560         {\r
5561             rad::Program *program = context->getCurrentProgram();\r
5562 \r
5563             if(!program)\r
5564             {\r
5565                 return error(GL_INVALID_OPERATION);\r
5566             }\r
5567 \r
5568             if(!program->setUniform4iv(location, count, v))\r
5569             {\r
5570                 return error(GL_INVALID_OPERATION);\r
5571             }\r
5572         }\r
5573     }\r
5574     catch(std::bad_alloc&)\r
5575     {\r
5576         return error(GL_OUT_OF_MEMORY);\r
5577     }\r
5578 }\r
5579 \r
5580 void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)\r
5581 {\r
5582     TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",\r
5583           location, count, transpose, value);\r
5584 \r
5585     try\r
5586     {\r
5587         if(count < 0 || transpose != GL_FALSE)\r
5588         {\r
5589             return error(GL_INVALID_VALUE);\r
5590         }\r
5591 \r
5592         if(location == -1)\r
5593         {\r
5594             return;\r
5595         }\r
5596 \r
5597         rad::Context *context = rad::getContext();\r
5598 \r
5599         if(context)\r
5600         {\r
5601             rad::Program *program = context->getCurrentProgram();\r
5602 \r
5603             if(!program)\r
5604             {\r
5605                 return error(GL_INVALID_OPERATION);\r
5606             }\r
5607 \r
5608             if(!program->setUniformMatrix2fv(location, count, value))\r
5609             {\r
5610                 return error(GL_INVALID_OPERATION);\r
5611             }\r
5612         }\r
5613     }\r
5614     catch(std::bad_alloc&)\r
5615     {\r
5616         return error(GL_OUT_OF_MEMORY);\r
5617     }\r
5618 }\r
5619 \r
5620 void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)\r
5621 {\r
5622     TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",\r
5623           location, count, transpose, value);\r
5624 \r
5625     try\r
5626     {\r
5627         if(count < 0 || transpose != GL_FALSE)\r
5628         {\r
5629             return error(GL_INVALID_VALUE);\r
5630         }\r
5631 \r
5632         if(location == -1)\r
5633         {\r
5634             return;\r
5635         }\r
5636 \r
5637         rad::Context *context = rad::getContext();\r
5638 \r
5639         if(context)\r
5640         {\r
5641             rad::Program *program = context->getCurrentProgram();\r
5642 \r
5643             if(!program)\r
5644             {\r
5645                 return error(GL_INVALID_OPERATION);\r
5646             }\r
5647 \r
5648             if(!program->setUniformMatrix3fv(location, count, value))\r
5649             {\r
5650                 return error(GL_INVALID_OPERATION);\r
5651             }\r
5652         }\r
5653     }\r
5654     catch(std::bad_alloc&)\r
5655     {\r
5656         return error(GL_OUT_OF_MEMORY);\r
5657     }\r
5658 }\r
5659 \r
5660 void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)\r
5661 {\r
5662     TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",\r
5663           location, count, transpose, value);\r
5664 \r
5665     try\r
5666     {\r
5667         if(count < 0 || transpose != GL_FALSE)\r
5668         {\r
5669             return error(GL_INVALID_VALUE);\r
5670         }\r
5671 \r
5672         if(location == -1)\r
5673         {\r
5674             return;\r
5675         }\r
5676 \r
5677         rad::Context *context = rad::getContext();\r
5678 \r
5679         if(context)\r
5680         {\r
5681             rad::Program *program = context->getCurrentProgram();\r
5682 \r
5683             if(!program)\r
5684             {\r
5685                 return error(GL_INVALID_OPERATION);\r
5686             }\r
5687 \r
5688             if(!program->setUniformMatrix4fv(location, count, value))\r
5689             {\r
5690                 return error(GL_INVALID_OPERATION);\r
5691             }\r
5692         }\r
5693     }\r
5694     catch(std::bad_alloc&)\r
5695     {\r
5696         return error(GL_OUT_OF_MEMORY);\r
5697     }\r
5698 }\r
5699 \r
5700 void GL_APIENTRY glUseProgram(GLuint program)\r
5701 {\r
5702     TRACE("(GLuint program = %d)", program);\r
5703 \r
5704     try\r
5705     {\r
5706         rad::Context *context = rad::getContext();\r
5707 \r
5708         if(context)\r
5709         {\r
5710             rad::Program *programObject = context->getProgram(program);\r
5711 \r
5712             if(!programObject && program != 0)\r
5713             {\r
5714                 if(context->getShader(program))\r
5715                 {\r
5716                     return error(GL_INVALID_OPERATION);\r
5717                 }\r
5718                 else\r
5719                 {\r
5720                     return error(GL_INVALID_VALUE);\r
5721                 }\r
5722             }\r
5723 \r
5724             if(program != 0 && !programObject->isLinked())\r
5725             {\r
5726                 return error(GL_INVALID_OPERATION);\r
5727             }\r
5728 \r
5729             context->useProgram(program);\r
5730         }\r
5731     }\r
5732     catch(std::bad_alloc&)\r
5733     {\r
5734         return error(GL_OUT_OF_MEMORY);\r
5735     }\r
5736 }\r
5737 \r
5738 void GL_APIENTRY glValidateProgram(GLuint program)\r
5739 {\r
5740     TRACE("(GLuint program = %d)", program);\r
5741 \r
5742     try\r
5743     {\r
5744         rad::Context *context = rad::getContext();\r
5745 \r
5746         if(context)\r
5747         {\r
5748             rad::Program *programObject = context->getProgram(program);\r
5749 \r
5750             if(!programObject)\r
5751             {\r
5752                 if(context->getShader(program))\r
5753                 {\r
5754                     return error(GL_INVALID_OPERATION);\r
5755                 }\r
5756                 else\r
5757                 {\r
5758                     return error(GL_INVALID_VALUE);\r
5759                 }\r
5760             }\r
5761 \r
5762             programObject->validate();\r
5763         }\r
5764     }\r
5765     catch(std::bad_alloc&)\r
5766     {\r
5767         return error(GL_OUT_OF_MEMORY);\r
5768     }\r
5769 }\r
5770 \r
5771 void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)\r
5772 {\r
5773     TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);\r
5774 \r
5775     try\r
5776     {\r
5777         if(index >= rad::MAX_VERTEX_ATTRIBS)\r
5778         {\r
5779             return error(GL_INVALID_VALUE);\r
5780         }\r
5781 \r
5782         rad::Context *context = rad::getContext();\r
5783 \r
5784         if(context)\r
5785         {\r
5786             GLfloat vals[4] = { x, 0, 0, 1 };\r
5787             context->setVertexAttrib(index, vals);\r
5788         }\r
5789     }\r
5790     catch(std::bad_alloc&)\r
5791     {\r
5792         return error(GL_OUT_OF_MEMORY);\r
5793     }\r
5794 }\r
5795 \r
5796 void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)\r
5797 {\r
5798     TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);\r
5799 \r
5800     try\r
5801     {\r
5802         if(index >= rad::MAX_VERTEX_ATTRIBS)\r
5803         {\r
5804             return error(GL_INVALID_VALUE);\r
5805         }\r
5806 \r
5807         rad::Context *context = rad::getContext();\r
5808 \r
5809         if(context)\r
5810         {\r
5811             GLfloat vals[4] = { values[0], 0, 0, 1 };\r
5812             context->setVertexAttrib(index, vals);\r
5813         }\r
5814     }\r
5815     catch(std::bad_alloc&)\r
5816     {\r
5817         return error(GL_OUT_OF_MEMORY);\r
5818     }\r
5819 }\r
5820 \r
5821 void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)\r
5822 {\r
5823     TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);\r
5824 \r
5825     try\r
5826     {\r
5827         if(index >= rad::MAX_VERTEX_ATTRIBS)\r
5828         {\r
5829             return error(GL_INVALID_VALUE);\r
5830         }\r
5831 \r
5832         rad::Context *context = rad::getContext();\r
5833 \r
5834         if(context)\r
5835         {\r
5836             GLfloat vals[4] = { x, y, 0, 1 };\r
5837             context->setVertexAttrib(index, vals);\r
5838         }\r
5839     }\r
5840     catch(std::bad_alloc&)\r
5841     {\r
5842         return error(GL_OUT_OF_MEMORY);\r
5843     }\r
5844 }\r
5845 \r
5846 void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)\r
5847 {\r
5848     TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);\r
5849 \r
5850     try\r
5851     {\r
5852         if(index >= rad::MAX_VERTEX_ATTRIBS)\r
5853         {\r
5854             return error(GL_INVALID_VALUE);\r
5855         }\r
5856 \r
5857         rad::Context *context = rad::getContext();\r
5858 \r
5859         if(context)\r
5860         {\r
5861             GLfloat vals[4] = { values[0], values[1], 0, 1 };\r
5862             context->setVertexAttrib(index, vals);\r
5863         }\r
5864     }\r
5865     catch(std::bad_alloc&)\r
5866     {\r
5867         return error(GL_OUT_OF_MEMORY);\r
5868     }\r
5869 }\r
5870 \r
5871 void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)\r
5872 {\r
5873     TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);\r
5874 \r
5875     try\r
5876     {\r
5877         if(index >= rad::MAX_VERTEX_ATTRIBS)\r
5878         {\r
5879             return error(GL_INVALID_VALUE);\r
5880         }\r
5881 \r
5882         rad::Context *context = rad::getContext();\r
5883 \r
5884         if(context)\r
5885         {\r
5886             GLfloat vals[4] = { x, y, z, 1 };\r
5887             context->setVertexAttrib(index, vals);\r
5888         }\r
5889     }\r
5890     catch(std::bad_alloc&)\r
5891     {\r
5892         return error(GL_OUT_OF_MEMORY);\r
5893     }\r
5894 }\r
5895 \r
5896 void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)\r
5897 {\r
5898     TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);\r
5899 \r
5900     try\r
5901     {\r
5902         if(index >= rad::MAX_VERTEX_ATTRIBS)\r
5903         {\r
5904             return error(GL_INVALID_VALUE);\r
5905         }\r
5906 \r
5907         rad::Context *context = rad::getContext();\r
5908 \r
5909         if(context)\r
5910         {\r
5911             GLfloat vals[4] = { values[0], values[1], values[2], 1 };\r
5912             context->setVertexAttrib(index, vals);\r
5913         }\r
5914     }\r
5915     catch(std::bad_alloc&)\r
5916     {\r
5917         return error(GL_OUT_OF_MEMORY);\r
5918     }\r
5919 }\r
5920 \r
5921 void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)\r
5922 {\r
5923     TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);\r
5924 \r
5925     try\r
5926     {\r
5927         if(index >= rad::MAX_VERTEX_ATTRIBS)\r
5928         {\r
5929             return error(GL_INVALID_VALUE);\r
5930         }\r
5931 \r
5932         rad::Context *context = rad::getContext();\r
5933 \r
5934         if(context)\r
5935         {\r
5936             GLfloat vals[4] = { x, y, z, w };\r
5937             context->setVertexAttrib(index, vals);\r
5938         }\r
5939     }\r
5940     catch(std::bad_alloc&)\r
5941     {\r
5942         return error(GL_OUT_OF_MEMORY);\r
5943     }\r
5944 }\r
5945 \r
5946 void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)\r
5947 {\r
5948     TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);\r
5949 \r
5950     try\r
5951     {\r
5952         if(index >= rad::MAX_VERTEX_ATTRIBS)\r
5953         {\r
5954             return error(GL_INVALID_VALUE);\r
5955         }\r
5956 \r
5957         rad::Context *context = rad::getContext();\r
5958 \r
5959         if(context)\r
5960         {\r
5961             context->setVertexAttrib(index, values);\r
5962         }\r
5963     }\r
5964     catch(std::bad_alloc&)\r
5965     {\r
5966         return error(GL_OUT_OF_MEMORY);\r
5967     }\r
5968 }\r
5969 \r
5970 void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)\r
5971 {\r
5972     TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "\r
5973           "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",\r
5974           index, size, type, normalized, stride, ptr);\r
5975 \r
5976     try\r
5977     {\r
5978         if(index >= rad::MAX_VERTEX_ATTRIBS)\r
5979         {\r
5980             return error(GL_INVALID_VALUE);\r
5981         }\r
5982 \r
5983         if(size < 1 || size > 4)\r
5984         {\r
5985             return error(GL_INVALID_VALUE);\r
5986         }\r
5987 \r
5988         switch(type)\r
5989         {\r
5990           case GL_BYTE:\r
5991           case GL_UNSIGNED_BYTE:\r
5992           case GL_SHORT:\r
5993           case GL_UNSIGNED_SHORT:\r
5994           case GL_FIXED:\r
5995           case GL_FLOAT:\r
5996             break;\r
5997           default:\r
5998             return error(GL_INVALID_ENUM);\r
5999         }\r
6000 \r
6001         if(stride < 0)\r
6002         {\r
6003             return error(GL_INVALID_VALUE);\r
6004         }\r
6005 \r
6006         rad::Context *context = rad::getContext();\r
6007 \r
6008         if(context)\r
6009         {\r
6010             context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);\r
6011         }\r
6012     }\r
6013     catch(std::bad_alloc&)\r
6014     {\r
6015         return error(GL_OUT_OF_MEMORY);\r
6016     }\r
6017 }\r
6018 \r
6019 void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)\r
6020 {\r
6021     TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);\r
6022 \r
6023     try\r
6024     {\r
6025         if(width < 0 || height < 0)\r
6026         {\r
6027             return error(GL_INVALID_VALUE);\r
6028         }\r
6029 \r
6030         rad::Context *context = rad::getContext();\r
6031 \r
6032         if(context)\r
6033         {\r
6034             context->setViewportParams(x, y, width, height);\r
6035         }\r
6036     }\r
6037     catch(std::bad_alloc&)\r
6038     {\r
6039         return error(GL_OUT_OF_MEMORY);\r
6040     }\r
6041 }\r
6042 \r
6043 void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,\r
6044                                       GLbitfield mask, GLenum filter)\r
6045 {\r
6046     TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "\r
6047           "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "\r
6048           "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",\r
6049           srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);\r
6050 \r
6051     try\r
6052     {\r
6053         switch(filter)\r
6054         {\r
6055           case GL_NEAREST:\r
6056             break;\r
6057           default:\r
6058             return error(GL_INVALID_ENUM);\r
6059         }\r
6060 \r
6061         if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)\r
6062         {\r
6063             return error(GL_INVALID_VALUE);\r
6064         }\r
6065 \r
6066         if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)\r
6067         {\r
6068             ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");\r
6069             return error(GL_INVALID_OPERATION);\r
6070         }\r
6071 \r
6072         rad::Context *context = rad::getContext();\r
6073 \r
6074         if(context)\r
6075         {\r
6076             if(context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())\r
6077             {\r
6078                 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");\r
6079                 return error(GL_INVALID_OPERATION);\r
6080             }\r
6081 \r
6082             context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);\r
6083         }\r
6084     }\r
6085     catch(std::bad_alloc&)\r
6086     {\r
6087         return error(GL_OUT_OF_MEMORY);\r
6088     }\r
6089 }\r
6090 \r
6091 void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,\r
6092                                GLint border, GLenum format, GLenum type, const GLvoid* pixels)\r
6093 {\r
6094     TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "\r
6095           "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "\r
6096           "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",\r
6097           target, level, internalformat, width, height, depth, border, format, type, pixels);\r
6098 \r
6099     try\r
6100     {\r
6101                 UNIMPLEMENTED();   // FIXME\r
6102     }\r
6103     catch(std::bad_alloc&)\r
6104     {\r
6105         return error(GL_OUT_OF_MEMORY);\r
6106     }\r
6107 }\r
6108 \r
6109 void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)\r
6110 {\r
6111     TRACE("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);\r
6112 \r
6113     try\r
6114     {\r
6115         switch(target)\r
6116         {\r
6117         case GL_TEXTURE_EXTERNAL_OES:\r
6118             break;\r
6119         default:\r
6120             return error(GL_INVALID_ENUM);\r
6121         }\r
6122 \r
6123         if(!image)\r
6124         {\r
6125             return error(GL_INVALID_OPERATION);\r
6126         }\r
6127 \r
6128         rad::Context *context = rad::getContext();\r
6129 \r
6130         if(context)\r
6131         {\r
6132             rad::TextureExternal *texture = context->getTextureExternal();\r
6133 \r
6134             if(!texture)\r
6135             {\r
6136                 return error(GL_INVALID_OPERATION);\r
6137             }\r
6138 \r
6139             rad::Image *glImage = static_cast<rad::Image*>(image);\r
6140 \r
6141             texture->setImage(glImage);\r
6142         }\r
6143     }\r
6144     catch(std::bad_alloc&)\r
6145     {\r
6146         return error(GL_OUT_OF_MEMORY);\r
6147     }\r
6148 }\r
6149 \r
6150 RADdevice RADAPIENTRY radCreateDevice (void) {UNIMPLEMENTED(); return 0;}\r
6151 void RADAPIENTRY radReferenceDevice (RADdevice device) {UNIMPLEMENTED();}\r
6152 void RADAPIENTRY radReleaseDevice (RADdevice device) {UNIMPLEMENTED();}\r
6153 RADuint RADAPIENTRY radGetTokenHeader (RADdevice device, RADtokenName name) {UNIMPLEMENTED(); return 0;}\r
6154 RADqueue RADAPIENTRY radCreateQueue (RADdevice device, RADqueueType queuetype) {UNIMPLEMENTED(); return 0;}\r
6155 void RADAPIENTRY radReferenceQueue (RADqueue queue) {UNIMPLEMENTED();}\r
6156 void RADAPIENTRY radReleaseQueue (RADqueue queue) {UNIMPLEMENTED();}\r
6157 void RADAPIENTRY radQueueTagBuffer (RADqueue queue, RADbuffer buffer) {UNIMPLEMENTED();}\r
6158 void RADAPIENTRY radQueueTagTexture (RADqueue queue, RADtexture texture) {UNIMPLEMENTED();}\r
6159 void RADAPIENTRY radQueueSubmitCommands (RADqueue queue, RADuint numCommands, const RADcommandHandle *handles) {UNIMPLEMENTED();}\r
6160 void RADAPIENTRY radFlushQueue (RADqueue queue) {UNIMPLEMENTED();}\r
6161 void RADAPIENTRY radFinishQueue (RADqueue queue) {UNIMPLEMENTED();}\r
6162 void RADAPIENTRY radQueueViewport (RADqueue queue, RADint x, RADint y, RADint w, RADint h) {UNIMPLEMENTED();}\r
6163 void RADAPIENTRY radQueueScissor (RADqueue queue, RADint x, RADint y, RADint w, RADint h) {UNIMPLEMENTED();}\r
6164 void RADAPIENTRY radQueueCopyBufferToImage (RADqueue queue, RADbuffer buffer, RADintptr bufferOffset, RADtexture texture, RADint level, RADuint xoffset, RADuint yoffset, RADuint zoffset, RADsizei width, RADsizei height, RADsizei depth) {UNIMPLEMENTED();}\r
6165 void RADAPIENTRY radQueueCopyImageToBuffer (RADqueue queue, RADbuffer buffer, RADintptr bufferOffset, RADtexture texture, RADint level, RADuint xoffset, RADuint yoffset, RADuint zoffset, RADsizei width, RADsizei height, RADsizei depth) {UNIMPLEMENTED();}\r
6166 void RADAPIENTRY radQueueCopyBuffer (RADqueue queue, RADbuffer srcBuffer, RADintptr srcOffset, RADbuffer dstBuffer, RADintptr dstOffset, RADsizei size) {UNIMPLEMENTED();}\r
6167 void RADAPIENTRY radQueueClearColor (RADqueue queue, RADuint index, const RADfloat *color) {UNIMPLEMENTED();}\r
6168 void RADAPIENTRY radQueueClearDepth (RADqueue queue, RADfloat depth) {UNIMPLEMENTED();}\r
6169 void RADAPIENTRY radQueueClearStencil (RADqueue queue, RADuint stencil) {UNIMPLEMENTED();}\r
6170 void RADAPIENTRY radQueuePresent (RADqueue queue, RADtexture texture) {UNIMPLEMENTED();}\r
6171 void RADAPIENTRY radQueueDrawArrays (RADqueue queue, RADprimitiveType mode, RADint first, RADsizei count) {UNIMPLEMENTED();}\r
6172 void RADAPIENTRY radQueueDrawElements (RADqueue queue, RADprimitiveType mode, RADindexType type, RADsizei count, RADindexHandle indexHandle, RADuint offset) {UNIMPLEMENTED();}\r
6173 void RADAPIENTRY radQueueBindPipeline (RADqueue queue, RADpipelineType pipelineType, RADpipelineHandle pipelineHandle) {UNIMPLEMENTED();}\r
6174 void RADAPIENTRY radQueueBindGroup (RADqueue queue, RADbitfield stages, RADuint group, RADuint count, RADbindGroupHandle groupHandle, RADuint offset) {UNIMPLEMENTED();}\r
6175 void RADAPIENTRY radQueueBeginPass (RADqueue queue, RADpass pass) {UNIMPLEMENTED();}\r
6176 void RADAPIENTRY radQueueEndPass (RADqueue queue, RADpass pass) {UNIMPLEMENTED();}\r
6177 void RADAPIENTRY radQueueSubmitDynamic (RADqueue queue, const void *dynamic, RADsizei length) {UNIMPLEMENTED();}\r
6178 void RADAPIENTRY radQueueStencilValueMask (RADqueue queue, RADfaceBitfield faces, RADuint mask) {UNIMPLEMENTED();}\r
6179 void RADAPIENTRY radQueueStencilMask (RADqueue queue, RADfaceBitfield faces, RADuint mask) {UNIMPLEMENTED();}\r
6180 void RADAPIENTRY radQueueStencilRef (RADqueue queue, RADfaceBitfield faces, RADint ref) {UNIMPLEMENTED();}\r
6181 void RADAPIENTRY radQueueBlendColor (RADqueue queue, const RADfloat *blendColor) {UNIMPLEMENTED();}\r
6182 void RADAPIENTRY radQueuePointSize (RADqueue queue, RADfloat pointSize) {UNIMPLEMENTED();}\r
6183 void RADAPIENTRY radQueueLineWidth (RADqueue queue, RADfloat lineWidth) {UNIMPLEMENTED();}\r
6184 void RADAPIENTRY radQueuePolygonOffsetClamp (RADqueue queue, RADfloat factor, RADfloat units, RADfloat clamp) {UNIMPLEMENTED();}\r
6185 void RADAPIENTRY radQueueSampleMask (RADqueue queue, RADuint mask) {UNIMPLEMENTED();}\r
6186 RADprogram RADAPIENTRY radCreateProgram (RADdevice device) {UNIMPLEMENTED(); return 0;}\r
6187 void RADAPIENTRY radReferenceProgram (RADprogram program) {UNIMPLEMENTED();}\r
6188 void RADAPIENTRY radReleaseProgram (RADprogram program) {UNIMPLEMENTED();}\r
6189 void RADAPIENTRY radProgramSource (RADprogram program, RADprogramFormat format, RADsizei length, const void *source) {UNIMPLEMENTED();}\r
6190 RADbuffer RADAPIENTRY radCreateBuffer (RADdevice device) {UNIMPLEMENTED(); return 0;}\r
6191 void RADAPIENTRY radReferenceBuffer (RADbuffer buffer) {UNIMPLEMENTED();}\r
6192 void RADAPIENTRY radReleaseBuffer (RADbuffer buffer, RADtagMode tagMode) {UNIMPLEMENTED();}\r
6193 void RADAPIENTRY radBufferAccess (RADbuffer buffer, RADbitfield access) {UNIMPLEMENTED();}\r
6194 void RADAPIENTRY radBufferMapAccess (RADbuffer buffer, RADbitfield mapAccess) {UNIMPLEMENTED();}\r
6195 void RADAPIENTRY radBufferStorage (RADbuffer buffer, RADsizei size) {UNIMPLEMENTED();}\r
6196 void* RADAPIENTRY radMapBuffer (RADbuffer buffer) {UNIMPLEMENTED(); return 0;}\r
6197 RADvertexHandle RADAPIENTRY radGetVertexHandle (RADbuffer buffer) {UNIMPLEMENTED(); return 0;}\r
6198 RADindexHandle RADAPIENTRY radGetIndexHandle (RADbuffer buffer) {UNIMPLEMENTED(); return 0;}\r
6199 RADuniformHandle RADAPIENTRY radGetUniformHandle (RADbuffer buffer) {UNIMPLEMENTED(); return 0;}\r
6200 RADbindGroupHandle RADAPIENTRY radGetBindGroupHandle (RADbuffer buffer) {UNIMPLEMENTED(); return 0;}\r
6201 RADtexture RADAPIENTRY radCreateTexture (RADdevice device) {UNIMPLEMENTED(); return 0;}\r
6202 void RADAPIENTRY radReferenceTexture (RADtexture texture) {UNIMPLEMENTED();}\r
6203 void RADAPIENTRY radReleaseTexture (RADtexture texture, RADtagMode tagMode) {UNIMPLEMENTED();}\r
6204 void RADAPIENTRY radTextureAccess (RADtexture texture, RADbitfield access) {UNIMPLEMENTED();}\r
6205 void RADAPIENTRY radTextureStorage (RADtexture texture, RADtextureTarget target, RADsizei levels, RADinternalFormat internalFormat, RADsizei width, RADsizei height, RADsizei depth, RADsizei samples) {UNIMPLEMENTED();}\r
6206 RADtextureHandle RADAPIENTRY radGetTextureSamplerHandle (RADtexture texture, RADsampler sampler, RADtextureTarget target, RADinternalFormat internalFormat, RADuint minLevel, RADuint numLevels, RADuint minLayer, RADuint numLayers) {UNIMPLEMENTED(); return 0;}\r
6207 RADrenderTargetHandle RADAPIENTRY radGetTextureRenderTargetHandle (RADtexture texture, RADtextureTarget target, RADinternalFormat internalFormat, RADuint level, RADuint minLayer, RADuint numLayers) {UNIMPLEMENTED(); return 0;}\r
6208 RADsampler RADAPIENTRY radCreateSampler (RADdevice device) {UNIMPLEMENTED(); return 0;}\r
6209 void RADAPIENTRY radReferenceSampler (RADsampler sampler) {UNIMPLEMENTED();}\r
6210 void RADAPIENTRY radReleaseSampler (RADsampler sampler) {UNIMPLEMENTED();}\r
6211 void RADAPIENTRY radSamplerDefault (RADsampler sampler) {UNIMPLEMENTED();}\r
6212 void RADAPIENTRY radSamplerMinMagFilter (RADsampler sampler, RADminFilter min, RADmagFilter mag) {UNIMPLEMENTED();}\r
6213 void RADAPIENTRY radSamplerWrapMode (RADsampler sampler, RADwrapMode s, RADwrapMode t, RADwrapMode r) {UNIMPLEMENTED();}\r
6214 void RADAPIENTRY radSamplerLodClamp (RADsampler sampler, RADfloat min, RADfloat max) {UNIMPLEMENTED();}\r
6215 void RADAPIENTRY radSamplerLodBias (RADsampler sampler, RADfloat bias) {UNIMPLEMENTED();}\r
6216 void RADAPIENTRY radSamplerCompare (RADsampler sampler, RADcompareMode mode, RADcompareFunc func) {UNIMPLEMENTED();}\r
6217 void RADAPIENTRY radSamplerBorderColorFloat (RADsampler sampler, const RADfloat *borderColor) {UNIMPLEMENTED();}\r
6218 void RADAPIENTRY radSamplerBorderColorInt (RADsampler sampler, const RADuint *borderColor) {UNIMPLEMENTED();}\r
6219 RADcolorState RADAPIENTRY radCreateColorState (RADdevice device) {UNIMPLEMENTED(); return 0;}\r
6220 void RADAPIENTRY radReferenceColorState (RADcolorState color) {UNIMPLEMENTED();}\r
6221 void RADAPIENTRY radReleaseColorState (RADcolorState color) {UNIMPLEMENTED();}\r
6222 void RADAPIENTRY radColorDefault (RADcolorState color) {UNIMPLEMENTED();}\r
6223 void RADAPIENTRY radColorBlendEnable (RADcolorState color, RADuint index, RADboolean enable) {UNIMPLEMENTED();}\r
6224 void RADAPIENTRY radColorBlendFunc (RADcolorState color, RADuint index, RADblendFunc srcFunc, RADblendFunc dstFunc, RADblendFunc srcFuncAlpha, RADblendFunc dstFuncAlpha) {UNIMPLEMENTED();}\r
6225 void RADAPIENTRY radColorBlendEquation (RADcolorState color, RADuint index, RADblendEquation modeRGB, RADblendEquation modeAlpha) {UNIMPLEMENTED();}\r
6226 void RADAPIENTRY radColorMask (RADcolorState color, RADuint index, RADboolean r, RADboolean g, RADboolean b, RADboolean a) {UNIMPLEMENTED();}\r
6227 void RADAPIENTRY radColorNumTargets (RADcolorState color, RADuint numTargets) {UNIMPLEMENTED();}\r
6228 void RADAPIENTRY radColorLogicOpEnable (RADcolorState color, RADboolean enable) {UNIMPLEMENTED();}\r
6229 void RADAPIENTRY radColorLogicOp (RADcolorState color, RADlogicOp logicOp) {UNIMPLEMENTED();}\r
6230 void RADAPIENTRY radColorAlphaToCoverageEnable (RADcolorState color, RADboolean enable) {UNIMPLEMENTED();}\r
6231 void RADAPIENTRY radColorBlendColor (RADcolorState color, const RADfloat *blendColor) {UNIMPLEMENTED();}\r
6232 void RADAPIENTRY radColorDynamic (RADcolorState color, RADcolorDynamic dynamic, RADboolean enable) {UNIMPLEMENTED();}\r
6233 RADrasterState RADAPIENTRY radCreateRasterState (RADdevice device) {UNIMPLEMENTED(); return 0;}\r
6234 void RADAPIENTRY radReferenceRasterState (RADrasterState raster) {UNIMPLEMENTED();}\r
6235 void RADAPIENTRY radReleaseRasterState (RADrasterState raster) {UNIMPLEMENTED();}\r
6236 void RADAPIENTRY radRasterDefault (RADrasterState raster) {UNIMPLEMENTED();}\r
6237 void RADAPIENTRY radRasterPointSize (RADrasterState raster, RADfloat pointSize) {UNIMPLEMENTED();}\r
6238 void RADAPIENTRY radRasterLineWidth (RADrasterState raster, RADfloat lineWidth) {UNIMPLEMENTED();}\r
6239 void RADAPIENTRY radRasterCullFace (RADrasterState raster, RADfaceBitfield face) {UNIMPLEMENTED();}\r
6240 void RADAPIENTRY radRasterFrontFace (RADrasterState raster, RADfrontFace face) {UNIMPLEMENTED();}\r
6241 void RADAPIENTRY radRasterPolygonMode (RADrasterState raster, RADpolygonMode polygonMode) {UNIMPLEMENTED();}\r
6242 void RADAPIENTRY radRasterPolygonOffsetClamp (RADrasterState raster, RADfloat factor, RADfloat units, RADfloat clamp) {UNIMPLEMENTED();}\r
6243 void RADAPIENTRY radRasterPolygonOffsetEnables (RADrasterState raster, RADpolygonOffsetEnables enables) {UNIMPLEMENTED();}\r
6244 void RADAPIENTRY radRasterDiscardEnable (RADrasterState raster, RADboolean enable) {UNIMPLEMENTED();}\r
6245 void RADAPIENTRY radRasterMultisampleEnable (RADrasterState raster, RADboolean enable) {UNIMPLEMENTED();}\r
6246 void RADAPIENTRY radRasterSamples (RADrasterState raster, RADuint samples) {UNIMPLEMENTED();}\r
6247 void RADAPIENTRY radRasterSampleMask (RADrasterState raster, RADuint mask) {UNIMPLEMENTED();}\r
6248 void RADAPIENTRY radRasterDynamic (RADrasterState raster, RADrasterDynamic dynamic, RADboolean enable) {UNIMPLEMENTED();}\r
6249 RADdepthStencilState RADAPIENTRY radCreateDepthStencilState (RADdevice device) {UNIMPLEMENTED(); return 0;}\r
6250 void RADAPIENTRY radReferenceDepthStencilState (RADdepthStencilState depthStencil) {UNIMPLEMENTED();}\r
6251 void RADAPIENTRY radReleaseDepthStencilState (RADdepthStencilState depthStencil) {UNIMPLEMENTED();}\r
6252 void RADAPIENTRY radDepthStencilDefault (RADdepthStencilState depthStencil) {UNIMPLEMENTED();}\r
6253 void RADAPIENTRY radDepthStencilDepthTestEnable (RADdepthStencilState depthStencil, RADboolean enable) {UNIMPLEMENTED();}\r
6254 void RADAPIENTRY radDepthStencilDepthWriteEnable (RADdepthStencilState depthStencil, RADboolean enable) {UNIMPLEMENTED();}\r
6255 void RADAPIENTRY radDepthStencilDepthFunc (RADdepthStencilState depthStencil, RADdepthFunc func) {UNIMPLEMENTED();}\r
6256 void RADAPIENTRY radDepthStencilStencilTestEnable (RADdepthStencilState depthStencil, RADboolean enable) {UNIMPLEMENTED();}\r
6257 void RADAPIENTRY radDepthStencilStencilFunc (RADdepthStencilState depthStencil, RADfaceBitfield faces, RADstencilFunc func, RADint ref, RADuint mask) {UNIMPLEMENTED();}\r
6258 void RADAPIENTRY radDepthStencilStencilOp (RADdepthStencilState depthStencil, RADfaceBitfield faces, RADstencilOp fail, RADstencilOp depthFail, RADstencilOp depthPass) {UNIMPLEMENTED();}\r
6259 void RADAPIENTRY radDepthStencilStencilMask (RADdepthStencilState depthStencil, RADfaceBitfield faces, RADuint mask) {UNIMPLEMENTED();}\r
6260 void RADAPIENTRY radDepthStencilDynamic (RADdepthStencilState depthStencil, RADdepthStencilDynamic dynamic, RADboolean enable) {UNIMPLEMENTED();}\r
6261 RADvertexState RADAPIENTRY radCreateVertexState (RADdevice device) {UNIMPLEMENTED(); return 0;}\r
6262 void RADAPIENTRY radReferenceVertexState (RADvertexState vertex) {UNIMPLEMENTED();}\r
6263 void RADAPIENTRY radReleaseVertexState (RADvertexState vertex) {UNIMPLEMENTED();}\r
6264 void RADAPIENTRY radVertexDefault (RADvertexState vertex) {UNIMPLEMENTED();}\r
6265 void RADAPIENTRY radVertexAttribFormat (RADvertexState vertex, RADint attribIndex, RADint numComponents, RADint bytesPerComponent, RADattribType type, RADuint relativeOffset) {UNIMPLEMENTED();}\r
6266 void RADAPIENTRY radVertexAttribBinding (RADvertexState vertex, RADint attribIndex, RADint bindingIndex) {UNIMPLEMENTED();}\r
6267 void RADAPIENTRY radVertexBindingGroup (RADvertexState vertex, RADint bindingIndex, RADint group, RADint index) {UNIMPLEMENTED();}\r
6268 void RADAPIENTRY radVertexAttribEnable (RADvertexState vertex, RADint attribIndex, RADboolean enable) {UNIMPLEMENTED();}\r
6269 void RADAPIENTRY radVertexBindingStride (RADvertexState vertex, RADint bindingIndex, RADuint stride) {UNIMPLEMENTED();}\r
6270 RADrtFormatState RADAPIENTRY radCreateRtFormatState (RADdevice device) {UNIMPLEMENTED(); return 0;}\r
6271 void RADAPIENTRY radReferenceRtFormatState (RADrtFormatState rtFormat) {UNIMPLEMENTED();}\r
6272 void RADAPIENTRY radReleaseRtFormatState (RADrtFormatState rtFormat) {UNIMPLEMENTED();}\r
6273 void RADAPIENTRY radRtFormatDefault (RADrtFormatState rtFormat) {UNIMPLEMENTED();}\r
6274 void RADAPIENTRY radRtFormatColorFormat (RADrtFormatState rtFormat, RADuint index, RADinternalFormat format) {UNIMPLEMENTED();}\r
6275 void RADAPIENTRY radRtFormatDepthFormat (RADrtFormatState rtFormat, RADinternalFormat format) {UNIMPLEMENTED();}\r
6276 void RADAPIENTRY radRtFormatStencilFormat (RADrtFormatState rtFormat, RADinternalFormat format) {UNIMPLEMENTED();}\r
6277 void RADAPIENTRY radRtFormatColorSamples (RADrtFormatState rtFormat, RADuint samples) {UNIMPLEMENTED();}\r
6278 void RADAPIENTRY radRtFormatDepthStencilSamples (RADrtFormatState rtFormat, RADuint samples) {UNIMPLEMENTED();}\r
6279 RADpipeline RADAPIENTRY radCreatePipeline (RADdevice device, RADpipelineType pipelineType) {UNIMPLEMENTED(); return 0;}\r
6280 void RADAPIENTRY radReferencePipeline (RADpipeline pipeline) {UNIMPLEMENTED();}\r
6281 void RADAPIENTRY radReleasePipeline (RADpipeline pipeline) {UNIMPLEMENTED();}\r
6282 void RADAPIENTRY radPipelineProgramStages (RADpipeline pipeline, RADbitfield stages, RADprogram program) {UNIMPLEMENTED();}\r
6283 void RADAPIENTRY radPipelineVertexState (RADpipeline pipeline, RADvertexState vertex) {UNIMPLEMENTED();}\r
6284 void RADAPIENTRY radPipelineColorState (RADpipeline pipeline, RADcolorState color) {UNIMPLEMENTED();}\r
6285 void RADAPIENTRY radPipelineRasterState (RADpipeline pipeline, RADrasterState raster) {UNIMPLEMENTED();}\r
6286 void RADAPIENTRY radPipelineDepthStencilState (RADpipeline pipeline, RADdepthStencilState depthStencil) {UNIMPLEMENTED();}\r
6287 void RADAPIENTRY radPipelineRtFormatState (RADpipeline pipeline, RADrtFormatState rtFormat) {UNIMPLEMENTED();}\r
6288 void RADAPIENTRY radPipelinePrimitiveType (RADpipeline pipeline, RADprimitiveType mode) {UNIMPLEMENTED();}\r
6289 void RADAPIENTRY radCompilePipeline (RADpipeline pipeline) {UNIMPLEMENTED();}\r
6290 RADpipelineHandle RADAPIENTRY radGetPipelineHandle (RADpipeline pipeline) {UNIMPLEMENTED(); return 0;}\r
6291 RADcommandBuffer RADAPIENTRY radCreateCommandBuffer (RADdevice device, RADqueueType queueType) {UNIMPLEMENTED(); return 0;}\r
6292 void RADAPIENTRY radReferenceCommandBuffer (RADcommandBuffer cmdBuf) {UNIMPLEMENTED();}\r
6293 void RADAPIENTRY radReleaseCommandBuffer (RADcommandBuffer cmdBuf) {UNIMPLEMENTED();}\r
6294 void RADAPIENTRY radCmdBindPipeline (RADcommandBuffer cmdBuf, RADpipelineType pipelineType, RADpipelineHandle pipelineHandle) {UNIMPLEMENTED();}\r
6295 void RADAPIENTRY radCmdBindGroup (RADcommandBuffer cmdBuf, RADbitfield stages, RADuint group, RADuint count, RADbindGroupHandle groupHandle, RADuint offset) {UNIMPLEMENTED();}\r
6296 void RADAPIENTRY radCmdDrawArrays (RADcommandBuffer cmdBuf, RADprimitiveType mode, RADint first, RADsizei count) {UNIMPLEMENTED();}\r
6297 void RADAPIENTRY radCmdDrawElements (RADcommandBuffer cmdBuf, RADprimitiveType mode, RADindexType type, RADsizei count, RADindexHandle indexHandle, RADuint offset) {UNIMPLEMENTED();}\r
6298 RADboolean RADAPIENTRY radCompileCommandBuffer (RADcommandBuffer cmdBuf) {UNIMPLEMENTED(); return 0;}\r
6299 RADcommandHandle RADAPIENTRY radGetCommandHandle (RADcommandBuffer cmdBuf) {UNIMPLEMENTED(); return 0;}\r
6300 void RADAPIENTRY radCmdStencilValueMask (RADcommandBuffer cmdBuf, RADfaceBitfield faces, RADuint mask) {UNIMPLEMENTED();}\r
6301 void RADAPIENTRY radCmdStencilMask (RADcommandBuffer cmdBuf, RADfaceBitfield faces, RADuint mask) {UNIMPLEMENTED();}\r
6302 void RADAPIENTRY radCmdStencilRef (RADcommandBuffer cmdBuf, RADfaceBitfield faces, RADint ref) {UNIMPLEMENTED();}\r
6303 void RADAPIENTRY radCmdBlendColor (RADcommandBuffer cmdBuf, const RADfloat *blendColor) {UNIMPLEMENTED();}\r
6304 void RADAPIENTRY radCmdPointSize (RADcommandBuffer cmdBuf, RADfloat pointSize) {UNIMPLEMENTED();}\r
6305 void RADAPIENTRY radCmdLineWidth (RADcommandBuffer cmdBuf, RADfloat lineWidth) {UNIMPLEMENTED();}\r
6306 void RADAPIENTRY radCmdPolygonOffsetClamp (RADcommandBuffer cmdBuf, RADfloat factor, RADfloat units, RADfloat clamp) {UNIMPLEMENTED();}\r
6307 void RADAPIENTRY radCmdSampleMask (RADcommandBuffer cmdBuf, RADuint mask) {UNIMPLEMENTED();}\r
6308 RADpass RADAPIENTRY radCreatePass (RADdevice device) {UNIMPLEMENTED(); return 0;}\r
6309 void RADAPIENTRY radReferencePass (RADpass pass) {UNIMPLEMENTED();}\r
6310 void RADAPIENTRY radReleasePass (RADpass pass) {UNIMPLEMENTED();}\r
6311 void RADAPIENTRY radPassDefault (RADpass pass) {UNIMPLEMENTED();}\r
6312 void RADAPIENTRY radCompilePass (RADpass pass) {UNIMPLEMENTED();}\r
6313 void RADAPIENTRY radPassRenderTargets (RADpass pass, RADuint numColors, const RADrenderTargetHandle *colors, RADrenderTargetHandle depth, RADrenderTargetHandle stencil) {UNIMPLEMENTED();}\r
6314 void RADAPIENTRY radPassPreserveEnable (RADpass pass, RADrtAttachment attachment, RADboolean enable) {UNIMPLEMENTED();}\r
6315 void RADAPIENTRY radPassDiscard (RADpass pass, RADuint numTextures, const RADtexture *textures, const RADoffset2D *offsets) {UNIMPLEMENTED();}\r
6316 void RADAPIENTRY radPassResolve (RADpass pass, RADrtAttachment attachment, RADtexture texture) {UNIMPLEMENTED();}\r
6317 void RADAPIENTRY radPassStore (RADpass pass, RADuint numTextures, const RADtexture *textures, const RADoffset2D *offsets) {UNIMPLEMENTED();}\r
6318 void RADAPIENTRY radPassClip (RADpass pass, const RADrect2D *rect) {UNIMPLEMENTED();}\r
6319 void RADAPIENTRY radPassDependencies (RADpass pass, RADuint numPasses, const RADpass *otherPasses, const RADbitfield *srcMask, const RADbitfield *dstMask, const RADbitfield *flushMask, const RADbitfield *invalidateMask) {UNIMPLEMENTED();}\r
6320 void RADAPIENTRY radPassTilingBoundary (RADpass pass, RADboolean boundary) {UNIMPLEMENTED();}\r
6321 void RADAPIENTRY radPassTileFilterWidth (RADpass pass, RADuint filterWidth, RADuint filterHeight) {UNIMPLEMENTED();}\r
6322 void RADAPIENTRY radPassTileFootprint (RADpass pass, RADuint bytesPerPixel, RADuint maxFilterWidth, RADuint maxFilterHeight) {UNIMPLEMENTED();}\r
6323 RADsync RADAPIENTRY radCreateSync (RADdevice device) {UNIMPLEMENTED(); return 0;}\r
6324 void RADAPIENTRY radReferenceSync (RADsync sync) {UNIMPLEMENTED();}\r
6325 void RADAPIENTRY radReleaseSync (RADsync sync) {UNIMPLEMENTED();}\r
6326 void RADAPIENTRY radQueueFenceSync (RADqueue queue, RADsync sync, RADsyncCondition condition, RADbitfield flags) {UNIMPLEMENTED();}\r
6327 RADwaitSyncResult RADAPIENTRY radWaitSync (RADsync sync, RADuint64 timeout) {UNIMPLEMENTED(); return RAD_WAIT_SYNC_FAILED;}\r
6328 RADboolean RADAPIENTRY radQueueWaitSync (RADqueue queue, RADsync sync) {UNIMPLEMENTED(); return 0;}\r
6329 \r
6330 RADPROC RADAPIENTRY radGetProcAddress(const RADchar *procname)\r
6331 {\r
6332         struct Extension\r
6333     {\r
6334         const char *name;\r
6335         RADPROC address;\r
6336     };\r
6337 \r
6338     static const Extension glExtensions[] =\r
6339     {\r
6340         #define EXTENSION(name) {#name, (RADPROC)name}\r
6341                 \r
6342                 EXTENSION(radGetProcAddress),\r
6343                 EXTENSION(radCreateDevice),\r
6344                 EXTENSION(radReferenceDevice),\r
6345                 EXTENSION(radReleaseDevice),\r
6346                 EXTENSION(radGetTokenHeader),\r
6347                 EXTENSION(radCreateQueue),\r
6348                 EXTENSION(radReferenceQueue),\r
6349                 EXTENSION(radReleaseQueue),\r
6350                 EXTENSION(radQueueTagBuffer),\r
6351                 EXTENSION(radQueueTagTexture),\r
6352                 EXTENSION(radQueueSubmitCommands),\r
6353                 EXTENSION(radFlushQueue),\r
6354                 EXTENSION(radFinishQueue),\r
6355                 EXTENSION(radQueueViewport),\r
6356                 EXTENSION(radQueueScissor),\r
6357                 EXTENSION(radQueueCopyBufferToImage),\r
6358                 EXTENSION(radQueueCopyImageToBuffer),\r
6359                 EXTENSION(radQueueCopyBuffer),\r
6360                 EXTENSION(radQueueClearColor),\r
6361                 EXTENSION(radQueueClearDepth),\r
6362                 EXTENSION(radQueueClearStencil),\r
6363                 EXTENSION(radQueuePresent),\r
6364                 EXTENSION(radQueueDrawArrays),\r
6365                 EXTENSION(radQueueDrawElements),\r
6366                 EXTENSION(radQueueBindPipeline),\r
6367                 EXTENSION(radQueueBindGroup),\r
6368                 EXTENSION(radQueueBeginPass),\r
6369                 EXTENSION(radQueueEndPass),\r
6370                 EXTENSION(radQueueSubmitDynamic),\r
6371                 EXTENSION(radQueueStencilValueMask),\r
6372                 EXTENSION(radQueueStencilMask),\r
6373                 EXTENSION(radQueueStencilRef),\r
6374                 EXTENSION(radQueueBlendColor),\r
6375                 EXTENSION(radQueuePointSize),\r
6376                 EXTENSION(radQueueLineWidth),\r
6377                 EXTENSION(radQueuePolygonOffsetClamp),\r
6378                 EXTENSION(radQueueSampleMask),\r
6379                 EXTENSION(radCreateProgram),\r
6380                 EXTENSION(radReferenceProgram),\r
6381                 EXTENSION(radReleaseProgram),\r
6382                 EXTENSION(radProgramSource),\r
6383                 EXTENSION(radCreateBuffer),\r
6384                 EXTENSION(radReferenceBuffer),\r
6385                 EXTENSION(radReleaseBuffer),\r
6386                 EXTENSION(radBufferAccess),\r
6387                 EXTENSION(radBufferMapAccess),\r
6388                 EXTENSION(radBufferStorage),\r
6389                 EXTENSION(radMapBuffer),\r
6390                 EXTENSION(radGetVertexHandle),\r
6391                 EXTENSION(radGetIndexHandle),\r
6392                 EXTENSION(radGetUniformHandle),\r
6393                 EXTENSION(radGetBindGroupHandle),\r
6394                 EXTENSION(radCreateTexture),\r
6395                 EXTENSION(radReferenceTexture),\r
6396                 EXTENSION(radReleaseTexture),\r
6397                 EXTENSION(radTextureAccess),\r
6398                 EXTENSION(radTextureStorage),\r
6399                 EXTENSION(radGetTextureSamplerHandle),\r
6400                 EXTENSION(radGetTextureRenderTargetHandle),\r
6401                 EXTENSION(radCreateSampler),\r
6402                 EXTENSION(radReferenceSampler),\r
6403                 EXTENSION(radReleaseSampler),\r
6404                 EXTENSION(radSamplerDefault),\r
6405                 EXTENSION(radSamplerMinMagFilter),\r
6406                 EXTENSION(radSamplerWrapMode),\r
6407                 EXTENSION(radSamplerLodClamp),\r
6408                 EXTENSION(radSamplerLodBias),\r
6409                 EXTENSION(radSamplerCompare),\r
6410                 EXTENSION(radSamplerBorderColorFloat),\r
6411                 EXTENSION(radSamplerBorderColorInt),\r
6412                 EXTENSION(radCreateColorState),\r
6413                 EXTENSION(radReferenceColorState),\r
6414                 EXTENSION(radReleaseColorState),\r
6415                 EXTENSION(radColorDefault),\r
6416                 EXTENSION(radColorBlendEnable),\r
6417                 EXTENSION(radColorBlendFunc),\r
6418                 EXTENSION(radColorBlendEquation),\r
6419                 EXTENSION(radColorMask),\r
6420                 EXTENSION(radColorNumTargets),\r
6421                 EXTENSION(radColorLogicOpEnable),\r
6422                 EXTENSION(radColorLogicOp),\r
6423                 EXTENSION(radColorAlphaToCoverageEnable),\r
6424                 EXTENSION(radColorBlendColor),\r
6425                 EXTENSION(radColorDynamic),\r
6426                 EXTENSION(radCreateRasterState),\r
6427                 EXTENSION(radReferenceRasterState),\r
6428                 EXTENSION(radReleaseRasterState),\r
6429                 EXTENSION(radRasterDefault),\r
6430                 EXTENSION(radRasterPointSize),\r
6431                 EXTENSION(radRasterLineWidth),\r
6432                 EXTENSION(radRasterCullFace),\r
6433                 EXTENSION(radRasterFrontFace),\r
6434                 EXTENSION(radRasterPolygonMode),\r
6435                 EXTENSION(radRasterPolygonOffsetClamp),\r
6436                 EXTENSION(radRasterPolygonOffsetEnables),\r
6437                 EXTENSION(radRasterDiscardEnable),\r
6438                 EXTENSION(radRasterMultisampleEnable),\r
6439                 EXTENSION(radRasterSamples),\r
6440                 EXTENSION(radRasterSampleMask),\r
6441                 EXTENSION(radRasterDynamic),\r
6442                 EXTENSION(radCreateDepthStencilState),\r
6443                 EXTENSION(radReferenceDepthStencilState),\r
6444                 EXTENSION(radReleaseDepthStencilState),\r
6445                 EXTENSION(radDepthStencilDefault),\r
6446                 EXTENSION(radDepthStencilDepthTestEnable),\r
6447                 EXTENSION(radDepthStencilDepthWriteEnable),\r
6448                 EXTENSION(radDepthStencilDepthFunc),\r
6449                 EXTENSION(radDepthStencilStencilTestEnable),\r
6450                 EXTENSION(radDepthStencilStencilFunc),\r
6451                 EXTENSION(radDepthStencilStencilOp),\r
6452                 EXTENSION(radDepthStencilStencilMask),\r
6453                 EXTENSION(radDepthStencilDynamic),\r
6454                 EXTENSION(radCreateVertexState),\r
6455                 EXTENSION(radReferenceVertexState),\r
6456                 EXTENSION(radReleaseVertexState),\r
6457                 EXTENSION(radVertexDefault),\r
6458                 EXTENSION(radVertexAttribFormat),\r
6459                 EXTENSION(radVertexAttribBinding),\r
6460                 EXTENSION(radVertexBindingGroup),\r
6461                 EXTENSION(radVertexAttribEnable),\r
6462                 EXTENSION(radVertexBindingStride),\r
6463                 EXTENSION(radCreateRtFormatState),\r
6464                 EXTENSION(radReferenceRtFormatState),\r
6465                 EXTENSION(radReleaseRtFormatState),\r
6466                 EXTENSION(radRtFormatDefault),\r
6467                 EXTENSION(radRtFormatColorFormat),\r
6468                 EXTENSION(radRtFormatDepthFormat),\r
6469                 EXTENSION(radRtFormatStencilFormat),\r
6470                 EXTENSION(radRtFormatColorSamples),\r
6471                 EXTENSION(radRtFormatDepthStencilSamples),\r
6472                 EXTENSION(radCreatePipeline),\r
6473                 EXTENSION(radReferencePipeline),\r
6474                 EXTENSION(radReleasePipeline),\r
6475                 EXTENSION(radPipelineProgramStages),\r
6476                 EXTENSION(radPipelineVertexState),\r
6477                 EXTENSION(radPipelineColorState),\r
6478                 EXTENSION(radPipelineRasterState),\r
6479                 EXTENSION(radPipelineDepthStencilState),\r
6480                 EXTENSION(radPipelineRtFormatState),\r
6481                 EXTENSION(radPipelinePrimitiveType),\r
6482                 EXTENSION(radCompilePipeline),\r
6483                 EXTENSION(radGetPipelineHandle),\r
6484                 EXTENSION(radCreateCommandBuffer),\r
6485                 EXTENSION(radReferenceCommandBuffer),\r
6486                 EXTENSION(radReleaseCommandBuffer),\r
6487                 EXTENSION(radCmdBindPipeline),\r
6488                 EXTENSION(radCmdBindGroup),\r
6489                 EXTENSION(radCmdDrawArrays),\r
6490                 EXTENSION(radCmdDrawElements),\r
6491                 EXTENSION(radCompileCommandBuffer),\r
6492                 EXTENSION(radGetCommandHandle),\r
6493                 EXTENSION(radCmdStencilValueMask),\r
6494                 EXTENSION(radCmdStencilMask),\r
6495                 EXTENSION(radCmdStencilRef),\r
6496                 EXTENSION(radCmdBlendColor),\r
6497                 EXTENSION(radCmdPointSize),\r
6498                 EXTENSION(radCmdLineWidth),\r
6499                 EXTENSION(radCmdPolygonOffsetClamp),\r
6500                 EXTENSION(radCmdSampleMask),\r
6501                 EXTENSION(radCreatePass),\r
6502                 EXTENSION(radReferencePass),\r
6503                 EXTENSION(radReleasePass),\r
6504                 EXTENSION(radPassDefault),\r
6505                 EXTENSION(radCompilePass),\r
6506                 EXTENSION(radPassRenderTargets),\r
6507                 EXTENSION(radPassPreserveEnable),\r
6508                 EXTENSION(radPassDiscard),\r
6509                 EXTENSION(radPassResolve),\r
6510                 EXTENSION(radPassStore),\r
6511                 EXTENSION(radPassClip),\r
6512                 EXTENSION(radPassDependencies),\r
6513                 EXTENSION(radPassTilingBoundary),\r
6514                 EXTENSION(radPassTileFilterWidth),\r
6515                 EXTENSION(radPassTileFootprint),\r
6516                 EXTENSION(radCreateSync),\r
6517                 EXTENSION(radReferenceSync),\r
6518                 EXTENSION(radReleaseSync),\r
6519                 EXTENSION(radQueueFenceSync),\r
6520                 EXTENSION(radWaitSync),\r
6521                 EXTENSION(radQueueWaitSync),\r
6522 \r
6523                 #undef EXTENSION\r
6524     };\r
6525 \r
6526     for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)\r
6527     {\r
6528         if(strcmp(procname, glExtensions[ext].name) == 0)\r
6529         {\r
6530             return (RADPROC)glExtensions[ext].address;\r
6531         }\r
6532     }\r
6533 \r
6534     return NULL;\r
6535 }\r
6536 \r
6537 __eglMustCastToProperFunctionPointerType glGetProcAddress(const char *procname)\r
6538 {\r
6539     struct Extension\r
6540     {\r
6541         const char *name;\r
6542         __eglMustCastToProperFunctionPointerType address;\r
6543     };\r
6544 \r
6545     static const Extension glExtensions[] =\r
6546     {\r
6547                 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}\r
6548 \r
6549         EXTENSION(glTexImage3DOES),\r
6550         EXTENSION(glBlitFramebufferANGLE),\r
6551         EXTENSION(glRenderbufferStorageMultisampleANGLE),\r
6552         EXTENSION(glDeleteFencesNV),\r
6553         EXTENSION(glGenFencesNV),\r
6554         EXTENSION(glIsFenceNV),\r
6555         EXTENSION(glTestFenceNV),\r
6556         EXTENSION(glGetFenceivNV),\r
6557         EXTENSION(glFinishFenceNV),\r
6558         EXTENSION(glSetFenceNV),\r
6559                 EXTENSION(glGetGraphicsResetStatusEXT),\r
6560         EXTENSION(glReadnPixelsEXT),\r
6561         EXTENSION(glGetnUniformfvEXT),\r
6562         EXTENSION(glGetnUniformivEXT),\r
6563                 EXTENSION(glGenQueriesEXT),\r
6564         EXTENSION(glDeleteQueriesEXT),\r
6565         EXTENSION(glIsQueryEXT),\r
6566         EXTENSION(glBeginQueryEXT),\r
6567         EXTENSION(glEndQueryEXT),\r
6568         EXTENSION(glGetQueryivEXT),\r
6569         EXTENSION(glGetQueryObjectuivEXT),\r
6570         EXTENSION(glEGLImageTargetTexture2DOES),\r
6571 \r
6572                 EXTENSION(radGetProcAddress),\r
6573 \r
6574                 #undef EXTENSION\r
6575     };\r
6576 \r
6577     for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)\r
6578     {\r
6579         if(strcmp(procname, glExtensions[ext].name) == 0)\r
6580         {\r
6581             return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;\r
6582         }\r
6583     }\r
6584 \r
6585     return NULL;\r
6586 }\r
6587 \r
6588 void GL_APIENTRY Register(const char *licenseKey)\r
6589 {\r
6590         RegisterLicenseKey(licenseKey);\r
6591 }\r
6592 \r
6593 }\r