blob: 553d0a2e3985a1e0878a897f6e4ea45de03862d8 [file] [log] [blame]
Nicolas Capens264f1522015-01-09 17:21:17 -05001// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2013 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
Nicolas Capens79eef882015-01-09 17:38:27 -050011// libGL.cpp: Implements the exported OpenGL functions.
Nicolas Capens264f1522015-01-09 17:21:17 -050012
13#include "main.h"
14#include "mathutil.h"
15#include "utilities.h"
16#include "Buffer.h"
17#include "Context.h"
18#include "Fence.h"
19#include "Framebuffer.h"
20#include "Program.h"
21#include "Renderbuffer.h"
22#include "Shader.h"
23#include "Texture.h"
24#include "Query.h"
25#include "common/debug.h"
26#include "Common/Version.h"
27#include "Main/Register.hpp"
28
Nicolas Capensa9b49372015-01-30 00:33:26 -050029#define _GDI32_
30#include <windows.h>
31#include <GL/GL.h>
Nicolas Capensa9b49372015-01-30 00:33:26 -050032#include <GL/glext.h>
Nicolas Capens264f1522015-01-09 17:21:17 -050033
Nicolas Capens264f1522015-01-09 17:21:17 -050034#include <limits>
35
36static bool validImageSize(GLint level, GLsizei width, GLsizei height)
37{
Nicolas Capensf4486fd2015-01-22 11:10:37 -050038 if(level < 0 || level >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
Nicolas Capens264f1522015-01-09 17:21:17 -050039 {
40 return false;
41 }
42
43 return true;
44}
45
Nicolas Capensf4486fd2015-01-22 11:10:37 -050046static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, gl::Texture *texture)
Nicolas Capens264f1522015-01-09 17:21:17 -050047{
48 if(!texture)
49 {
50 return error(GL_INVALID_OPERATION, false);
51 }
52
53 if(compressed != texture->isCompressed(target, level))
54 {
55 return error(GL_INVALID_OPERATION, false);
56 }
57
Maxime Grégoiredff6d002015-07-16 10:26:45 -040058 if(format != GL_NONE && format != texture->getFormat(target, level))
Nicolas Capens264f1522015-01-09 17:21:17 -050059 {
60 return error(GL_INVALID_OPERATION, false);
61 }
62
63 if(compressed)
64 {
65 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
66 (height % 4 != 0 && height != texture->getHeight(target, 0)))
67 {
68 return error(GL_INVALID_OPERATION, false);
69 }
70 }
71
72 if(xoffset + width > texture->getWidth(target, level) ||
73 yoffset + height > texture->getHeight(target, level))
74 {
75 return error(GL_INVALID_VALUE, false);
76 }
77
78 return true;
79}
80
81// Check for combinations of format and type that are valid for ReadPixels
82static bool validReadFormatType(GLenum format, GLenum type)
83{
84 switch(format)
85 {
86 case GL_RGBA:
87 switch(type)
88 {
89 case GL_UNSIGNED_BYTE:
90 break;
91 default:
92 return false;
93 }
94 break;
95 case GL_BGRA_EXT:
96 switch(type)
97 {
98 case GL_UNSIGNED_BYTE:
Nicolas Capensa9b49372015-01-30 00:33:26 -050099 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
100 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
Nicolas Capens264f1522015-01-09 17:21:17 -0500101 break;
102 default:
103 return false;
104 }
105 break;
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500106 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500107 switch(type)
108 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500109 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
Nicolas Capens264f1522015-01-09 17:21:17 -0500110 break;
111 default:
112 return false;
113 }
114 break;
115 default:
116 return false;
117 }
118
119 return true;
120}
121
122extern "C"
123{
124
Nicolas Capensa9b49372015-01-30 00:33:26 -0500125void APIENTRY glActiveTexture(GLenum texture)
Nicolas Capens264f1522015-01-09 17:21:17 -0500126{
127 TRACE("(GLenum texture = 0x%X)", texture);
128
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500129 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500130
131 if(context)
132 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500133 if(context->getListIndex() != 0)
134 {
135 UNIMPLEMENTED();
136 }
137
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500138 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
Nicolas Capens264f1522015-01-09 17:21:17 -0500139 {
140 return error(GL_INVALID_ENUM);
141 }
142
143 context->setActiveSampler(texture - GL_TEXTURE0);
144 }
145}
146
Nicolas Capensa9b49372015-01-30 00:33:26 -0500147void APIENTRY glAttachShader(GLuint program, GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -0500148{
149 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
150
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500151 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500152
153 if(context)
154 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500155 gl::Program *programObject = context->getProgram(program);
156 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -0500157
158 if(!programObject)
159 {
160 if(context->getShader(program))
161 {
162 return error(GL_INVALID_OPERATION);
163 }
164 else
165 {
166 return error(GL_INVALID_VALUE);
167 }
168 }
169
170 if(!shaderObject)
171 {
172 if(context->getProgram(shader))
173 {
174 return error(GL_INVALID_OPERATION);
175 }
176 else
177 {
178 return error(GL_INVALID_VALUE);
179 }
180 }
181
182 if(!programObject->attachShader(shaderObject))
183 {
184 return error(GL_INVALID_OPERATION);
185 }
186 }
187}
188
Nicolas Capensa9b49372015-01-30 00:33:26 -0500189void APIENTRY glBeginQueryEXT(GLenum target, GLuint name)
Nicolas Capens264f1522015-01-09 17:21:17 -0500190{
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500191 TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
Nicolas Capens264f1522015-01-09 17:21:17 -0500192
193 switch(target)
194 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500195 case GL_ANY_SAMPLES_PASSED:
196 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
Nicolas Capens264f1522015-01-09 17:21:17 -0500197 break;
198 default:
199 return error(GL_INVALID_ENUM);
200 }
201
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500202 if(name == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -0500203 {
204 return error(GL_INVALID_OPERATION);
205 }
206
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500207 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500208
209 if(context)
210 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500211 if(context->getListIndex() != 0)
212 {
213 UNIMPLEMENTED();
214 }
215
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500216 context->beginQuery(target, name);
Nicolas Capens264f1522015-01-09 17:21:17 -0500217 }
218}
219
Nicolas Capensa9b49372015-01-30 00:33:26 -0500220void APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -0500221{
222 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
223
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500224 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -0500225 {
226 return error(GL_INVALID_VALUE);
227 }
228
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500229 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500230
231 if(context)
232 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500233 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -0500234
235 if(!programObject)
236 {
237 if(context->getShader(program))
238 {
239 return error(GL_INVALID_OPERATION);
240 }
241 else
242 {
243 return error(GL_INVALID_VALUE);
244 }
245 }
246
247 if(strncmp(name, "gl_", 3) == 0)
248 {
249 return error(GL_INVALID_OPERATION);
250 }
251
252 programObject->bindAttributeLocation(index, name);
253 }
254}
255
Nicolas Capensa9b49372015-01-30 00:33:26 -0500256void APIENTRY glBindBuffer(GLenum target, GLuint buffer)
Nicolas Capens264f1522015-01-09 17:21:17 -0500257{
258 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
259
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500260 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500261
262 if(context)
263 {
264 switch(target)
265 {
266 case GL_ARRAY_BUFFER:
267 context->bindArrayBuffer(buffer);
268 return;
269 case GL_ELEMENT_ARRAY_BUFFER:
270 context->bindElementArrayBuffer(buffer);
271 return;
272 default:
273 return error(GL_INVALID_ENUM);
274 }
275 }
276}
277
Nicolas Capensa9b49372015-01-30 00:33:26 -0500278void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -0500279{
280 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
281
Nicolas Capensa9b49372015-01-30 00:33:26 -0500282 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500283 {
284 return error(GL_INVALID_ENUM);
285 }
286
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500287 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500288
289 if(context)
290 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500291 if(context->getListIndex() != 0)
292 {
293 UNIMPLEMENTED();
294 }
295
296 if(target == GL_READ_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
Nicolas Capens264f1522015-01-09 17:21:17 -0500297 {
298 context->bindReadFramebuffer(framebuffer);
299 }
Nicolas Capensa9b49372015-01-30 00:33:26 -0500300
301 if(target == GL_DRAW_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
Nicolas Capens264f1522015-01-09 17:21:17 -0500302 {
303 context->bindDrawFramebuffer(framebuffer);
304 }
305 }
306}
307
Nicolas Capensa9b49372015-01-30 00:33:26 -0500308void APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -0500309{
310 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
311
312 if(target != GL_RENDERBUFFER)
313 {
314 return error(GL_INVALID_ENUM);
315 }
316
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500317 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500318
319 if(context)
320 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500321 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -0500322 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500323 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -0500324 }
325
326 context->bindRenderbuffer(renderbuffer);
327 }
328}
329
Nicolas Capensa9b49372015-01-30 00:33:26 -0500330void APIENTRY glBindTexture(GLenum target, GLuint texture)
Nicolas Capens264f1522015-01-09 17:21:17 -0500331{
332 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
333
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500334 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500335
336 if(context)
337 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500338 if(context->getListIndex() != 0)
339 {
340 UNIMPLEMENTED();
341 }
342
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500343 gl::Texture *textureObject = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -0500344
345 if(textureObject && textureObject->getTarget() != target && texture != 0)
346 {
347 return error(GL_INVALID_OPERATION);
348 }
349
350 switch(target)
351 {
352 case GL_TEXTURE_2D:
353 context->bindTexture2D(texture);
354 return;
355 case GL_TEXTURE_CUBE_MAP:
356 context->bindTextureCubeMap(texture);
357 return;
Nicolas Capens264f1522015-01-09 17:21:17 -0500358 default:
359 return error(GL_INVALID_ENUM);
360 }
361 }
362}
363
Nicolas Capensa9b49372015-01-30 00:33:26 -0500364void APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500365{
366 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
Nicolas Capensa9b49372015-01-30 00:33:26 -0500367 red, green, blue, alpha);
Nicolas Capens264f1522015-01-09 17:21:17 -0500368
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500369 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500370
371 if(context)
372 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500373 if(context->getListIndex() != 0)
374 {
375 UNIMPLEMENTED();
376 }
377
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500378 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
Nicolas Capens264f1522015-01-09 17:21:17 -0500379 }
380}
381
Nicolas Capensa9b49372015-01-30 00:33:26 -0500382void APIENTRY glBlendEquation(GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -0500383{
384 glBlendEquationSeparate(mode, mode);
385}
386
Nicolas Capensa9b49372015-01-30 00:33:26 -0500387void APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500388{
389 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
390
391 switch(modeRGB)
392 {
393 case GL_FUNC_ADD:
394 case GL_FUNC_SUBTRACT:
395 case GL_FUNC_REVERSE_SUBTRACT:
396 case GL_MIN_EXT:
397 case GL_MAX_EXT:
398 break;
399 default:
400 return error(GL_INVALID_ENUM);
401 }
402
403 switch(modeAlpha)
404 {
405 case GL_FUNC_ADD:
406 case GL_FUNC_SUBTRACT:
407 case GL_FUNC_REVERSE_SUBTRACT:
408 case GL_MIN_EXT:
409 case GL_MAX_EXT:
410 break;
411 default:
412 return error(GL_INVALID_ENUM);
413 }
414
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500415 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500416
417 if(context)
418 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500419 if(context->getListIndex() != 0)
420 {
421 UNIMPLEMENTED();
422 }
423
Nicolas Capens264f1522015-01-09 17:21:17 -0500424 context->setBlendEquation(modeRGB, modeAlpha);
425 }
426}
427
Nicolas Capensa9b49372015-01-30 00:33:26 -0500428void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
Nicolas Capens264f1522015-01-09 17:21:17 -0500429{
430 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
431}
432
Nicolas Capensa9b49372015-01-30 00:33:26 -0500433void APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500434{
435 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
436 srcRGB, dstRGB, srcAlpha, dstAlpha);
437
438 switch(srcRGB)
439 {
440 case GL_ZERO:
441 case GL_ONE:
442 case GL_SRC_COLOR:
443 case GL_ONE_MINUS_SRC_COLOR:
444 case GL_DST_COLOR:
445 case GL_ONE_MINUS_DST_COLOR:
446 case GL_SRC_ALPHA:
447 case GL_ONE_MINUS_SRC_ALPHA:
448 case GL_DST_ALPHA:
449 case GL_ONE_MINUS_DST_ALPHA:
450 case GL_CONSTANT_COLOR:
451 case GL_ONE_MINUS_CONSTANT_COLOR:
452 case GL_CONSTANT_ALPHA:
453 case GL_ONE_MINUS_CONSTANT_ALPHA:
454 case GL_SRC_ALPHA_SATURATE:
455 break;
456 default:
457 return error(GL_INVALID_ENUM);
458 }
459
460 switch(dstRGB)
461 {
462 case GL_ZERO:
463 case GL_ONE:
464 case GL_SRC_COLOR:
465 case GL_ONE_MINUS_SRC_COLOR:
466 case GL_DST_COLOR:
467 case GL_ONE_MINUS_DST_COLOR:
468 case GL_SRC_ALPHA:
469 case GL_ONE_MINUS_SRC_ALPHA:
470 case GL_DST_ALPHA:
471 case GL_ONE_MINUS_DST_ALPHA:
472 case GL_CONSTANT_COLOR:
473 case GL_ONE_MINUS_CONSTANT_COLOR:
474 case GL_CONSTANT_ALPHA:
475 case GL_ONE_MINUS_CONSTANT_ALPHA:
476 break;
477 default:
478 return error(GL_INVALID_ENUM);
479 }
480
481 switch(srcAlpha)
482 {
483 case GL_ZERO:
484 case GL_ONE:
485 case GL_SRC_COLOR:
486 case GL_ONE_MINUS_SRC_COLOR:
487 case GL_DST_COLOR:
488 case GL_ONE_MINUS_DST_COLOR:
489 case GL_SRC_ALPHA:
490 case GL_ONE_MINUS_SRC_ALPHA:
491 case GL_DST_ALPHA:
492 case GL_ONE_MINUS_DST_ALPHA:
493 case GL_CONSTANT_COLOR:
494 case GL_ONE_MINUS_CONSTANT_COLOR:
495 case GL_CONSTANT_ALPHA:
496 case GL_ONE_MINUS_CONSTANT_ALPHA:
497 case GL_SRC_ALPHA_SATURATE:
498 break;
499 default:
500 return error(GL_INVALID_ENUM);
501 }
502
503 switch(dstAlpha)
504 {
505 case GL_ZERO:
506 case GL_ONE:
507 case GL_SRC_COLOR:
508 case GL_ONE_MINUS_SRC_COLOR:
509 case GL_DST_COLOR:
510 case GL_ONE_MINUS_DST_COLOR:
511 case GL_SRC_ALPHA:
512 case GL_ONE_MINUS_SRC_ALPHA:
513 case GL_DST_ALPHA:
514 case GL_ONE_MINUS_DST_ALPHA:
515 case GL_CONSTANT_COLOR:
516 case GL_ONE_MINUS_CONSTANT_COLOR:
517 case GL_CONSTANT_ALPHA:
518 case GL_ONE_MINUS_CONSTANT_ALPHA:
519 break;
520 default:
521 return error(GL_INVALID_ENUM);
522 }
523
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500524 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500525
526 if(context)
527 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500528 if(context->getListIndex() != 0)
529 {
530 UNIMPLEMENTED();
531 }
532
Nicolas Capens264f1522015-01-09 17:21:17 -0500533 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
534 }
535}
536
Nicolas Capensa9b49372015-01-30 00:33:26 -0500537void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
Nicolas Capens264f1522015-01-09 17:21:17 -0500538{
Nicolas Capens4be33702015-04-28 15:13:30 -0700539 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
Nicolas Capens264f1522015-01-09 17:21:17 -0500540 target, size, data, usage);
541
542 if(size < 0)
543 {
544 return error(GL_INVALID_VALUE);
545 }
546
547 switch(usage)
548 {
549 case GL_STREAM_DRAW:
550 case GL_STATIC_DRAW:
551 case GL_DYNAMIC_DRAW:
552 break;
553 default:
554 return error(GL_INVALID_ENUM);
555 }
556
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500557 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500558
559 if(context)
560 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500561 gl::Buffer *buffer;
Nicolas Capens264f1522015-01-09 17:21:17 -0500562
563 switch(target)
564 {
565 case GL_ARRAY_BUFFER:
566 buffer = context->getArrayBuffer();
567 break;
568 case GL_ELEMENT_ARRAY_BUFFER:
569 buffer = context->getElementArrayBuffer();
570 break;
571 default:
572 return error(GL_INVALID_ENUM);
573 }
574
575 if(!buffer)
576 {
577 return error(GL_INVALID_OPERATION);
578 }
579
580 buffer->bufferData(data, size, usage);
581 }
582}
583
Nicolas Capensa9b49372015-01-30 00:33:26 -0500584void APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
Nicolas Capens264f1522015-01-09 17:21:17 -0500585{
Nicolas Capens4be33702015-04-28 15:13:30 -0700586 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -0500587 target, offset, size, data);
588
589 if(size < 0 || offset < 0)
590 {
591 return error(GL_INVALID_VALUE);
592 }
593
594 if(data == NULL)
595 {
596 return;
597 }
598
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500599 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500600
601 if(context)
602 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500603 gl::Buffer *buffer;
Nicolas Capens264f1522015-01-09 17:21:17 -0500604
605 switch(target)
606 {
607 case GL_ARRAY_BUFFER:
608 buffer = context->getArrayBuffer();
609 break;
610 case GL_ELEMENT_ARRAY_BUFFER:
611 buffer = context->getElementArrayBuffer();
612 break;
613 default:
614 return error(GL_INVALID_ENUM);
615 }
616
617 if(!buffer)
618 {
619 return error(GL_INVALID_OPERATION);
620 }
621
622 if((size_t)size + offset > buffer->size())
623 {
624 return error(GL_INVALID_VALUE);
625 }
626
627 buffer->bufferSubData(data, size, offset);
628 }
629}
630
Nicolas Capensa9b49372015-01-30 00:33:26 -0500631GLenum APIENTRY glCheckFramebufferStatus(GLenum target)
Nicolas Capens264f1522015-01-09 17:21:17 -0500632{
633 TRACE("(GLenum target = 0x%X)", target);
634
Nicolas Capensa9b49372015-01-30 00:33:26 -0500635 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500636 {
637 return error(GL_INVALID_ENUM, 0);
638 }
639
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500640 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500641
642 if(context)
643 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500644 if(context->getListIndex() != 0)
645 {
646 UNIMPLEMENTED();
647 }
648
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500649 gl::Framebuffer *framebuffer = NULL;
Nicolas Capensa9b49372015-01-30 00:33:26 -0500650 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500651 {
652 framebuffer = context->getReadFramebuffer();
653 }
654 else
655 {
656 framebuffer = context->getDrawFramebuffer();
657 }
658
659 return framebuffer->completeness();
660 }
661
662 return 0;
663}
664
Nicolas Capensa9b49372015-01-30 00:33:26 -0500665void APIENTRY glClear(GLbitfield mask)
Nicolas Capens264f1522015-01-09 17:21:17 -0500666{
667 TRACE("(GLbitfield mask = %X)", mask);
668
669 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
670 {
671 return error(GL_INVALID_VALUE);
672 }
673
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500674 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500675
676 if(context)
677 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500678 if(context->getListIndex() != 0)
679 {
680 return context->listCommand(gl::newCommand(glClear, mask));
681 }
682
Nicolas Capens264f1522015-01-09 17:21:17 -0500683 context->clear(mask);
684 }
685}
686
Nicolas Capensa9b49372015-01-30 00:33:26 -0500687void APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500688{
689 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
690 red, green, blue, alpha);
691
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500692 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500693
694 if(context)
695 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500696 if(context->getListIndex() != 0)
697 {
698 UNIMPLEMENTED();
699 }
700
Nicolas Capens264f1522015-01-09 17:21:17 -0500701 context->setClearColor(red, green, blue, alpha);
702 }
703}
704
Nicolas Capensa9b49372015-01-30 00:33:26 -0500705void APIENTRY glClearDepthf(GLclampf depth)
Nicolas Capens264f1522015-01-09 17:21:17 -0500706{
707 TRACE("(GLclampf depth = %f)", depth);
708
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500709 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500710
711 if(context)
712 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500713 if(context->getListIndex() != 0)
714 {
715 UNIMPLEMENTED();
716 }
717
Nicolas Capens264f1522015-01-09 17:21:17 -0500718 context->setClearDepth(depth);
719 }
720}
721
Nicolas Capensa9b49372015-01-30 00:33:26 -0500722void APIENTRY glClearStencil(GLint s)
Nicolas Capens264f1522015-01-09 17:21:17 -0500723{
724 TRACE("(GLint s = %d)", s);
725
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500726 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500727
728 if(context)
729 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500730 if(context->getListIndex() != 0)
731 {
732 UNIMPLEMENTED();
733 }
734
Nicolas Capens264f1522015-01-09 17:21:17 -0500735 context->setClearStencil(s);
736 }
737}
738
Nicolas Capensa9b49372015-01-30 00:33:26 -0500739void APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500740{
741 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
742 red, green, blue, alpha);
743
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500744 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500745
746 if(context)
747 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500748 if(context->getListIndex() != 0)
749 {
750 UNIMPLEMENTED();
751 }
752
Nicolas Capens264f1522015-01-09 17:21:17 -0500753 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
754 }
755}
756
Nicolas Capensa9b49372015-01-30 00:33:26 -0500757void APIENTRY glCompileShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -0500758{
759 TRACE("(GLuint shader = %d)", shader);
760
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500761 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500762
763 if(context)
764 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500765 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -0500766
767 if(!shaderObject)
768 {
769 if(context->getProgram(shader))
770 {
771 return error(GL_INVALID_OPERATION);
772 }
773 else
774 {
775 return error(GL_INVALID_VALUE);
776 }
777 }
778
779 shaderObject->compile();
780 }
781}
782
Nicolas Capensa9b49372015-01-30 00:33:26 -0500783void APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -0500784 GLint border, GLsizei imageSize, const GLvoid* data)
785{
786 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -0700787 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -0500788 target, level, internalformat, width, height, border, imageSize, data);
789
790 if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
791 {
792 return error(GL_INVALID_VALUE);
793 }
794
795 switch(internalformat)
796 {
Nicolas Capens264f1522015-01-09 17:21:17 -0500797 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
798 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500799 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
800 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500801 if(!S3TC_SUPPORT)
802 {
803 return error(GL_INVALID_ENUM);
804 }
805 break;
806 case GL_DEPTH_COMPONENT:
807 case GL_DEPTH_COMPONENT16:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500808 case GL_DEPTH_COMPONENT32:
809 case GL_DEPTH_STENCIL_EXT:
810 case GL_DEPTH24_STENCIL8_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500811 return error(GL_INVALID_OPERATION);
812 default:
813 return error(GL_INVALID_ENUM);
814 }
815
816 if(border != 0)
817 {
818 return error(GL_INVALID_VALUE);
819 }
820
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500821 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500822
823 if(context)
824 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500825 if(context->getListIndex() != 0)
826 {
827 UNIMPLEMENTED();
828 }
829
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500830 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -0500831 {
832 return error(GL_INVALID_VALUE);
833 }
834
835 switch(target)
836 {
837 case GL_TEXTURE_2D:
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500838 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
839 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -0500840 {
841 return error(GL_INVALID_VALUE);
842 }
843 break;
844 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
845 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
846 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
847 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
848 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
849 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
850 if(width != height)
851 {
852 return error(GL_INVALID_VALUE);
853 }
854
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500855 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
856 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -0500857 {
858 return error(GL_INVALID_VALUE);
859 }
860 break;
861 default:
862 return error(GL_INVALID_ENUM);
863 }
864
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500865 if(imageSize != gl::ComputeCompressedSize(width, height, internalformat))
Nicolas Capens264f1522015-01-09 17:21:17 -0500866 {
867 return error(GL_INVALID_VALUE);
868 }
869
870 if(target == GL_TEXTURE_2D)
871 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500872 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -0500873
874 if(!texture)
875 {
876 return error(GL_INVALID_OPERATION);
877 }
878
879 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
880 }
881 else
882 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500883 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -0500884
885 if(!texture)
886 {
887 return error(GL_INVALID_OPERATION);
888 }
889
890 switch(target)
891 {
892 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
893 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
894 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
895 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
896 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
897 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
898 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
899 break;
900 default: UNREACHABLE();
901 }
902 }
903 }
904}
905
Nicolas Capensa9b49372015-01-30 00:33:26 -0500906void APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -0500907 GLenum format, GLsizei imageSize, const GLvoid* data)
908{
909 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
910 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -0700911 "GLsizei imageSize = %d, const GLvoid* data = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -0500912 target, level, xoffset, yoffset, width, height, format, imageSize, data);
913
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500914 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -0500915 {
916 return error(GL_INVALID_ENUM);
917 }
918
919 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
920 {
921 return error(GL_INVALID_VALUE);
922 }
923
924 switch(format)
925 {
Nicolas Capens264f1522015-01-09 17:21:17 -0500926 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
927 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500928 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
929 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500930 if(!S3TC_SUPPORT)
931 {
932 return error(GL_INVALID_ENUM);
933 }
934 break;
935 default:
936 return error(GL_INVALID_ENUM);
937 }
938
939 if(width == 0 || height == 0 || data == NULL)
940 {
941 return;
942 }
943
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500944 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500945
946 if(context)
947 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500948 if(context->getListIndex() != 0)
949 {
950 UNIMPLEMENTED();
951 }
952
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500953 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -0500954 {
955 return error(GL_INVALID_VALUE);
956 }
957
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500958 if(imageSize != gl::ComputeCompressedSize(width, height, format))
Nicolas Capens264f1522015-01-09 17:21:17 -0500959 {
960 return error(GL_INVALID_VALUE);
961 }
962
963 if(xoffset % 4 != 0 || yoffset % 4 != 0)
964 {
965 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
966 return error(GL_INVALID_OPERATION);
967 }
968
969 if(target == GL_TEXTURE_2D)
970 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500971 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -0500972
973 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
974 {
975 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
976 }
977 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500978 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -0500979 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500980 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -0500981
982 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
983 {
984 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
985 }
986 }
987 else
988 {
989 UNREACHABLE();
990 }
991 }
992}
993
Nicolas Capensa9b49372015-01-30 00:33:26 -0500994void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
Nicolas Capens264f1522015-01-09 17:21:17 -0500995{
996 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
997 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
998 target, level, internalformat, x, y, width, height, border);
999
1000 if(!validImageSize(level, width, height))
1001 {
1002 return error(GL_INVALID_VALUE);
1003 }
1004
1005 if(border != 0)
1006 {
1007 return error(GL_INVALID_VALUE);
1008 }
1009
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001010 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001011
1012 if(context)
1013 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001014 if(context->getListIndex() != 0)
1015 {
1016 UNIMPLEMENTED();
1017 }
1018
Nicolas Capens264f1522015-01-09 17:21:17 -05001019 switch(target)
1020 {
1021 case GL_TEXTURE_2D:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001022 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
1023 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -05001024 {
1025 return error(GL_INVALID_VALUE);
1026 }
1027 break;
1028 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1029 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1030 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1031 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1032 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1033 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1034 if(width != height)
1035 {
1036 return error(GL_INVALID_VALUE);
1037 }
1038
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001039 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1040 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -05001041 {
1042 return error(GL_INVALID_VALUE);
1043 }
1044 break;
1045 default:
1046 return error(GL_INVALID_ENUM);
1047 }
1048
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001049 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001050
1051 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1052 {
1053 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1054 }
1055
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001056 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capens264f1522015-01-09 17:21:17 -05001057 {
1058 return error(GL_INVALID_OPERATION);
1059 }
1060
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001061 gl::Renderbuffer *source = framebuffer->getColorbuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001062 GLenum colorbufferFormat = source->getFormat();
1063
Nicolas Capens264f1522015-01-09 17:21:17 -05001064 switch(internalformat)
1065 {
1066 case GL_ALPHA:
1067 if(colorbufferFormat != GL_ALPHA &&
1068 colorbufferFormat != GL_RGBA &&
1069 colorbufferFormat != GL_RGBA4 &&
1070 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001071 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001072 {
1073 return error(GL_INVALID_OPERATION);
1074 }
1075 break;
1076 case GL_LUMINANCE:
1077 case GL_RGB:
1078 if(colorbufferFormat != GL_RGB &&
1079 colorbufferFormat != GL_RGB565 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001080 colorbufferFormat != GL_RGB8_EXT &&
Nicolas Capens264f1522015-01-09 17:21:17 -05001081 colorbufferFormat != GL_RGBA &&
1082 colorbufferFormat != GL_RGBA4 &&
1083 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001084 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001085 {
1086 return error(GL_INVALID_OPERATION);
1087 }
1088 break;
1089 case GL_LUMINANCE_ALPHA:
1090 case GL_RGBA:
1091 if(colorbufferFormat != GL_RGBA &&
1092 colorbufferFormat != GL_RGBA4 &&
1093 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001094 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001095 {
1096 return error(GL_INVALID_OPERATION);
1097 }
1098 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001099 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1100 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05001101 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1102 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05001103 if(S3TC_SUPPORT)
1104 {
1105 return error(GL_INVALID_OPERATION);
1106 }
1107 else
1108 {
1109 return error(GL_INVALID_ENUM);
1110 }
1111 default:
1112 return error(GL_INVALID_ENUM);
1113 }
1114
1115 if(target == GL_TEXTURE_2D)
1116 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001117 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05001118
1119 if(!texture)
1120 {
1121 return error(GL_INVALID_OPERATION);
1122 }
1123
1124 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
1125 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001126 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05001127 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001128 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05001129
1130 if(!texture)
1131 {
1132 return error(GL_INVALID_OPERATION);
1133 }
1134
1135 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
1136 }
1137 else UNREACHABLE();
1138 }
1139}
1140
Nicolas Capensa9b49372015-01-30 00:33:26 -05001141void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05001142{
1143 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1144 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
1145 target, level, xoffset, yoffset, x, y, width, height);
1146
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001147 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05001148 {
1149 return error(GL_INVALID_ENUM);
1150 }
1151
1152 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
1153 {
1154 return error(GL_INVALID_VALUE);
1155 }
1156
1157 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1158 {
1159 return error(GL_INVALID_VALUE);
1160 }
1161
1162 if(width == 0 || height == 0)
1163 {
1164 return;
1165 }
1166
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001167 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001168
1169 if(context)
1170 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001171 if(context->getListIndex() != 0)
1172 {
1173 UNIMPLEMENTED();
1174 }
1175
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001176 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -05001177 {
1178 return error(GL_INVALID_VALUE);
1179 }
1180
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001181 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001182
1183 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1184 {
1185 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1186 }
1187
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001188 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capens264f1522015-01-09 17:21:17 -05001189 {
1190 return error(GL_INVALID_OPERATION);
1191 }
1192
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001193 gl::Renderbuffer *source = framebuffer->getColorbuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001194 GLenum colorbufferFormat = source->getFormat();
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001195 gl::Texture *texture = NULL;
Nicolas Capens264f1522015-01-09 17:21:17 -05001196
1197 if(target == GL_TEXTURE_2D)
1198 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001199 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05001200 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001201 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05001202 {
1203 texture = context->getTextureCubeMap();
1204 }
1205 else UNREACHABLE();
1206
1207 if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))
1208 {
1209 return;
1210 }
1211
1212 GLenum textureFormat = texture->getFormat(target, level);
1213
Nicolas Capens264f1522015-01-09 17:21:17 -05001214 switch(textureFormat)
1215 {
1216 case GL_ALPHA:
1217 if(colorbufferFormat != GL_ALPHA &&
1218 colorbufferFormat != GL_RGBA &&
1219 colorbufferFormat != GL_RGBA4 &&
1220 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001221 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001222 {
1223 return error(GL_INVALID_OPERATION);
1224 }
1225 break;
1226 case GL_LUMINANCE:
1227 case GL_RGB:
1228 if(colorbufferFormat != GL_RGB &&
1229 colorbufferFormat != GL_RGB565 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001230 colorbufferFormat != GL_RGB8_EXT &&
Nicolas Capens264f1522015-01-09 17:21:17 -05001231 colorbufferFormat != GL_RGBA &&
1232 colorbufferFormat != GL_RGBA4 &&
1233 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001234 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001235 {
1236 return error(GL_INVALID_OPERATION);
1237 }
1238 break;
1239 case GL_LUMINANCE_ALPHA:
1240 case GL_RGBA:
1241 if(colorbufferFormat != GL_RGBA &&
1242 colorbufferFormat != GL_RGBA4 &&
1243 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001244 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001245 {
1246 return error(GL_INVALID_OPERATION);
1247 }
1248 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001249 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1250 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05001251 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1252 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1253 return error(GL_INVALID_OPERATION);
1254 case GL_DEPTH_COMPONENT:
1255 case GL_DEPTH_STENCIL_EXT:
1256 return error(GL_INVALID_OPERATION);
1257 case GL_BGRA_EXT:
1258 if(colorbufferFormat != GL_RGB8)
Nicolas Capens264f1522015-01-09 17:21:17 -05001259 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001260 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05001261 return error(GL_INVALID_OPERATION);
1262 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05001263 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001264 default:
1265 return error(GL_INVALID_ENUM);
1266 }
1267
1268 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
1269 }
1270}
1271
Nicolas Capensa9b49372015-01-30 00:33:26 -05001272GLuint APIENTRY glCreateProgram(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05001273{
1274 TRACE("()");
1275
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001276 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001277
1278 if(context)
1279 {
1280 return context->createProgram();
1281 }
1282
1283 return 0;
1284}
1285
Nicolas Capensa9b49372015-01-30 00:33:26 -05001286GLuint APIENTRY glCreateShader(GLenum type)
Nicolas Capens264f1522015-01-09 17:21:17 -05001287{
1288 TRACE("(GLenum type = 0x%X)", type);
1289
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001290 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001291
1292 if(context)
1293 {
1294 switch(type)
1295 {
1296 case GL_FRAGMENT_SHADER:
1297 case GL_VERTEX_SHADER:
1298 return context->createShader(type);
1299 default:
1300 return error(GL_INVALID_ENUM, 0);
1301 }
1302 }
1303
1304 return 0;
1305}
1306
Nicolas Capensa9b49372015-01-30 00:33:26 -05001307void APIENTRY glCullFace(GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05001308{
1309 TRACE("(GLenum mode = 0x%X)", mode);
1310
1311 switch(mode)
1312 {
1313 case GL_FRONT:
1314 case GL_BACK:
1315 case GL_FRONT_AND_BACK:
1316 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001317 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001318
1319 if(context)
1320 {
1321 context->setCullMode(mode);
1322 }
1323 }
1324 break;
1325 default:
1326 return error(GL_INVALID_ENUM);
1327 }
1328}
1329
Nicolas Capensa9b49372015-01-30 00:33:26 -05001330void APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05001331{
Nicolas Capens4be33702015-04-28 15:13:30 -07001332 TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
Nicolas Capens264f1522015-01-09 17:21:17 -05001333
1334 if(n < 0)
1335 {
1336 return error(GL_INVALID_VALUE);
1337 }
1338
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001339 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001340
1341 if(context)
1342 {
1343 for(int i = 0; i < n; i++)
1344 {
1345 context->deleteBuffer(buffers[i]);
1346 }
1347 }
1348}
1349
Nicolas Capensa9b49372015-01-30 00:33:26 -05001350void APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
Nicolas Capens264f1522015-01-09 17:21:17 -05001351{
Nicolas Capens4be33702015-04-28 15:13:30 -07001352 TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);
Nicolas Capens264f1522015-01-09 17:21:17 -05001353
1354 if(n < 0)
1355 {
1356 return error(GL_INVALID_VALUE);
1357 }
1358
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001359 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001360
1361 if(context)
1362 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001363 if(context->getListIndex() != 0)
1364 {
1365 UNIMPLEMENTED();
1366 }
1367
Nicolas Capens264f1522015-01-09 17:21:17 -05001368 for(int i = 0; i < n; i++)
1369 {
1370 context->deleteFence(fences[i]);
1371 }
1372 }
1373}
1374
Nicolas Capensa9b49372015-01-30 00:33:26 -05001375void APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05001376{
Nicolas Capens4be33702015-04-28 15:13:30 -07001377 TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
Nicolas Capens264f1522015-01-09 17:21:17 -05001378
1379 if(n < 0)
1380 {
1381 return error(GL_INVALID_VALUE);
1382 }
1383
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001384 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001385
1386 if(context)
1387 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001388 if(context->getListIndex() != 0)
1389 {
1390 UNIMPLEMENTED();
1391 }
1392
Nicolas Capens264f1522015-01-09 17:21:17 -05001393 for(int i = 0; i < n; i++)
1394 {
1395 if(framebuffers[i] != 0)
1396 {
1397 context->deleteFramebuffer(framebuffers[i]);
1398 }
1399 }
1400 }
1401}
1402
Nicolas Capensa9b49372015-01-30 00:33:26 -05001403void APIENTRY glDeleteProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05001404{
1405 TRACE("(GLuint program = %d)", program);
1406
1407 if(program == 0)
1408 {
1409 return;
1410 }
1411
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001412 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001413
1414 if(context)
1415 {
1416 if(!context->getProgram(program))
1417 {
1418 if(context->getShader(program))
1419 {
1420 return error(GL_INVALID_OPERATION);
1421 }
1422 else
1423 {
1424 return error(GL_INVALID_VALUE);
1425 }
1426 }
1427
1428 context->deleteProgram(program);
1429 }
1430}
1431
Nicolas Capensa9b49372015-01-30 00:33:26 -05001432void APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
Nicolas Capens264f1522015-01-09 17:21:17 -05001433{
Nicolas Capens4be33702015-04-28 15:13:30 -07001434 TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
Nicolas Capens264f1522015-01-09 17:21:17 -05001435
1436 if(n < 0)
1437 {
1438 return error(GL_INVALID_VALUE);
1439 }
1440
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001441 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001442
1443 if(context)
1444 {
1445 for(int i = 0; i < n; i++)
1446 {
1447 context->deleteQuery(ids[i]);
1448 }
1449 }
1450}
1451
Nicolas Capensa9b49372015-01-30 00:33:26 -05001452void APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05001453{
Nicolas Capens4be33702015-04-28 15:13:30 -07001454 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
Nicolas Capens264f1522015-01-09 17:21:17 -05001455
1456 if(n < 0)
1457 {
1458 return error(GL_INVALID_VALUE);
1459 }
1460
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001461 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001462
1463 if(context)
1464 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001465 if(context->getListIndex() != 0)
1466 {
1467 UNIMPLEMENTED();
1468 }
1469
Nicolas Capens264f1522015-01-09 17:21:17 -05001470 for(int i = 0; i < n; i++)
1471 {
1472 context->deleteRenderbuffer(renderbuffers[i]);
1473 }
1474 }
1475}
1476
Nicolas Capensa9b49372015-01-30 00:33:26 -05001477void APIENTRY glDeleteShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05001478{
1479 TRACE("(GLuint shader = %d)", shader);
1480
1481 if(shader == 0)
1482 {
1483 return;
1484 }
1485
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001486 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001487
1488 if(context)
1489 {
1490 if(!context->getShader(shader))
1491 {
1492 if(context->getProgram(shader))
1493 {
1494 return error(GL_INVALID_OPERATION);
1495 }
1496 else
1497 {
1498 return error(GL_INVALID_VALUE);
1499 }
1500 }
1501
1502 context->deleteShader(shader);
1503 }
1504}
1505
Nicolas Capensa9b49372015-01-30 00:33:26 -05001506void APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
Nicolas Capens264f1522015-01-09 17:21:17 -05001507{
Nicolas Capens4be33702015-04-28 15:13:30 -07001508 TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
Nicolas Capens264f1522015-01-09 17:21:17 -05001509
1510 if(n < 0)
1511 {
1512 return error(GL_INVALID_VALUE);
1513 }
1514
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001515 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001516
1517 if(context)
1518 {
1519 for(int i = 0; i < n; i++)
1520 {
1521 if(textures[i] != 0)
1522 {
1523 context->deleteTexture(textures[i]);
1524 }
1525 }
1526 }
1527}
1528
Nicolas Capensa9b49372015-01-30 00:33:26 -05001529void APIENTRY glDepthFunc(GLenum func)
Nicolas Capens264f1522015-01-09 17:21:17 -05001530{
1531 TRACE("(GLenum func = 0x%X)", func);
1532
1533 switch(func)
1534 {
1535 case GL_NEVER:
1536 case GL_ALWAYS:
1537 case GL_LESS:
1538 case GL_LEQUAL:
1539 case GL_EQUAL:
1540 case GL_GREATER:
1541 case GL_GEQUAL:
1542 case GL_NOTEQUAL:
1543 break;
1544 default:
1545 return error(GL_INVALID_ENUM);
1546 }
1547
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001548 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001549
1550 if(context)
1551 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001552 if(context->getListIndex() != 0)
1553 {
1554 UNIMPLEMENTED();
1555 }
1556
Nicolas Capens264f1522015-01-09 17:21:17 -05001557 context->setDepthFunc(func);
1558 }
1559}
1560
Nicolas Capensa9b49372015-01-30 00:33:26 -05001561void APIENTRY glDepthMask(GLboolean flag)
Nicolas Capens264f1522015-01-09 17:21:17 -05001562{
1563 TRACE("(GLboolean flag = %d)", flag);
1564
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001565 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001566
1567 if(context)
1568 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001569 if(context->getListIndex() != 0)
1570 {
1571 UNIMPLEMENTED();
1572 }
1573
Nicolas Capens264f1522015-01-09 17:21:17 -05001574 context->setDepthMask(flag != GL_FALSE);
1575 }
1576}
1577
Nicolas Capensa9b49372015-01-30 00:33:26 -05001578void APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
Nicolas Capens264f1522015-01-09 17:21:17 -05001579{
1580 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
1581
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001582 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001583
1584 if(context)
1585 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001586 if(context->getListIndex() != 0)
1587 {
1588 UNIMPLEMENTED();
1589 }
1590
Nicolas Capens264f1522015-01-09 17:21:17 -05001591 context->setDepthRange(zNear, zFar);
1592 }
1593}
1594
Nicolas Capensa9b49372015-01-30 00:33:26 -05001595void APIENTRY glDetachShader(GLuint program, GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05001596{
1597 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
1598
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001599 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001600
1601 if(context)
1602 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001603 gl::Program *programObject = context->getProgram(program);
1604 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05001605
1606 if(!programObject)
1607 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001608 gl::Shader *shaderByProgramHandle;
Nicolas Capens264f1522015-01-09 17:21:17 -05001609 shaderByProgramHandle = context->getShader(program);
1610 if(!shaderByProgramHandle)
1611 {
1612 return error(GL_INVALID_VALUE);
1613 }
1614 else
1615 {
1616 return error(GL_INVALID_OPERATION);
1617 }
1618 }
1619
1620 if(!shaderObject)
1621 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001622 gl::Program *programByShaderHandle = context->getProgram(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05001623 if(!programByShaderHandle)
1624 {
1625 return error(GL_INVALID_VALUE);
1626 }
1627 else
1628 {
1629 return error(GL_INVALID_OPERATION);
1630 }
1631 }
1632
1633 if(!programObject->detachShader(shaderObject))
1634 {
1635 return error(GL_INVALID_OPERATION);
1636 }
1637 }
1638}
1639
Nicolas Capensa9b49372015-01-30 00:33:26 -05001640void APIENTRY glDisable(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05001641{
1642 TRACE("(GLenum cap = 0x%X)", cap);
1643
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001644 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001645
1646 if(context)
1647 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001648 if(context->getListIndex() != 0)
1649 {
1650 UNIMPLEMENTED();
1651 }
1652
Nicolas Capens264f1522015-01-09 17:21:17 -05001653 switch(cap)
1654 {
Maxime Grégoiredff6d002015-07-16 10:26:45 -04001655 case GL_CULL_FACE: context->setCullFace(false); break;
1656 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1657 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1658 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1659 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1660 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1661 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1662 case GL_BLEND: context->setBlend(false); break;
1663 case GL_DITHER: context->setDither(false); break;
1664 case GL_LIGHTING: context->setLighting(false); break;
1665 case GL_FOG: context->setFog(false); break;
1666 case GL_ALPHA_TEST: context->setAlphaTest(false); break;
1667 case GL_TEXTURE_2D: context->setTexture2D(false); break;
1668 case GL_LIGHT0: context->setLight(0, false); break;
1669 case GL_LIGHT1: context->setLight(1, false); break;
1670 case GL_LIGHT2: context->setLight(2, false); break;
1671 case GL_LIGHT3: context->setLight(3, false); break;
1672 case GL_LIGHT4: context->setLight(4, false); break;
1673 case GL_LIGHT5: context->setLight(5, false); break;
1674 case GL_LIGHT6: context->setLight(6, false); break;
1675 case GL_LIGHT7: context->setLight(7, false); break;
1676 case GL_COLOR_MATERIAL: context->setColorMaterial(false); break;
1677 case GL_RESCALE_NORMAL: context->setNormalizeNormals(false); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001678 default:
1679 return error(GL_INVALID_ENUM);
1680 }
1681 }
1682}
1683
Nicolas Capensa9b49372015-01-30 00:33:26 -05001684void APIENTRY glDisableVertexAttribArray(GLuint index)
Nicolas Capens264f1522015-01-09 17:21:17 -05001685{
1686 TRACE("(GLuint index = %d)", index);
1687
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001688 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05001689 {
1690 return error(GL_INVALID_VALUE);
1691 }
1692
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001693 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001694
1695 if(context)
1696 {
1697 context->setEnableVertexAttribArray(index, false);
1698 }
1699}
1700
Nicolas Capensa9b49372015-01-30 00:33:26 -05001701void APIENTRY glCaptureAttribs()
1702{
1703 TRACE("()");
1704
1705 gl::Context *context = gl::getContext();
1706
1707 if(context)
1708 {
1709 context->captureAttribs();
1710 }
1711}
1712
1713void APIENTRY glRestoreAttribs()
1714{
1715 TRACE("()");
1716
1717 gl::Context *context = gl::getContext();
1718
1719 if(context)
1720 {
1721 context->restoreAttribs();
1722 }
1723}
1724
1725void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
Nicolas Capens264f1522015-01-09 17:21:17 -05001726{
1727 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
1728
1729 if(count < 0 || first < 0)
1730 {
1731 return error(GL_INVALID_VALUE);
1732 }
1733
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001734 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001735
1736 if(context)
1737 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001738 if(context->getListIndex() != 0)
1739 {
1740 ASSERT(context->getListMode() != GL_COMPILE_AND_EXECUTE); // UNIMPLEMENTED!
1741
1742 context->listCommand(gl::newCommand(glCaptureAttribs));
1743 context->captureDrawArrays(mode, first, count);
1744 context->listCommand(gl::newCommand(glDrawArrays, mode, first, count));
1745 context->listCommand(gl::newCommand(glRestoreAttribs));
1746
1747 return;
1748 }
1749
Nicolas Capens264f1522015-01-09 17:21:17 -05001750 context->drawArrays(mode, first, count);
1751 }
1752}
1753
Nicolas Capensa9b49372015-01-30 00:33:26 -05001754void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
Nicolas Capens264f1522015-01-09 17:21:17 -05001755{
Nicolas Capens4be33702015-04-28 15:13:30 -07001756 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05001757 mode, count, type, indices);
1758
1759 if(count < 0)
1760 {
1761 return error(GL_INVALID_VALUE);
1762 }
1763
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001764 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001765
1766 if(context)
1767 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001768 if(context->getListIndex() != 0)
1769 {
1770 UNIMPLEMENTED();
1771 }
1772
Nicolas Capens264f1522015-01-09 17:21:17 -05001773 switch(type)
1774 {
1775 case GL_UNSIGNED_BYTE:
1776 case GL_UNSIGNED_SHORT:
1777 case GL_UNSIGNED_INT:
1778 break;
1779 default:
1780 return error(GL_INVALID_ENUM);
1781 }
1782
1783 context->drawElements(mode, count, type, indices);
1784 }
1785}
1786
Nicolas Capensa9b49372015-01-30 00:33:26 -05001787void APIENTRY glEnable(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05001788{
1789 TRACE("(GLenum cap = 0x%X)", cap);
1790
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001791 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001792
1793 if(context)
1794 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001795 if(context->getListIndex() != 0)
1796 {
1797 UNIMPLEMENTED();
1798 }
1799
Nicolas Capens264f1522015-01-09 17:21:17 -05001800 switch(cap)
1801 {
1802 case GL_CULL_FACE: context->setCullFace(true); break;
1803 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1804 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1805 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1806 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1807 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1808 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1809 case GL_BLEND: context->setBlend(true); break;
1810 case GL_DITHER: context->setDither(true); break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05001811 case GL_TEXTURE_2D: context->setTexture2D(true); break;
1812 case GL_ALPHA_TEST: context->setAlphaTest(true); break;
1813 case GL_COLOR_MATERIAL: context->setColorMaterial(true); break;
1814 case GL_FOG: context->setFog(true); break;
1815 case GL_LIGHTING: context->setLighting(true); break;
1816 case GL_LIGHT0: context->setLight(0, true); break;
1817 case GL_LIGHT1: context->setLight(1, true); break;
1818 case GL_LIGHT2: context->setLight(2, true); break;
1819 case GL_LIGHT3: context->setLight(3, true); break;
1820 case GL_LIGHT4: context->setLight(4, true); break;
1821 case GL_LIGHT5: context->setLight(5, true); break;
1822 case GL_LIGHT6: context->setLight(6, true); break;
1823 case GL_LIGHT7: context->setLight(7, true); break;
1824 case GL_RESCALE_NORMAL: context->setNormalizeNormals(true); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001825 default:
1826 return error(GL_INVALID_ENUM);
1827 }
1828 }
1829}
1830
Nicolas Capensa9b49372015-01-30 00:33:26 -05001831void APIENTRY glEnableVertexAttribArray(GLuint index)
Nicolas Capens264f1522015-01-09 17:21:17 -05001832{
1833 TRACE("(GLuint index = %d)", index);
1834
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001835 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05001836 {
1837 return error(GL_INVALID_VALUE);
1838 }
1839
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001840 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001841
1842 if(context)
1843 {
1844 context->setEnableVertexAttribArray(index, true);
1845 }
1846}
1847
Nicolas Capensa9b49372015-01-30 00:33:26 -05001848void APIENTRY glEndQueryEXT(GLenum target)
Nicolas Capens264f1522015-01-09 17:21:17 -05001849{
1850 TRACE("GLenum target = 0x%X)", target);
1851
1852 switch(target)
1853 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001854 case GL_ANY_SAMPLES_PASSED:
1855 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
Nicolas Capens264f1522015-01-09 17:21:17 -05001856 break;
1857 default:
1858 return error(GL_INVALID_ENUM);
1859 }
1860
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001861 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001862
1863 if(context)
1864 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001865 if(context->getListIndex() != 0)
1866 {
1867 UNIMPLEMENTED();
1868 }
1869
Nicolas Capens264f1522015-01-09 17:21:17 -05001870 context->endQuery(target);
1871 }
1872}
1873
Nicolas Capensa9b49372015-01-30 00:33:26 -05001874void APIENTRY glFinishFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05001875{
1876 TRACE("(GLuint fence = %d)", fence);
1877
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001878 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001879
1880 if(context)
1881 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001882 if(context->getListIndex() != 0)
1883 {
1884 UNIMPLEMENTED();
1885 }
1886
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001887 gl::Fence* fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05001888
1889 if(fenceObject == NULL)
1890 {
1891 return error(GL_INVALID_OPERATION);
1892 }
1893
1894 fenceObject->finishFence();
1895 }
1896}
1897
Nicolas Capensa9b49372015-01-30 00:33:26 -05001898void APIENTRY glFinish(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05001899{
1900 TRACE("()");
1901
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001902 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001903
1904 if(context)
1905 {
1906 context->finish();
1907 }
1908}
1909
Nicolas Capensa9b49372015-01-30 00:33:26 -05001910void APIENTRY glFlush(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05001911{
1912 TRACE("()");
1913
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001914 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001915
1916 if(context)
1917 {
1918 context->flush();
1919 }
1920}
1921
Nicolas Capensa9b49372015-01-30 00:33:26 -05001922void APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05001923{
1924 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1925 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
1926
Nicolas Capensa9b49372015-01-30 00:33:26 -05001927 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT) ||
Nicolas Capens264f1522015-01-09 17:21:17 -05001928 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
1929 {
1930 return error(GL_INVALID_ENUM);
1931 }
1932
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001933 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001934
1935 if(context)
1936 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001937 if(context->getListIndex() != 0)
1938 {
1939 UNIMPLEMENTED();
1940 }
1941
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001942 gl::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001943 GLuint framebufferName = 0;
Nicolas Capensa9b49372015-01-30 00:33:26 -05001944 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001945 {
1946 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001947 framebufferName = context->getReadFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05001948 }
1949 else
1950 {
1951 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001952 framebufferName = context->getDrawFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05001953 }
1954
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001955 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
Nicolas Capens264f1522015-01-09 17:21:17 -05001956 {
1957 return error(GL_INVALID_OPERATION);
1958 }
1959
1960 switch(attachment)
1961 {
1962 case GL_COLOR_ATTACHMENT0:
1963 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1964 break;
1965 case GL_DEPTH_ATTACHMENT:
1966 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1967 break;
1968 case GL_STENCIL_ATTACHMENT:
1969 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1970 break;
1971 default:
1972 return error(GL_INVALID_ENUM);
1973 }
1974 }
1975}
1976
Nicolas Capensa9b49372015-01-30 00:33:26 -05001977void APIENTRY glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1978{
1979 UNIMPLEMENTED();
1980}
1981
1982void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
Nicolas Capens264f1522015-01-09 17:21:17 -05001983{
1984 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1985 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
1986
Nicolas Capensa9b49372015-01-30 00:33:26 -05001987 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001988 {
1989 return error(GL_INVALID_ENUM);
1990 }
1991
1992 switch(attachment)
1993 {
1994 case GL_COLOR_ATTACHMENT0:
1995 case GL_DEPTH_ATTACHMENT:
1996 case GL_STENCIL_ATTACHMENT:
1997 break;
1998 default:
1999 return error(GL_INVALID_ENUM);
2000 }
2001
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002002 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002003
2004 if(context)
2005 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002006 if(context->getListIndex() != 0)
2007 {
2008 UNIMPLEMENTED();
2009 }
2010
Nicolas Capens264f1522015-01-09 17:21:17 -05002011 if(texture == 0)
2012 {
2013 textarget = GL_NONE;
2014 }
2015 else
2016 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002017 gl::Texture *tex = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -05002018
2019 if(tex == NULL)
2020 {
2021 return error(GL_INVALID_OPERATION);
2022 }
2023
2024 if(tex->isCompressed(textarget, level))
2025 {
2026 return error(GL_INVALID_OPERATION);
2027 }
2028
2029 switch(textarget)
2030 {
2031 case GL_TEXTURE_2D:
2032 if(tex->getTarget() != GL_TEXTURE_2D)
2033 {
2034 return error(GL_INVALID_OPERATION);
2035 }
2036 break;
2037 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2038 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2039 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2040 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2041 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2042 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2043 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2044 {
2045 return error(GL_INVALID_OPERATION);
2046 }
2047 break;
2048 default:
2049 return error(GL_INVALID_ENUM);
2050 }
2051
2052 if(level != 0)
2053 {
2054 return error(GL_INVALID_VALUE);
2055 }
2056 }
2057
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002058 gl::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002059 GLuint framebufferName = 0;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002060 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05002061 {
2062 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002063 framebufferName = context->getReadFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002064 }
2065 else
2066 {
2067 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002068 framebufferName = context->getDrawFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002069 }
2070
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002071 if(framebufferName == 0 || !framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05002072 {
2073 return error(GL_INVALID_OPERATION);
2074 }
2075
2076 switch(attachment)
2077 {
2078 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2079 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2080 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2081 }
2082 }
2083}
2084
Nicolas Capensa9b49372015-01-30 00:33:26 -05002085void APIENTRY glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
2086{
2087 UNIMPLEMENTED();
2088}
2089
2090void APIENTRY glFrontFace(GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05002091{
2092 TRACE("(GLenum mode = 0x%X)", mode);
2093
2094 switch(mode)
2095 {
2096 case GL_CW:
2097 case GL_CCW:
2098 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002099 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002100
2101 if(context)
2102 {
2103 context->setFrontFace(mode);
2104 }
2105 }
2106 break;
2107 default:
2108 return error(GL_INVALID_ENUM);
2109 }
2110}
2111
Nicolas Capensa9b49372015-01-30 00:33:26 -05002112void APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05002113{
Nicolas Capens4be33702015-04-28 15:13:30 -07002114 TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
Nicolas Capens264f1522015-01-09 17:21:17 -05002115
2116 if(n < 0)
2117 {
2118 return error(GL_INVALID_VALUE);
2119 }
2120
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002121 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002122
2123 if(context)
2124 {
2125 for(int i = 0; i < n; i++)
2126 {
2127 buffers[i] = context->createBuffer();
2128 }
2129 }
2130}
2131
Nicolas Capensa9b49372015-01-30 00:33:26 -05002132void APIENTRY glGenerateMipmap(GLenum target)
Nicolas Capens264f1522015-01-09 17:21:17 -05002133{
2134 TRACE("(GLenum target = 0x%X)", target);
2135
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002136 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002137
2138 if(context)
2139 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002140 if(context->getListIndex() != 0)
2141 {
2142 UNIMPLEMENTED();
2143 }
2144
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002145 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05002146
2147 switch(target)
2148 {
2149 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05002150 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05002151 break;
2152 case GL_TEXTURE_CUBE_MAP:
2153 texture = context->getTextureCubeMap();
2154 break;
2155 default:
2156 return error(GL_INVALID_ENUM);
2157 }
2158
2159 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2160 {
2161 return error(GL_INVALID_OPERATION);
2162 }
2163
2164 texture->generateMipmaps();
2165 }
2166}
2167
Nicolas Capensa9b49372015-01-30 00:33:26 -05002168void APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
Nicolas Capens264f1522015-01-09 17:21:17 -05002169{
Nicolas Capens4be33702015-04-28 15:13:30 -07002170 TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);
Nicolas Capens264f1522015-01-09 17:21:17 -05002171
2172 if(n < 0)
2173 {
2174 return error(GL_INVALID_VALUE);
2175 }
2176
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002177 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002178
2179 if(context)
2180 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002181 if(context->getListIndex() != 0)
2182 {
2183 UNIMPLEMENTED();
2184 }
2185
Nicolas Capens264f1522015-01-09 17:21:17 -05002186 for(int i = 0; i < n; i++)
2187 {
2188 fences[i] = context->createFence();
2189 }
2190 }
2191}
2192
Nicolas Capensa9b49372015-01-30 00:33:26 -05002193void APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05002194{
Nicolas Capens4be33702015-04-28 15:13:30 -07002195 TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
Nicolas Capens264f1522015-01-09 17:21:17 -05002196
2197 if(n < 0)
2198 {
2199 return error(GL_INVALID_VALUE);
2200 }
2201
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002202 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002203
2204 if(context)
2205 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002206 if(context->getListIndex() != 0)
2207 {
2208 UNIMPLEMENTED();
2209 }
2210
Nicolas Capens264f1522015-01-09 17:21:17 -05002211 for(int i = 0; i < n; i++)
2212 {
2213 framebuffers[i] = context->createFramebuffer();
2214 }
2215 }
2216}
2217
Nicolas Capensa9b49372015-01-30 00:33:26 -05002218void APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
Nicolas Capens264f1522015-01-09 17:21:17 -05002219{
Nicolas Capens4be33702015-04-28 15:13:30 -07002220 TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
Nicolas Capens264f1522015-01-09 17:21:17 -05002221
2222 if(n < 0)
2223 {
2224 return error(GL_INVALID_VALUE);
2225 }
2226
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002227 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002228
2229 if(context)
2230 {
2231 for(int i = 0; i < n; i++)
2232 {
2233 ids[i] = context->createQuery();
2234 }
2235 }
2236}
2237
Nicolas Capensa9b49372015-01-30 00:33:26 -05002238void APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05002239{
Nicolas Capens4be33702015-04-28 15:13:30 -07002240 TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
Nicolas Capens264f1522015-01-09 17:21:17 -05002241
2242 if(n < 0)
2243 {
2244 return error(GL_INVALID_VALUE);
2245 }
2246
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002247 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002248
2249 if(context)
2250 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002251 if(context->getListIndex() != 0)
2252 {
2253 UNIMPLEMENTED();
2254 }
2255
Nicolas Capens264f1522015-01-09 17:21:17 -05002256 for(int i = 0; i < n; i++)
2257 {
2258 renderbuffers[i] = context->createRenderbuffer();
2259 }
2260 }
2261}
2262
Nicolas Capensa9b49372015-01-30 00:33:26 -05002263void APIENTRY glGenTextures(GLsizei n, GLuint* textures)
Nicolas Capens264f1522015-01-09 17:21:17 -05002264{
Nicolas Capens4be33702015-04-28 15:13:30 -07002265 TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
Nicolas Capens264f1522015-01-09 17:21:17 -05002266
2267 if(n < 0)
2268 {
2269 return error(GL_INVALID_VALUE);
2270 }
2271
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002272 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002273
2274 if(context)
2275 {
2276 for(int i = 0; i < n; i++)
2277 {
2278 textures[i] = context->createTexture();
2279 }
2280 }
2281}
2282
Nicolas Capensa9b49372015-01-30 00:33:26 -05002283void APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002284{
Nicolas Capens4be33702015-04-28 15:13:30 -07002285 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
2286 "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05002287 program, index, bufsize, length, size, type, name);
2288
2289 if(bufsize < 0)
2290 {
2291 return error(GL_INVALID_VALUE);
2292 }
2293
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002294 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002295
2296 if(context)
2297 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002298 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002299
2300 if(!programObject)
2301 {
2302 if(context->getShader(program))
2303 {
2304 return error(GL_INVALID_OPERATION);
2305 }
2306 else
2307 {
2308 return error(GL_INVALID_VALUE);
2309 }
2310 }
2311
2312 if(index >= (GLuint)programObject->getActiveAttributeCount())
2313 {
2314 return error(GL_INVALID_VALUE);
2315 }
2316
2317 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2318 }
2319}
2320
Nicolas Capensa9b49372015-01-30 00:33:26 -05002321void APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002322{
2323 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07002324 "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
Nicolas Capens264f1522015-01-09 17:21:17 -05002325 program, index, bufsize, length, size, type, name);
2326
2327 if(bufsize < 0)
2328 {
2329 return error(GL_INVALID_VALUE);
2330 }
2331
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002332 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002333
2334 if(context)
2335 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002336 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002337
2338 if(!programObject)
2339 {
2340 if(context->getShader(program))
2341 {
2342 return error(GL_INVALID_OPERATION);
2343 }
2344 else
2345 {
2346 return error(GL_INVALID_VALUE);
2347 }
2348 }
2349
2350 if(index >= (GLuint)programObject->getActiveUniformCount())
2351 {
2352 return error(GL_INVALID_VALUE);
2353 }
2354
2355 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2356 }
2357}
2358
Nicolas Capensa9b49372015-01-30 00:33:26 -05002359void APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
Nicolas Capens264f1522015-01-09 17:21:17 -05002360{
Nicolas Capens4be33702015-04-28 15:13:30 -07002361 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05002362 program, maxcount, count, shaders);
2363
2364 if(maxcount < 0)
2365 {
2366 return error(GL_INVALID_VALUE);
2367 }
2368
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002369 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002370
2371 if(context)
2372 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002373 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002374
2375 if(!programObject)
2376 {
2377 if(context->getShader(program))
2378 {
2379 return error(GL_INVALID_OPERATION);
2380 }
2381 else
2382 {
2383 return error(GL_INVALID_VALUE);
2384 }
2385 }
2386
2387 return programObject->getAttachedShaders(maxcount, count, shaders);
2388 }
2389}
2390
Nicolas Capensa9b49372015-01-30 00:33:26 -05002391int APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002392{
2393 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
2394
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002395 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002396
2397 if(context)
2398 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002399 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002400
2401 if(!programObject)
2402 {
2403 if(context->getShader(program))
2404 {
2405 return error(GL_INVALID_OPERATION, -1);
2406 }
2407 else
2408 {
2409 return error(GL_INVALID_VALUE, -1);
2410 }
2411 }
2412
2413 if(!programObject->isLinked())
2414 {
2415 return error(GL_INVALID_OPERATION, -1);
2416 }
2417
2418 return programObject->getAttributeLocation(name);
2419 }
2420
2421 return -1;
2422}
2423
Nicolas Capensa9b49372015-01-30 00:33:26 -05002424void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002425{
Nicolas Capens4be33702015-04-28 15:13:30 -07002426 TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)", pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002427
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002428 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002429
2430 if(context)
2431 {
2432 if(!(context->getBooleanv(pname, params)))
2433 {
2434 GLenum nativeType;
2435 unsigned int numParams = 0;
2436 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2437 return error(GL_INVALID_ENUM);
2438
2439 if(numParams == 0)
2440 return; // it is known that the pname is valid, but there are no parameters to return
2441
2442 if(nativeType == GL_FLOAT)
2443 {
2444 GLfloat *floatParams = NULL;
2445 floatParams = new GLfloat[numParams];
2446
2447 context->getFloatv(pname, floatParams);
2448
2449 for(unsigned int i = 0; i < numParams; ++i)
2450 {
2451 if(floatParams[i] == 0.0f)
2452 params[i] = GL_FALSE;
2453 else
2454 params[i] = GL_TRUE;
2455 }
2456
2457 delete [] floatParams;
2458 }
2459 else if(nativeType == GL_INT)
2460 {
2461 GLint *intParams = NULL;
2462 intParams = new GLint[numParams];
2463
2464 context->getIntegerv(pname, intParams);
2465
2466 for(unsigned int i = 0; i < numParams; ++i)
2467 {
2468 if(intParams[i] == 0)
2469 params[i] = GL_FALSE;
2470 else
2471 params[i] = GL_TRUE;
2472 }
2473
2474 delete [] intParams;
2475 }
2476 }
2477 }
2478}
2479
Nicolas Capensa9b49372015-01-30 00:33:26 -05002480void APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002481{
Nicolas Capens4be33702015-04-28 15:13:30 -07002482 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002483
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002484 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002485
2486 if(context)
2487 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002488 gl::Buffer *buffer;
Nicolas Capens264f1522015-01-09 17:21:17 -05002489
2490 switch(target)
2491 {
2492 case GL_ARRAY_BUFFER:
2493 buffer = context->getArrayBuffer();
2494 break;
2495 case GL_ELEMENT_ARRAY_BUFFER:
2496 buffer = context->getElementArrayBuffer();
2497 break;
2498 default:
2499 return error(GL_INVALID_ENUM);
2500 }
2501
2502 if(!buffer)
2503 {
2504 // A null buffer means that "0" is bound to the requested buffer target
2505 return error(GL_INVALID_OPERATION);
2506 }
2507
2508 switch(pname)
2509 {
2510 case GL_BUFFER_USAGE:
2511 *params = buffer->usage();
2512 break;
2513 case GL_BUFFER_SIZE:
2514 *params = buffer->size();
2515 break;
2516 default:
2517 return error(GL_INVALID_ENUM);
2518 }
2519 }
2520}
2521
Nicolas Capensa9b49372015-01-30 00:33:26 -05002522GLenum APIENTRY glGetError(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05002523{
2524 TRACE("()");
2525
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002526 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002527
2528 if(context)
2529 {
2530 return context->getError();
2531 }
2532
2533 return GL_NO_ERROR;
2534}
2535
Nicolas Capensa9b49372015-01-30 00:33:26 -05002536void APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002537{
Nicolas Capens4be33702015-04-28 15:13:30 -07002538 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002539
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002540 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002541
2542 if(context)
2543 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002544 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05002545
2546 if(fenceObject == NULL)
2547 {
2548 return error(GL_INVALID_OPERATION);
2549 }
2550
2551 fenceObject->getFenceiv(pname, params);
2552 }
2553}
2554
Nicolas Capensa9b49372015-01-30 00:33:26 -05002555void APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002556{
Nicolas Capens4be33702015-04-28 15:13:30 -07002557 TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002558
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002559 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002560
2561 if(context)
2562 {
2563 if(!(context->getFloatv(pname, params)))
2564 {
2565 GLenum nativeType;
2566 unsigned int numParams = 0;
2567 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2568 return error(GL_INVALID_ENUM);
2569
2570 if(numParams == 0)
2571 return; // it is known that the pname is valid, but that there are no parameters to return.
2572
2573 if(nativeType == GL_BOOL)
2574 {
2575 GLboolean *boolParams = NULL;
2576 boolParams = new GLboolean[numParams];
2577
2578 context->getBooleanv(pname, boolParams);
2579
2580 for(unsigned int i = 0; i < numParams; ++i)
2581 {
2582 if(boolParams[i] == GL_FALSE)
2583 params[i] = 0.0f;
2584 else
2585 params[i] = 1.0f;
2586 }
2587
2588 delete [] boolParams;
2589 }
2590 else if(nativeType == GL_INT)
2591 {
2592 GLint *intParams = NULL;
2593 intParams = new GLint[numParams];
2594
2595 context->getIntegerv(pname, intParams);
2596
2597 for(unsigned int i = 0; i < numParams; ++i)
2598 {
2599 params[i] = (GLfloat)intParams[i];
2600 }
2601
2602 delete [] intParams;
2603 }
2604 }
2605 }
2606}
2607
Nicolas Capensa9b49372015-01-30 00:33:26 -05002608void APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002609{
Nicolas Capens4be33702015-04-28 15:13:30 -07002610 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05002611 target, attachment, pname, params);
2612
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002613 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002614
2615 if(context)
2616 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002617 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05002618 {
2619 return error(GL_INVALID_ENUM);
2620 }
2621
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002622 gl::Framebuffer *framebuffer = NULL;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002623 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05002624 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002625 if(context->getReadFramebufferName() == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05002626 {
2627 return error(GL_INVALID_OPERATION);
2628 }
2629
2630 framebuffer = context->getReadFramebuffer();
2631 }
2632 else
2633 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002634 if(context->getDrawFramebufferName() == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05002635 {
2636 return error(GL_INVALID_OPERATION);
2637 }
2638
2639 framebuffer = context->getDrawFramebuffer();
2640 }
2641
2642 GLenum attachmentType;
2643 GLuint attachmentHandle;
2644 switch(attachment)
2645 {
2646 case GL_COLOR_ATTACHMENT0:
2647 attachmentType = framebuffer->getColorbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002648 attachmentHandle = framebuffer->getColorbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002649 break;
2650 case GL_DEPTH_ATTACHMENT:
2651 attachmentType = framebuffer->getDepthbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002652 attachmentHandle = framebuffer->getDepthbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002653 break;
2654 case GL_STENCIL_ATTACHMENT:
2655 attachmentType = framebuffer->getStencilbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002656 attachmentHandle = framebuffer->getStencilbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002657 break;
2658 default:
2659 return error(GL_INVALID_ENUM);
2660 }
2661
2662 GLenum attachmentObjectType; // Type category
2663 if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
2664 {
2665 attachmentObjectType = attachmentType;
2666 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002667 else if(gl::IsTextureTarget(attachmentType))
Nicolas Capens264f1522015-01-09 17:21:17 -05002668 {
2669 attachmentObjectType = GL_TEXTURE;
2670 }
2671 else UNREACHABLE();
2672
2673 switch(pname)
2674 {
2675 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2676 *params = attachmentObjectType;
2677 break;
2678 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2679 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2680 {
2681 *params = attachmentHandle;
2682 }
2683 else
2684 {
2685 return error(GL_INVALID_ENUM);
2686 }
2687 break;
2688 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2689 if(attachmentObjectType == GL_TEXTURE)
2690 {
2691 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2692 }
2693 else
2694 {
2695 return error(GL_INVALID_ENUM);
2696 }
2697 break;
2698 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2699 if(attachmentObjectType == GL_TEXTURE)
2700 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002701 if(gl::IsCubemapTextureTarget(attachmentType))
Nicolas Capens264f1522015-01-09 17:21:17 -05002702 {
2703 *params = attachmentType;
2704 }
2705 else
2706 {
2707 *params = 0;
2708 }
2709 }
2710 else
2711 {
2712 return error(GL_INVALID_ENUM);
2713 }
2714 break;
2715 default:
2716 return error(GL_INVALID_ENUM);
2717 }
2718 }
2719}
2720
Nicolas Capensa9b49372015-01-30 00:33:26 -05002721GLenum APIENTRY glGetGraphicsResetStatusEXT(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05002722{
2723 TRACE("()");
2724
2725 return GL_NO_ERROR;
2726}
2727
Nicolas Capensa9b49372015-01-30 00:33:26 -05002728void APIENTRY glGetIntegerv(GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002729{
Nicolas Capens4be33702015-04-28 15:13:30 -07002730 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002731
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002732 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002733
2734 if(context)
2735 {
2736 if(!(context->getIntegerv(pname, params)))
2737 {
2738 GLenum nativeType;
2739 unsigned int numParams = 0;
2740 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2741 return error(GL_INVALID_ENUM);
2742
2743 if(numParams == 0)
2744 return; // it is known that pname is valid, but there are no parameters to return
2745
2746 if(nativeType == GL_BOOL)
2747 {
2748 GLboolean *boolParams = NULL;
2749 boolParams = new GLboolean[numParams];
2750
2751 context->getBooleanv(pname, boolParams);
2752
2753 for(unsigned int i = 0; i < numParams; ++i)
2754 {
2755 if(boolParams[i] == GL_FALSE)
2756 params[i] = 0;
2757 else
2758 params[i] = 1;
2759 }
2760
2761 delete [] boolParams;
2762 }
2763 else if(nativeType == GL_FLOAT)
2764 {
2765 GLfloat *floatParams = NULL;
2766 floatParams = new GLfloat[numParams];
2767
2768 context->getFloatv(pname, floatParams);
2769
2770 for(unsigned int i = 0; i < numParams; ++i)
2771 {
2772 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
2773 {
2774 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
2775 }
2776 else
2777 {
2778 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
2779 }
2780 }
2781
2782 delete [] floatParams;
2783 }
2784 }
2785 }
2786}
2787
Nicolas Capensa9b49372015-01-30 00:33:26 -05002788void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002789{
Nicolas Capens4be33702015-04-28 15:13:30 -07002790 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002791
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002792 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002793
2794 if(context)
2795 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002796 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002797
2798 if(!programObject)
2799 {
2800 return error(GL_INVALID_VALUE);
2801 }
2802
2803 switch(pname)
2804 {
2805 case GL_DELETE_STATUS:
2806 *params = programObject->isFlaggedForDeletion();
2807 return;
2808 case GL_LINK_STATUS:
2809 *params = programObject->isLinked();
2810 return;
2811 case GL_VALIDATE_STATUS:
2812 *params = programObject->isValidated();
2813 return;
2814 case GL_INFO_LOG_LENGTH:
2815 *params = programObject->getInfoLogLength();
2816 return;
2817 case GL_ATTACHED_SHADERS:
2818 *params = programObject->getAttachedShadersCount();
2819 return;
2820 case GL_ACTIVE_ATTRIBUTES:
2821 *params = programObject->getActiveAttributeCount();
2822 return;
2823 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2824 *params = programObject->getActiveAttributeMaxLength();
2825 return;
2826 case GL_ACTIVE_UNIFORMS:
2827 *params = programObject->getActiveUniformCount();
2828 return;
2829 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2830 *params = programObject->getActiveUniformMaxLength();
2831 return;
2832 default:
2833 return error(GL_INVALID_ENUM);
2834 }
2835 }
2836}
2837
Nicolas Capensa9b49372015-01-30 00:33:26 -05002838void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
Nicolas Capens264f1522015-01-09 17:21:17 -05002839{
Nicolas Capens4be33702015-04-28 15:13:30 -07002840 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05002841 program, bufsize, length, infolog);
2842
2843 if(bufsize < 0)
2844 {
2845 return error(GL_INVALID_VALUE);
2846 }
2847
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002848 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002849
2850 if(context)
2851 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002852 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002853
2854 if(!programObject)
2855 {
2856 return error(GL_INVALID_VALUE);
2857 }
2858
2859 programObject->getInfoLog(bufsize, length, infolog);
2860 }
2861}
2862
Nicolas Capensa9b49372015-01-30 00:33:26 -05002863void APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002864{
Nicolas Capens4be33702015-04-28 15:13:30 -07002865 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002866
2867 switch(pname)
2868 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002869 case GL_CURRENT_QUERY:
Nicolas Capens264f1522015-01-09 17:21:17 -05002870 break;
2871 default:
2872 return error(GL_INVALID_ENUM);
2873 }
2874
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002875 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002876
2877 if(context)
2878 {
2879 params[0] = context->getActiveQuery(target);
2880 }
2881}
2882
Nicolas Capensa9b49372015-01-30 00:33:26 -05002883void APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002884{
Nicolas Capens4be33702015-04-28 15:13:30 -07002885 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002886
2887 switch(pname)
2888 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002889 case GL_QUERY_RESULT:
2890 case GL_QUERY_RESULT_AVAILABLE:
Nicolas Capens264f1522015-01-09 17:21:17 -05002891 break;
2892 default:
2893 return error(GL_INVALID_ENUM);
2894 }
2895
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002896 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002897
2898 if(context)
2899 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002900 gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
Nicolas Capens264f1522015-01-09 17:21:17 -05002901
2902 if(!queryObject)
2903 {
2904 return error(GL_INVALID_OPERATION);
2905 }
2906
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002907 if(context->getActiveQuery(queryObject->getType()) == name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002908 {
2909 return error(GL_INVALID_OPERATION);
2910 }
2911
2912 switch(pname)
2913 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002914 case GL_QUERY_RESULT:
Nicolas Capens264f1522015-01-09 17:21:17 -05002915 params[0] = queryObject->getResult();
2916 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002917 case GL_QUERY_RESULT_AVAILABLE:
Nicolas Capens264f1522015-01-09 17:21:17 -05002918 params[0] = queryObject->isResultAvailable();
2919 break;
2920 default:
2921 ASSERT(false);
2922 }
2923 }
2924}
2925
Nicolas Capensa9b49372015-01-30 00:33:26 -05002926void APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002927{
Nicolas Capens4be33702015-04-28 15:13:30 -07002928 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002929
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002930 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002931
2932 if(context)
2933 {
2934 if(target != GL_RENDERBUFFER)
2935 {
2936 return error(GL_INVALID_ENUM);
2937 }
2938
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002939 if(context->getRenderbufferName() == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05002940 {
2941 return error(GL_INVALID_OPERATION);
2942 }
2943
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002944 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
Nicolas Capens264f1522015-01-09 17:21:17 -05002945
2946 switch(pname)
2947 {
2948 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
2949 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
2950 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
2951 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
2952 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
2953 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
2954 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
2955 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
2956 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002957 case GL_RENDERBUFFER_SAMPLES_EXT: *params = renderbuffer->getSamples(); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05002958 default:
2959 return error(GL_INVALID_ENUM);
2960 }
2961 }
2962}
2963
Nicolas Capensa9b49372015-01-30 00:33:26 -05002964void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002965{
Nicolas Capens4be33702015-04-28 15:13:30 -07002966 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002967
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002968 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002969
2970 if(context)
2971 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002972 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05002973
2974 if(!shaderObject)
2975 {
2976 return error(GL_INVALID_VALUE);
2977 }
2978
2979 switch(pname)
2980 {
2981 case GL_SHADER_TYPE:
2982 *params = shaderObject->getType();
2983 return;
2984 case GL_DELETE_STATUS:
2985 *params = shaderObject->isFlaggedForDeletion();
2986 return;
2987 case GL_COMPILE_STATUS:
2988 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2989 return;
2990 case GL_INFO_LOG_LENGTH:
2991 *params = shaderObject->getInfoLogLength();
2992 return;
2993 case GL_SHADER_SOURCE_LENGTH:
2994 *params = shaderObject->getSourceLength();
2995 return;
2996 default:
2997 return error(GL_INVALID_ENUM);
2998 }
2999 }
3000}
3001
Nicolas Capensa9b49372015-01-30 00:33:26 -05003002void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
Nicolas Capens264f1522015-01-09 17:21:17 -05003003{
Nicolas Capens4be33702015-04-28 15:13:30 -07003004 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003005 shader, bufsize, length, infolog);
3006
3007 if(bufsize < 0)
3008 {
3009 return error(GL_INVALID_VALUE);
3010 }
3011
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003012 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003013
3014 if(context)
3015 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003016 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003017
3018 if(!shaderObject)
3019 {
3020 return error(GL_INVALID_VALUE);
3021 }
3022
3023 shaderObject->getInfoLog(bufsize, length, infolog);
3024 }
3025}
3026
Nicolas Capensa9b49372015-01-30 00:33:26 -05003027void APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
Nicolas Capens264f1522015-01-09 17:21:17 -05003028{
Nicolas Capens4be33702015-04-28 15:13:30 -07003029 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003030 shadertype, precisiontype, range, precision);
3031
3032 switch(shadertype)
3033 {
3034 case GL_VERTEX_SHADER:
3035 case GL_FRAGMENT_SHADER:
3036 break;
3037 default:
3038 return error(GL_INVALID_ENUM);
3039 }
3040
3041 switch(precisiontype)
3042 {
3043 case GL_LOW_FLOAT:
3044 case GL_MEDIUM_FLOAT:
3045 case GL_HIGH_FLOAT:
3046 // IEEE 754 single-precision
3047 range[0] = 127;
3048 range[1] = 127;
3049 *precision = 23;
3050 break;
3051 case GL_LOW_INT:
3052 case GL_MEDIUM_INT:
3053 case GL_HIGH_INT:
3054 // Single-precision floating-point numbers can accurately represent integers up to +/-16777216
3055 range[0] = 24;
3056 range[1] = 24;
3057 *precision = 0;
3058 break;
3059 default:
3060 return error(GL_INVALID_ENUM);
3061 }
3062}
3063
Nicolas Capensa9b49372015-01-30 00:33:26 -05003064void APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
Nicolas Capens264f1522015-01-09 17:21:17 -05003065{
Nicolas Capens4be33702015-04-28 15:13:30 -07003066 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003067 shader, bufsize, length, source);
3068
3069 if(bufsize < 0)
3070 {
3071 return error(GL_INVALID_VALUE);
3072 }
3073
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003074 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003075
3076 if(context)
3077 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003078 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003079
3080 if(!shaderObject)
3081 {
3082 return error(GL_INVALID_OPERATION);
3083 }
3084
3085 shaderObject->getSource(bufsize, length, source);
3086 }
3087}
3088
Nicolas Capensa9b49372015-01-30 00:33:26 -05003089const GLubyte* APIENTRY glGetString(GLenum name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003090{
3091 TRACE("(GLenum name = 0x%X)", name);
3092
Nicolas Capens264f1522015-01-09 17:21:17 -05003093 switch(name)
3094 {
3095 case GL_VENDOR:
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003096 return (GLubyte*)"TransGaming Inc.";
Nicolas Capens264f1522015-01-09 17:21:17 -05003097 case GL_RENDERER:
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003098 return (GLubyte*)"SwiftShader";
Nicolas Capens264f1522015-01-09 17:21:17 -05003099 case GL_VERSION:
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003100 return (GLubyte*)"2.1 SwiftShader "VERSION_STRING;
Nicolas Capens264f1522015-01-09 17:21:17 -05003101 case GL_SHADING_LANGUAGE_VERSION:
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003102 return (GLubyte*)"3.30 SwiftShader "VERSION_STRING;
Nicolas Capens264f1522015-01-09 17:21:17 -05003103 case GL_EXTENSIONS:
3104 // Keep list sorted in following order:
3105 // OES extensions
3106 // EXT extensions
3107 // Vendor extensions
3108 return (GLubyte*)
Maxime Grégoiredf041002015-07-15 15:19:38 -04003109 //"GL_ARB_compressed_texture_pixel_storage "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003110 "GL_ARB_framebuffer_object "
Maxime Grégoiredf041002015-07-15 15:19:38 -04003111 //"GL_ARB_half_float_pixel "
Maxime Grégoiredf041002015-07-15 15:19:38 -04003112 //"GL_ARB_pixel_buffer_object "
Nicolas Capens264f1522015-01-09 17:21:17 -05003113 "GL_EXT_blend_minmax "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003114 "GL_EXT_depth_texture "
3115 "GL_EXT_depth_texture_cube_map "
3116 "GL_EXT_element_index_uint "
3117 "GL_EXT_packed_depth_stencil "
3118 "GL_EXT_rgb8_rgba8 "
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003119 //"GL_EXT_pixel_buffer_object "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003120 "GL_EXT_standard_derivatives "
3121 "GL_EXT_texture_float "
3122 "GL_EXT_texture_float_linear "
3123 "GL_EXT_texture_half_float "
3124 "GL_EXT_texture_half_float_linear "
3125 "GL_EXT_texture_npot "
Nicolas Capens264f1522015-01-09 17:21:17 -05003126 "GL_EXT_occlusion_query_boolean "
3127 "GL_EXT_read_format_bgra "
3128 #if (S3TC_SUPPORT)
3129 "GL_EXT_texture_compression_dxt1 "
3130 #endif
Nicolas Capensa9b49372015-01-30 00:33:26 -05003131 "GL_EXT_blend_func_separate "
3132 "GL_EXT_secondary_color "
Nicolas Capens264f1522015-01-09 17:21:17 -05003133 "GL_EXT_texture_filter_anisotropic "
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003134 //"GL_NV_pixel_data_range "
3135 //"WGL_ARB_pixel_format "
3136 //"WGL_ARB_pixel_format_float "
3137 //"WGL_ATI_pixel_format_float "
3138 //"WGL_EXT_pixel_format_packed_float "
Nicolas Capens264f1522015-01-09 17:21:17 -05003139 "GL_EXT_texture_format_BGRA8888 "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003140 "GL_EXT_framebuffer_blit "
3141 "GL_EXT_framebuffer_multisample "
Nicolas Capens264f1522015-01-09 17:21:17 -05003142 #if (S3TC_SUPPORT)
Nicolas Capensa9b49372015-01-30 00:33:26 -05003143 "GL_EXT_texture_compression_dxt3 "
3144 "GL_EXT_texture_compression_dxt5 "
Nicolas Capens264f1522015-01-09 17:21:17 -05003145 #endif
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003146 "GL_NV_fence";
Nicolas Capens264f1522015-01-09 17:21:17 -05003147 default:
3148 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3149 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05003150
3151 return NULL;
Nicolas Capens264f1522015-01-09 17:21:17 -05003152}
3153
Nicolas Capensa9b49372015-01-30 00:33:26 -05003154void APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003155{
Nicolas Capens4be33702015-04-28 15:13:30 -07003156 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003157
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003158 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003159
3160 if(context)
3161 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003162 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05003163
3164 switch(target)
3165 {
3166 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003167 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05003168 break;
3169 case GL_TEXTURE_CUBE_MAP:
3170 texture = context->getTextureCubeMap();
3171 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003172 default:
3173 return error(GL_INVALID_ENUM);
3174 }
3175
3176 switch(pname)
3177 {
3178 case GL_TEXTURE_MAG_FILTER:
3179 *params = (GLfloat)texture->getMagFilter();
3180 break;
3181 case GL_TEXTURE_MIN_FILTER:
3182 *params = (GLfloat)texture->getMinFilter();
3183 break;
3184 case GL_TEXTURE_WRAP_S:
3185 *params = (GLfloat)texture->getWrapS();
3186 break;
3187 case GL_TEXTURE_WRAP_T:
3188 *params = (GLfloat)texture->getWrapT();
3189 break;
3190 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3191 *params = texture->getMaxAnisotropy();
3192 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003193 default:
3194 return error(GL_INVALID_ENUM);
3195 }
3196 }
3197}
3198
Nicolas Capensa9b49372015-01-30 00:33:26 -05003199void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003200{
Nicolas Capens4be33702015-04-28 15:13:30 -07003201 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003202
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003203 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003204
3205 if(context)
3206 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003207 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05003208
3209 switch(target)
3210 {
3211 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003212 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05003213 break;
3214 case GL_TEXTURE_CUBE_MAP:
3215 texture = context->getTextureCubeMap();
3216 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003217 default:
3218 return error(GL_INVALID_ENUM);
3219 }
3220
3221 switch(pname)
3222 {
3223 case GL_TEXTURE_MAG_FILTER:
3224 *params = texture->getMagFilter();
3225 break;
3226 case GL_TEXTURE_MIN_FILTER:
3227 *params = texture->getMinFilter();
3228 break;
3229 case GL_TEXTURE_WRAP_S:
3230 *params = texture->getWrapS();
3231 break;
3232 case GL_TEXTURE_WRAP_T:
3233 *params = texture->getWrapT();
3234 break;
3235 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3236 *params = (GLint)texture->getMaxAnisotropy();
3237 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003238 default:
3239 return error(GL_INVALID_ENUM);
3240 }
3241 }
3242}
3243
Nicolas Capensa9b49372015-01-30 00:33:26 -05003244void APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003245{
Nicolas Capens4be33702015-04-28 15:13:30 -07003246 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003247 program, location, bufSize, params);
3248
3249 if(bufSize < 0)
3250 {
3251 return error(GL_INVALID_VALUE);
3252 }
3253
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003254 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003255
3256 if(context)
3257 {
3258 if(program == 0)
3259 {
3260 return error(GL_INVALID_VALUE);
3261 }
3262
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003263 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003264
3265 if(!programObject || !programObject->isLinked())
3266 {
3267 return error(GL_INVALID_OPERATION);
3268 }
3269
3270 if(!programObject->getUniformfv(location, &bufSize, params))
3271 {
3272 return error(GL_INVALID_OPERATION);
3273 }
3274 }
3275}
3276
Nicolas Capensa9b49372015-01-30 00:33:26 -05003277void APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003278{
Nicolas Capens4be33702015-04-28 15:13:30 -07003279 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003280
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003281 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003282
3283 if(context)
3284 {
3285 if(program == 0)
3286 {
3287 return error(GL_INVALID_VALUE);
3288 }
3289
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003290 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003291
3292 if(!programObject || !programObject->isLinked())
3293 {
3294 return error(GL_INVALID_OPERATION);
3295 }
3296
3297 if(!programObject->getUniformfv(location, NULL, params))
3298 {
3299 return error(GL_INVALID_OPERATION);
3300 }
3301 }
3302}
3303
Nicolas Capensa9b49372015-01-30 00:33:26 -05003304void APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003305{
Nicolas Capens4be33702015-04-28 15:13:30 -07003306 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003307 program, location, bufSize, params);
3308
3309 if(bufSize < 0)
3310 {
3311 return error(GL_INVALID_VALUE);
3312 }
3313
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003314 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003315
3316 if(context)
3317 {
3318 if(program == 0)
3319 {
3320 return error(GL_INVALID_VALUE);
3321 }
3322
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003323 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003324
3325 if(!programObject || !programObject->isLinked())
3326 {
3327 return error(GL_INVALID_OPERATION);
3328 }
3329
3330 if(!programObject)
3331 {
3332 return error(GL_INVALID_OPERATION);
3333 }
3334
3335 if(!programObject->getUniformiv(location, &bufSize, params))
3336 {
3337 return error(GL_INVALID_OPERATION);
3338 }
3339 }
3340}
3341
Nicolas Capensa9b49372015-01-30 00:33:26 -05003342void APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003343{
Nicolas Capens4be33702015-04-28 15:13:30 -07003344 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003345
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003346 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003347
3348 if(context)
3349 {
3350 if(program == 0)
3351 {
3352 return error(GL_INVALID_VALUE);
3353 }
3354
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003355 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003356
3357 if(!programObject || !programObject->isLinked())
3358 {
3359 return error(GL_INVALID_OPERATION);
3360 }
3361
3362 if(!programObject)
3363 {
3364 return error(GL_INVALID_OPERATION);
3365 }
3366
3367 if(!programObject->getUniformiv(location, NULL, params))
3368 {
3369 return error(GL_INVALID_OPERATION);
3370 }
3371 }
3372}
3373
Nicolas Capensa9b49372015-01-30 00:33:26 -05003374int APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003375{
3376 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
3377
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003378 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003379
3380 if(strstr(name, "gl_") == name)
3381 {
3382 return -1;
3383 }
3384
3385 if(context)
3386 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003387 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003388
3389 if(!programObject)
3390 {
3391 if(context->getShader(program))
3392 {
3393 return error(GL_INVALID_OPERATION, -1);
3394 }
3395 else
3396 {
3397 return error(GL_INVALID_VALUE, -1);
3398 }
3399 }
3400
3401 if(!programObject->isLinked())
3402 {
3403 return error(GL_INVALID_OPERATION, -1);
3404 }
3405
3406 return programObject->getUniformLocation(name);
3407 }
3408
3409 return -1;
3410}
3411
Nicolas Capensa9b49372015-01-30 00:33:26 -05003412void APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003413{
Nicolas Capens4be33702015-04-28 15:13:30 -07003414 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003415
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003416 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003417
3418 if(context)
3419 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003420 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003421 {
3422 return error(GL_INVALID_VALUE);
3423 }
3424
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003425 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
Nicolas Capens264f1522015-01-09 17:21:17 -05003426
3427 switch(pname)
3428 {
3429 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3430 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3431 break;
3432 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3433 *params = (GLfloat)attribState.mSize;
3434 break;
3435 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3436 *params = (GLfloat)attribState.mStride;
3437 break;
3438 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3439 *params = (GLfloat)attribState.mType;
3440 break;
3441 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3442 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
3443 break;
3444 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003445 *params = (GLfloat)attribState.mBoundBuffer.name();
Nicolas Capens264f1522015-01-09 17:21:17 -05003446 break;
3447 case GL_CURRENT_VERTEX_ATTRIB:
3448 for(int i = 0; i < 4; ++i)
3449 {
3450 params[i] = attribState.mCurrentValue[i];
3451 }
3452 break;
3453 default: return error(GL_INVALID_ENUM);
3454 }
3455 }
3456}
3457
Nicolas Capensa9b49372015-01-30 00:33:26 -05003458void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003459{
Nicolas Capens4be33702015-04-28 15:13:30 -07003460 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003461
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003462 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003463
3464 if(context)
3465 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003466 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003467 {
3468 return error(GL_INVALID_VALUE);
3469 }
3470
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003471 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
Nicolas Capens264f1522015-01-09 17:21:17 -05003472
3473 switch(pname)
3474 {
3475 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3476 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3477 break;
3478 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3479 *params = attribState.mSize;
3480 break;
3481 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3482 *params = attribState.mStride;
3483 break;
3484 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3485 *params = attribState.mType;
3486 break;
3487 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3488 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
3489 break;
3490 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003491 *params = attribState.mBoundBuffer.name();
Nicolas Capens264f1522015-01-09 17:21:17 -05003492 break;
3493 case GL_CURRENT_VERTEX_ATTRIB:
3494 for(int i = 0; i < 4; ++i)
3495 {
3496 float currentValue = attribState.mCurrentValue[i];
3497 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3498 }
3499 break;
3500 default: return error(GL_INVALID_ENUM);
3501 }
3502 }
3503}
3504
Nicolas Capensa9b49372015-01-30 00:33:26 -05003505void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003506{
Nicolas Capens4be33702015-04-28 15:13:30 -07003507 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003508
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003509 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003510
3511 if(context)
3512 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003513 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003514 {
3515 return error(GL_INVALID_VALUE);
3516 }
3517
3518 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3519 {
3520 return error(GL_INVALID_ENUM);
3521 }
3522
3523 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
3524 }
3525}
3526
Nicolas Capensa9b49372015-01-30 00:33:26 -05003527void APIENTRY glHint(GLenum target, GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05003528{
3529 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
3530
3531 switch(mode)
3532 {
3533 case GL_FASTEST:
3534 case GL_NICEST:
3535 case GL_DONT_CARE:
3536 break;
3537 default:
3538 return error(GL_INVALID_ENUM);
3539 }
3540
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003541 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003542 switch(target)
3543 {
3544 case GL_GENERATE_MIPMAP_HINT:
3545 if(context) context->setGenerateMipmapHint(mode);
3546 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05003547 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
Nicolas Capens264f1522015-01-09 17:21:17 -05003548 if(context) context->setFragmentShaderDerivativeHint(mode);
3549 break;
3550 default:
3551 return error(GL_INVALID_ENUM);
3552 }
3553}
3554
Nicolas Capensa9b49372015-01-30 00:33:26 -05003555GLboolean APIENTRY glIsBuffer(GLuint buffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003556{
3557 TRACE("(GLuint buffer = %d)", buffer);
3558
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003559 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003560
3561 if(context && buffer)
3562 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003563 gl::Buffer *bufferObject = context->getBuffer(buffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003564
3565 if(bufferObject)
3566 {
3567 return GL_TRUE;
3568 }
3569 }
3570
3571 return GL_FALSE;
3572}
3573
Nicolas Capensa9b49372015-01-30 00:33:26 -05003574GLboolean APIENTRY glIsEnabled(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05003575{
3576 TRACE("(GLenum cap = 0x%X)", cap);
3577
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003578 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003579
3580 if(context)
3581 {
3582 switch(cap)
3583 {
3584 case GL_CULL_FACE: return context->isCullFaceEnabled();
3585 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3586 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3587 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3588 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3589 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3590 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3591 case GL_BLEND: return context->isBlendEnabled();
3592 case GL_DITHER: return context->isDitherEnabled();
3593 default:
3594 return error(GL_INVALID_ENUM, false);
3595 }
3596 }
3597
3598 return false;
3599}
3600
Nicolas Capensa9b49372015-01-30 00:33:26 -05003601GLboolean APIENTRY glIsFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05003602{
3603 TRACE("(GLuint fence = %d)", fence);
3604
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003605 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003606
3607 if(context)
3608 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003609 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05003610
3611 if(fenceObject == NULL)
3612 {
3613 return GL_FALSE;
3614 }
3615
3616 return fenceObject->isFence();
3617 }
3618
3619 return GL_FALSE;
3620}
3621
Nicolas Capensa9b49372015-01-30 00:33:26 -05003622GLboolean APIENTRY glIsFramebuffer(GLuint framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003623{
3624 TRACE("(GLuint framebuffer = %d)", framebuffer);
3625
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003626 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003627
3628 if(context && framebuffer)
3629 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003630 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003631
3632 if(framebufferObject)
3633 {
3634 return GL_TRUE;
3635 }
3636 }
3637
3638 return GL_FALSE;
3639}
3640
Nicolas Capensa9b49372015-01-30 00:33:26 -05003641GLboolean APIENTRY glIsProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05003642{
3643 TRACE("(GLuint program = %d)", program);
3644
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003645 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003646
3647 if(context && program)
3648 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003649 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003650
3651 if(programObject)
3652 {
3653 return GL_TRUE;
3654 }
3655 }
3656
3657 return GL_FALSE;
3658}
3659
Nicolas Capensa9b49372015-01-30 00:33:26 -05003660GLboolean APIENTRY glIsQueryEXT(GLuint name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003661{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003662 TRACE("(GLuint name = %d)", name);
Nicolas Capens264f1522015-01-09 17:21:17 -05003663
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003664 if(name == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05003665 {
3666 return GL_FALSE;
3667 }
3668
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003669 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003670
3671 if(context)
3672 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003673 gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
Nicolas Capens264f1522015-01-09 17:21:17 -05003674
3675 if(queryObject)
3676 {
3677 return GL_TRUE;
3678 }
3679 }
3680
3681 return GL_FALSE;
3682}
3683
Nicolas Capensa9b49372015-01-30 00:33:26 -05003684GLboolean APIENTRY glIsRenderbuffer(GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003685{
3686 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
3687
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003688 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003689
3690 if(context && renderbuffer)
3691 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003692 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003693
3694 if(renderbufferObject)
3695 {
3696 return GL_TRUE;
3697 }
3698 }
3699
3700 return GL_FALSE;
3701}
3702
Nicolas Capensa9b49372015-01-30 00:33:26 -05003703GLboolean APIENTRY glIsShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05003704{
3705 TRACE("(GLuint shader = %d)", shader);
3706
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003707 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003708
3709 if(context && shader)
3710 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003711 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003712
3713 if(shaderObject)
3714 {
3715 return GL_TRUE;
3716 }
3717 }
3718
3719 return GL_FALSE;
3720}
3721
Nicolas Capensa9b49372015-01-30 00:33:26 -05003722GLboolean APIENTRY glIsTexture(GLuint texture)
Nicolas Capens264f1522015-01-09 17:21:17 -05003723{
3724 TRACE("(GLuint texture = %d)", texture);
3725
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003726 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003727
3728 if(context && texture)
3729 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003730 gl::Texture *textureObject = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -05003731
3732 if(textureObject)
3733 {
3734 return GL_TRUE;
3735 }
3736 }
3737
3738 return GL_FALSE;
3739}
3740
Nicolas Capensa9b49372015-01-30 00:33:26 -05003741void APIENTRY glLineWidth(GLfloat width)
Nicolas Capens264f1522015-01-09 17:21:17 -05003742{
3743 TRACE("(GLfloat width = %f)", width);
3744
3745 if(width <= 0.0f)
3746 {
3747 return error(GL_INVALID_VALUE);
3748 }
3749
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003750 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003751
3752 if(context)
3753 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003754 if(context->getListIndex() != 0)
3755 {
3756 UNIMPLEMENTED();
3757 }
3758
Nicolas Capens264f1522015-01-09 17:21:17 -05003759 context->setLineWidth(width);
3760 }
3761}
3762
Nicolas Capensa9b49372015-01-30 00:33:26 -05003763void APIENTRY glLinkProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05003764{
3765 TRACE("(GLuint program = %d)", program);
3766
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003767 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003768
3769 if(context)
3770 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003771 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003772
3773 if(!programObject)
3774 {
3775 if(context->getShader(program))
3776 {
3777 return error(GL_INVALID_OPERATION);
3778 }
3779 else
3780 {
3781 return error(GL_INVALID_VALUE);
3782 }
3783 }
3784
3785 programObject->link();
3786 }
3787}
3788
Nicolas Capensa9b49372015-01-30 00:33:26 -05003789void APIENTRY glPixelStorei(GLenum pname, GLint param)
Nicolas Capens264f1522015-01-09 17:21:17 -05003790{
3791 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
3792
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003793 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003794
3795 if(context)
3796 {
3797 switch(pname)
3798 {
3799 case GL_UNPACK_ALIGNMENT:
3800 if(param != 1 && param != 2 && param != 4 && param != 8)
3801 {
3802 return error(GL_INVALID_VALUE);
3803 }
3804 context->setUnpackAlignment(param);
3805 break;
3806 case GL_PACK_ALIGNMENT:
3807 if(param != 1 && param != 2 && param != 4 && param != 8)
3808 {
3809 return error(GL_INVALID_VALUE);
3810 }
3811 context->setPackAlignment(param);
3812 break;
3813 default:
3814 return error(GL_INVALID_ENUM);
3815 }
3816 }
3817}
3818
Nicolas Capensa9b49372015-01-30 00:33:26 -05003819void APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
Nicolas Capens264f1522015-01-09 17:21:17 -05003820{
3821 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
3822
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003823 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003824
3825 if(context)
3826 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003827 if(context->getListIndex() != 0)
3828 {
3829 UNIMPLEMENTED();
3830 }
3831
Nicolas Capens264f1522015-01-09 17:21:17 -05003832 context->setPolygonOffsetParams(factor, units);
3833 }
3834}
3835
Nicolas Capensa9b49372015-01-30 00:33:26 -05003836void APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -05003837 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
3838{
3839 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07003840 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003841 x, y, width, height, format, type, bufSize, data);
3842
3843 if(width < 0 || height < 0 || bufSize < 0)
3844 {
3845 return error(GL_INVALID_VALUE);
3846 }
3847
3848 if(!validReadFormatType(format, type))
3849 {
3850 return error(GL_INVALID_OPERATION);
3851 }
3852
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003853 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003854
3855 if(context)
3856 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003857 if(context->getListIndex() != 0)
3858 {
3859 UNIMPLEMENTED();
3860 }
3861
Nicolas Capens264f1522015-01-09 17:21:17 -05003862 context->readPixels(x, y, width, height, format, type, &bufSize, data);
3863 }
3864}
3865
Nicolas Capensa9b49372015-01-30 00:33:26 -05003866void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
Nicolas Capens264f1522015-01-09 17:21:17 -05003867{
3868 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07003869 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003870 x, y, width, height, format, type, pixels);
3871
3872 if(width < 0 || height < 0)
3873 {
3874 return error(GL_INVALID_VALUE);
3875 }
3876
3877 if(!validReadFormatType(format, type))
3878 {
3879 return error(GL_INVALID_OPERATION);
3880 }
3881
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003882 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003883
3884 if(context)
3885 {
3886 context->readPixels(x, y, width, height, format, type, NULL, pixels);
3887 }
3888}
3889
Nicolas Capensa9b49372015-01-30 00:33:26 -05003890void APIENTRY glReleaseShaderCompiler(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05003891{
3892 TRACE("()");
3893
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003894 gl::Shader::releaseCompiler();
Nicolas Capens264f1522015-01-09 17:21:17 -05003895}
3896
Nicolas Capensa9b49372015-01-30 00:33:26 -05003897void APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05003898{
3899 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3900 target, samples, internalformat, width, height);
3901
3902 switch(target)
3903 {
3904 case GL_RENDERBUFFER:
3905 break;
3906 default:
3907 return error(GL_INVALID_ENUM);
3908 }
3909
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003910 if(!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
Nicolas Capens264f1522015-01-09 17:21:17 -05003911 {
3912 return error(GL_INVALID_ENUM);
3913 }
3914
3915 if(width < 0 || height < 0 || samples < 0)
3916 {
3917 return error(GL_INVALID_VALUE);
3918 }
3919
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003920 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003921
3922 if(context)
3923 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003924 if(context->getListIndex() != 0)
3925 {
3926 UNIMPLEMENTED();
3927 }
3928
3929 if(width > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003930 height > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
3931 samples > gl::IMPLEMENTATION_MAX_SAMPLES)
Nicolas Capens264f1522015-01-09 17:21:17 -05003932 {
3933 return error(GL_INVALID_VALUE);
3934 }
3935
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003936 GLuint handle = context->getRenderbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05003937 if(handle == 0)
3938 {
3939 return error(GL_INVALID_OPERATION);
3940 }
3941
3942 switch(internalformat)
3943 {
3944 case GL_DEPTH_COMPONENT16:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003945 case GL_DEPTH_COMPONENT24:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003946 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003947 break;
3948 case GL_RGBA4:
3949 case GL_RGB5_A1:
3950 case GL_RGB565:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003951 case GL_RGB8_EXT:
3952 case GL_RGBA8_EXT:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003953 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003954 break;
3955 case GL_STENCIL_INDEX8:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003956 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003957 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05003958 case GL_DEPTH24_STENCIL8_EXT:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003959 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003960 break;
3961 default:
3962 return error(GL_INVALID_ENUM);
3963 }
3964 }
3965}
3966
Nicolas Capensa9b49372015-01-30 00:33:26 -05003967void APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05003968{
3969 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
3970}
3971
Nicolas Capensa9b49372015-01-30 00:33:26 -05003972void APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
Nicolas Capens264f1522015-01-09 17:21:17 -05003973{
3974 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
3975
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003976 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003977
3978 if(context)
3979 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003980 if(context->getListIndex() != 0)
3981 {
3982 UNIMPLEMENTED();
3983 }
3984
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003985 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
Nicolas Capens264f1522015-01-09 17:21:17 -05003986 }
3987}
3988
Nicolas Capensa9b49372015-01-30 00:33:26 -05003989void APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
Nicolas Capens264f1522015-01-09 17:21:17 -05003990{
3991 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
3992
3993 if(condition != GL_ALL_COMPLETED_NV)
3994 {
3995 return error(GL_INVALID_ENUM);
3996 }
3997
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003998 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003999
4000 if(context)
4001 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004002 if(context->getListIndex() != 0)
4003 {
4004 UNIMPLEMENTED();
4005 }
4006
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004007 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05004008
4009 if(fenceObject == NULL)
4010 {
4011 return error(GL_INVALID_OPERATION);
4012 }
4013
4014 fenceObject->setFence(condition);
4015 }
4016}
4017
Nicolas Capensa9b49372015-01-30 00:33:26 -05004018void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05004019{
4020 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4021
4022 if(width < 0 || height < 0)
4023 {
4024 return error(GL_INVALID_VALUE);
4025 }
4026
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004027 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004028
4029 if(context)
4030 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004031 if(context->getListIndex() != 0)
4032 {
4033 UNIMPLEMENTED();
4034 }
4035
Nicolas Capens264f1522015-01-09 17:21:17 -05004036 context->setScissorParams(x, y, width, height);
4037 }
4038}
4039
Nicolas Capensa9b49372015-01-30 00:33:26 -05004040void APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
Nicolas Capens264f1522015-01-09 17:21:17 -05004041{
Nicolas Capens4be33702015-04-28 15:13:30 -07004042 TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
4043 "const GLvoid* binary = %p, GLsizei length = %d)",
Nicolas Capens264f1522015-01-09 17:21:17 -05004044 n, shaders, binaryformat, binary, length);
4045
4046 // No binary shader formats are supported.
4047 return error(GL_INVALID_ENUM);
4048}
4049
Nicolas Capensa9b49372015-01-30 00:33:26 -05004050void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
Nicolas Capens264f1522015-01-09 17:21:17 -05004051{
Nicolas Capens4be33702015-04-28 15:13:30 -07004052 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05004053 shader, count, string, length);
4054
4055 if(count < 0)
4056 {
4057 return error(GL_INVALID_VALUE);
4058 }
4059
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004060 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004061
4062 if(context)
4063 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004064 if(context->getListIndex() != 0)
4065 {
4066 UNIMPLEMENTED();
4067 }
4068
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004069 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05004070
4071 if(!shaderObject)
4072 {
4073 if(context->getProgram(shader))
4074 {
4075 return error(GL_INVALID_OPERATION);
4076 }
4077 else
4078 {
4079 return error(GL_INVALID_VALUE);
4080 }
4081 }
4082
4083 shaderObject->setSource(count, string, length);
4084 }
4085}
4086
Nicolas Capensa9b49372015-01-30 00:33:26 -05004087void APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004088{
4089 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4090}
4091
Nicolas Capensa9b49372015-01-30 00:33:26 -05004092void APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004093{
4094 TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
4095
4096 switch(face)
4097 {
4098 case GL_FRONT:
4099 case GL_BACK:
4100 case GL_FRONT_AND_BACK:
4101 break;
4102 default:
4103 return error(GL_INVALID_ENUM);
4104 }
4105
4106 switch(func)
4107 {
4108 case GL_NEVER:
4109 case GL_ALWAYS:
4110 case GL_LESS:
4111 case GL_LEQUAL:
4112 case GL_EQUAL:
4113 case GL_GEQUAL:
4114 case GL_GREATER:
4115 case GL_NOTEQUAL:
4116 break;
4117 default:
4118 return error(GL_INVALID_ENUM);
4119 }
4120
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004121 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004122
4123 if(context)
4124 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004125 if(context->getListIndex() != 0)
4126 {
4127 UNIMPLEMENTED();
4128 }
4129
Nicolas Capens264f1522015-01-09 17:21:17 -05004130 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4131 {
4132 context->setStencilParams(func, ref, mask);
4133 }
4134
4135 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4136 {
4137 context->setStencilBackParams(func, ref, mask);
4138 }
4139 }
4140}
4141
Nicolas Capensa9b49372015-01-30 00:33:26 -05004142void APIENTRY glStencilMask(GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004143{
4144 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4145}
4146
Nicolas Capensa9b49372015-01-30 00:33:26 -05004147void APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004148{
4149 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
4150
4151 switch(face)
4152 {
4153 case GL_FRONT:
4154 case GL_BACK:
4155 case GL_FRONT_AND_BACK:
4156 break;
4157 default:
4158 return error(GL_INVALID_ENUM);
4159 }
4160
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004161 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004162
4163 if(context)
4164 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004165 if(context->getListIndex() != 0)
4166 {
4167 UNIMPLEMENTED();
4168 }
4169
Nicolas Capens264f1522015-01-09 17:21:17 -05004170 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4171 {
4172 context->setStencilWritemask(mask);
4173 }
4174
4175 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4176 {
4177 context->setStencilBackWritemask(mask);
4178 }
4179 }
4180}
4181
Nicolas Capensa9b49372015-01-30 00:33:26 -05004182void APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
Nicolas Capens264f1522015-01-09 17:21:17 -05004183{
4184 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4185}
4186
Nicolas Capensa9b49372015-01-30 00:33:26 -05004187void APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
Nicolas Capens264f1522015-01-09 17:21:17 -05004188{
4189 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4190 face, fail, zfail, zpass);
4191
4192 switch(face)
4193 {
4194 case GL_FRONT:
4195 case GL_BACK:
4196 case GL_FRONT_AND_BACK:
4197 break;
4198 default:
4199 return error(GL_INVALID_ENUM);
4200 }
4201
4202 switch(fail)
4203 {
4204 case GL_ZERO:
4205 case GL_KEEP:
4206 case GL_REPLACE:
4207 case GL_INCR:
4208 case GL_DECR:
4209 case GL_INVERT:
4210 case GL_INCR_WRAP:
4211 case GL_DECR_WRAP:
4212 break;
4213 default:
4214 return error(GL_INVALID_ENUM);
4215 }
4216
4217 switch(zfail)
4218 {
4219 case GL_ZERO:
4220 case GL_KEEP:
4221 case GL_REPLACE:
4222 case GL_INCR:
4223 case GL_DECR:
4224 case GL_INVERT:
4225 case GL_INCR_WRAP:
4226 case GL_DECR_WRAP:
4227 break;
4228 default:
4229 return error(GL_INVALID_ENUM);
4230 }
4231
4232 switch(zpass)
4233 {
4234 case GL_ZERO:
4235 case GL_KEEP:
4236 case GL_REPLACE:
4237 case GL_INCR:
4238 case GL_DECR:
4239 case GL_INVERT:
4240 case GL_INCR_WRAP:
4241 case GL_DECR_WRAP:
4242 break;
4243 default:
4244 return error(GL_INVALID_ENUM);
4245 }
4246
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004247 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004248
4249 if(context)
4250 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004251 if(context->getListIndex() != 0)
4252 {
4253 UNIMPLEMENTED();
4254 }
4255
Nicolas Capens264f1522015-01-09 17:21:17 -05004256 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4257 {
4258 context->setStencilOperations(fail, zfail, zpass);
4259 }
4260
4261 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4262 {
4263 context->setStencilBackOperations(fail, zfail, zpass);
4264 }
4265 }
4266}
4267
Nicolas Capensa9b49372015-01-30 00:33:26 -05004268GLboolean APIENTRY glTestFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05004269{
4270 TRACE("(GLuint fence = %d)", fence);
4271
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004272 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004273
4274 if(context)
4275 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004276 if(context->getListIndex() != 0)
4277 {
4278 UNIMPLEMENTED();
4279 }
4280
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004281 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05004282
4283 if(fenceObject == NULL)
4284 {
4285 return error(GL_INVALID_OPERATION, GL_TRUE);
4286 }
4287
4288 return fenceObject->testFence();
4289 }
4290
4291 return GL_TRUE;
4292}
4293
Nicolas Capensa9b49372015-01-30 00:33:26 -05004294void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -05004295 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4296{
4297 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004298 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05004299 target, level, internalformat, width, height, border, format, type, pixels);
4300
4301 if(!validImageSize(level, width, height))
4302 {
4303 return error(GL_INVALID_VALUE);
4304 }
4305
4306 if(internalformat != format)
4307 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004308 //TRACE("UNIMPLEMENTED!!");
4309 //return error(GL_INVALID_OPERATION);
Nicolas Capens264f1522015-01-09 17:21:17 -05004310 }
4311
4312 switch(format)
4313 {
4314 case GL_ALPHA:
4315 case GL_LUMINANCE:
4316 case GL_LUMINANCE_ALPHA:
4317 switch(type)
4318 {
4319 case GL_UNSIGNED_BYTE:
4320 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004321 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004322 break;
4323 default:
4324 return error(GL_INVALID_ENUM);
4325 }
4326 break;
4327 case GL_RGB:
4328 switch(type)
4329 {
4330 case GL_UNSIGNED_BYTE:
4331 case GL_UNSIGNED_SHORT_5_6_5:
4332 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004333 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004334 break;
4335 default:
4336 return error(GL_INVALID_ENUM);
4337 }
4338 break;
4339 case GL_RGBA:
4340 switch(type)
4341 {
4342 case GL_UNSIGNED_BYTE:
4343 case GL_UNSIGNED_SHORT_4_4_4_4:
4344 case GL_UNSIGNED_SHORT_5_5_5_1:
4345 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004346 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004347 break;
4348 default:
4349 return error(GL_INVALID_ENUM);
4350 }
4351 break;
4352 case GL_BGRA_EXT:
4353 switch(type)
4354 {
4355 case GL_UNSIGNED_BYTE:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004356 case GL_UNSIGNED_SHORT_5_6_5:
4357 case GL_UNSIGNED_INT_8_8_8_8_REV:
Nicolas Capens264f1522015-01-09 17:21:17 -05004358 break;
4359 default:
4360 return error(GL_INVALID_ENUM);
4361 }
4362 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004363 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
Nicolas Capens264f1522015-01-09 17:21:17 -05004364 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004365 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
4366 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
4367 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004368 case GL_DEPTH_COMPONENT:
4369 switch(type)
4370 {
4371 case GL_UNSIGNED_SHORT:
4372 case GL_UNSIGNED_INT:
4373 break;
4374 default:
4375 return error(GL_INVALID_ENUM);
4376 }
4377 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004378 case GL_DEPTH_STENCIL_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004379 switch(type)
4380 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004381 case GL_UNSIGNED_INT_24_8_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004382 break;
4383 default:
4384 return error(GL_INVALID_ENUM);
4385 }
4386 break;
4387 default:
4388 return error(GL_INVALID_VALUE);
4389 }
4390
4391 if(border != 0)
4392 {
4393 return error(GL_INVALID_VALUE);
4394 }
4395
Nicolas Capensa9b49372015-01-30 00:33:26 -05004396 switch(target)
4397 {
4398 case GL_TEXTURE_2D:
4399 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4400 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4401 {
4402 return error(GL_INVALID_VALUE);
4403 }
4404 break;
4405 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4406 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4407 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4408 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4409 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4410 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4411 if(width != height)
4412 {
4413 return error(GL_INVALID_VALUE);
4414 }
4415
4416 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
4417 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
4418 {
4419 return error(GL_INVALID_VALUE);
4420 }
4421 break;
4422 case GL_PROXY_TEXTURE_2D:
4423 pixels = 0;
4424
4425 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4426 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4427 {
4428 //UNIMPLEMENTED();
4429 width = 0;
4430 height = 0;
4431 internalformat = GL_NONE;
4432 format = GL_NONE;
4433 type = GL_NONE;
4434
4435 //return;// error(GL_INVALID_VALUE);
4436 }
4437 break;
4438 default:
4439 return error(GL_INVALID_ENUM);
4440 }
4441
4442 if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4443 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
4444 format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
4445 format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
4446 {
4447 if(S3TC_SUPPORT)
4448 {
4449 return error(GL_INVALID_OPERATION);
4450 }
4451 else
4452 {
4453 return error(GL_INVALID_ENUM);
4454 }
4455 }
4456
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004457 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004458
4459 if(context)
4460 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004461 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05004462 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004463 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05004464 }
4465
Maxime Grégoiredff6d002015-07-16 10:26:45 -04004466 if(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D)
Nicolas Capens264f1522015-01-09 17:21:17 -05004467 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004468 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004469
4470 if(!texture)
4471 {
4472 return error(GL_INVALID_OPERATION);
4473 }
4474
4475 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
4476 }
4477 else
4478 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004479 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05004480
4481 if(!texture)
4482 {
4483 return error(GL_INVALID_OPERATION);
4484 }
4485
4486 texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
4487 }
4488 }
4489}
4490
Nicolas Capensa9b49372015-01-30 00:33:26 -05004491void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
Nicolas Capens264f1522015-01-09 17:21:17 -05004492{
4493 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
4494
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004495 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004496
4497 if(context)
4498 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004499 if(context->getListIndex() != 0)
4500 {
4501 UNIMPLEMENTED();
4502 }
4503
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004504 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05004505
4506 switch(target)
4507 {
4508 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004509 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004510 break;
4511 case GL_TEXTURE_CUBE_MAP:
4512 texture = context->getTextureCubeMap();
4513 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004514 default:
4515 return error(GL_INVALID_ENUM);
4516 }
4517
4518 switch(pname)
4519 {
4520 case GL_TEXTURE_WRAP_S:
4521 if(!texture->setWrapS((GLenum)param))
4522 {
4523 return error(GL_INVALID_ENUM);
4524 }
4525 break;
4526 case GL_TEXTURE_WRAP_T:
4527 if(!texture->setWrapT((GLenum)param))
4528 {
4529 return error(GL_INVALID_ENUM);
4530 }
4531 break;
4532 case GL_TEXTURE_MIN_FILTER:
4533 if(!texture->setMinFilter((GLenum)param))
4534 {
4535 return error(GL_INVALID_ENUM);
4536 }
4537 break;
4538 case GL_TEXTURE_MAG_FILTER:
4539 if(!texture->setMagFilter((GLenum)param))
4540 {
4541 return error(GL_INVALID_ENUM);
4542 }
4543 break;
4544 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4545 if(!texture->setMaxAnisotropy(param))
4546 {
4547 return error(GL_INVALID_VALUE);
4548 }
4549 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004550 case GL_TEXTURE_MIN_LOD:
4551 //TRACE("() UNIMPLEMENTED!!"); // FIXME
4552 //UNIMPLEMENTED();
4553 break;
4554 case GL_TEXTURE_MAX_LOD:
4555 //TRACE("() UNIMPLEMENTED!!"); // FIXME
4556 //UNIMPLEMENTED();
4557 break;
4558 case GL_TEXTURE_LOD_BIAS:
4559 if(param != 0.0f)
4560 {
4561 UNIMPLEMENTED();
4562 }
4563 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004564 default:
4565 return error(GL_INVALID_ENUM);
4566 }
4567 }
4568}
4569
Nicolas Capensa9b49372015-01-30 00:33:26 -05004570void APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05004571{
4572 glTexParameterf(target, pname, *params);
4573}
4574
Nicolas Capensa9b49372015-01-30 00:33:26 -05004575void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
Nicolas Capens264f1522015-01-09 17:21:17 -05004576{
4577 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
4578
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004579 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004580
4581 if(context)
4582 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004583 if(context->getListIndex() != 0)
4584 {
4585 UNIMPLEMENTED();
4586 }
4587
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004588 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05004589
4590 switch(target)
4591 {
4592 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004593 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004594 break;
4595 case GL_TEXTURE_CUBE_MAP:
4596 texture = context->getTextureCubeMap();
4597 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004598 default:
4599 return error(GL_INVALID_ENUM);
4600 }
4601
4602 switch(pname)
4603 {
4604 case GL_TEXTURE_WRAP_S:
4605 if(!texture->setWrapS((GLenum)param))
4606 {
4607 return error(GL_INVALID_ENUM);
4608 }
4609 break;
4610 case GL_TEXTURE_WRAP_T:
4611 if(!texture->setWrapT((GLenum)param))
4612 {
4613 return error(GL_INVALID_ENUM);
4614 }
4615 break;
4616 case GL_TEXTURE_MIN_FILTER:
4617 if(!texture->setMinFilter((GLenum)param))
4618 {
4619 return error(GL_INVALID_ENUM);
4620 }
4621 break;
4622 case GL_TEXTURE_MAG_FILTER:
4623 if(!texture->setMagFilter((GLenum)param))
4624 {
4625 return error(GL_INVALID_ENUM);
4626 }
4627 break;
4628 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4629 if(!texture->setMaxAnisotropy((GLfloat)param))
4630 {
4631 return error(GL_INVALID_VALUE);
4632 }
4633 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004634 case GL_TEXTURE_MAX_LEVEL:
4635 if(!texture->setMaxLevel(param))
4636 {
4637 return error(GL_INVALID_ENUM);
4638 }
4639 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004640 default:
4641 return error(GL_INVALID_ENUM);
4642 }
4643 }
4644}
4645
Nicolas Capensa9b49372015-01-30 00:33:26 -05004646void APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05004647{
4648 glTexParameteri(target, pname, *params);
4649}
4650
Nicolas Capensa9b49372015-01-30 00:33:26 -05004651void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4652 GLenum format, GLenum type, const GLvoid* pixels)
Nicolas Capens264f1522015-01-09 17:21:17 -05004653{
4654 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4655 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004656 "const GLvoid* pixels = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05004657 target, level, xoffset, yoffset, width, height, format, type, pixels);
4658
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004659 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05004660 {
4661 return error(GL_INVALID_ENUM);
4662 }
4663
4664 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
4665 {
4666 return error(GL_INVALID_VALUE);
4667 }
4668
4669 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4670 {
4671 return error(GL_INVALID_VALUE);
4672 }
4673
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004674 if(!gl::CheckTextureFormatType(format, type))
Nicolas Capens264f1522015-01-09 17:21:17 -05004675 {
4676 return error(GL_INVALID_ENUM);
4677 }
4678
4679 if(width == 0 || height == 0 || pixels == NULL)
4680 {
4681 return;
4682 }
4683
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004684 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004685
4686 if(context)
4687 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004688 if(context->getListIndex() != 0)
4689 {
4690 UNIMPLEMENTED();
4691 }
4692
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004693 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -05004694 {
4695 return error(GL_INVALID_VALUE);
4696 }
4697
Maxime Grégoiredff6d002015-07-16 10:26:45 -04004698 if(target == GL_TEXTURE_2D)
Nicolas Capens264f1522015-01-09 17:21:17 -05004699 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004700 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004701
4702 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
4703 {
4704 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4705 }
4706 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004707 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05004708 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004709 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05004710
4711 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
4712 {
4713 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4714 }
4715 }
4716 else
4717 {
4718 UNREACHABLE();
4719 }
4720 }
4721}
4722
Nicolas Capensa9b49372015-01-30 00:33:26 -05004723void APIENTRY glUniform1f(GLint location, GLfloat x)
Nicolas Capens264f1522015-01-09 17:21:17 -05004724{
4725 glUniform1fv(location, 1, &x);
4726}
4727
Nicolas Capensa9b49372015-01-30 00:33:26 -05004728void APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004729{
Nicolas Capens4be33702015-04-28 15:13:30 -07004730 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004731
4732 if(count < 0)
4733 {
4734 return error(GL_INVALID_VALUE);
4735 }
4736
4737 if(location == -1)
4738 {
4739 return;
4740 }
4741
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004742 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004743
4744 if(context)
4745 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004746 if(context->getListIndex() != 0)
4747 {
4748 UNIMPLEMENTED();
4749 }
4750
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004751 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004752
4753 if(!program)
4754 {
4755 return error(GL_INVALID_OPERATION);
4756 }
4757
4758 if(!program->setUniform1fv(location, count, v))
4759 {
4760 return error(GL_INVALID_OPERATION);
4761 }
4762 }
4763}
4764
Nicolas Capensa9b49372015-01-30 00:33:26 -05004765void APIENTRY glUniform1i(GLint location, GLint x)
Nicolas Capens264f1522015-01-09 17:21:17 -05004766{
4767 glUniform1iv(location, 1, &x);
4768}
4769
Nicolas Capensa9b49372015-01-30 00:33:26 -05004770void APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004771{
Nicolas Capens4be33702015-04-28 15:13:30 -07004772 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004773
4774 if(count < 0)
4775 {
4776 return error(GL_INVALID_VALUE);
4777 }
4778
4779 if(location == -1)
4780 {
4781 return;
4782 }
4783
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004784 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004785
4786 if(context)
4787 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004788 if(context->getListIndex() != 0)
4789 {
4790 UNIMPLEMENTED();
4791 }
4792
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004793 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004794
4795 if(!program)
4796 {
4797 return error(GL_INVALID_OPERATION);
4798 }
4799
4800 if(!program->setUniform1iv(location, count, v))
4801 {
4802 return error(GL_INVALID_OPERATION);
4803 }
4804 }
4805}
4806
Nicolas Capensa9b49372015-01-30 00:33:26 -05004807void APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
Nicolas Capens264f1522015-01-09 17:21:17 -05004808{
4809 GLfloat xy[2] = {x, y};
4810
4811 glUniform2fv(location, 1, (GLfloat*)&xy);
4812}
4813
Nicolas Capensa9b49372015-01-30 00:33:26 -05004814void APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004815{
Nicolas Capens4be33702015-04-28 15:13:30 -07004816 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004817
4818 if(count < 0)
4819 {
4820 return error(GL_INVALID_VALUE);
4821 }
4822
4823 if(location == -1)
4824 {
4825 return;
4826 }
4827
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004828 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004829
4830 if(context)
4831 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004832 if(context->getListIndex() != 0)
4833 {
4834 UNIMPLEMENTED();
4835 }
4836
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004837 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004838
4839 if(!program)
4840 {
4841 return error(GL_INVALID_OPERATION);
4842 }
4843
4844 if(!program->setUniform2fv(location, count, v))
4845 {
4846 return error(GL_INVALID_OPERATION);
4847 }
4848 }
4849}
4850
Nicolas Capensa9b49372015-01-30 00:33:26 -05004851void APIENTRY glUniform2i(GLint location, GLint x, GLint y)
Nicolas Capens264f1522015-01-09 17:21:17 -05004852{
4853 GLint xy[4] = {x, y};
4854
4855 glUniform2iv(location, 1, (GLint*)&xy);
4856}
4857
Nicolas Capensa9b49372015-01-30 00:33:26 -05004858void APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004859{
Nicolas Capens4be33702015-04-28 15:13:30 -07004860 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004861
4862 if(count < 0)
4863 {
4864 return error(GL_INVALID_VALUE);
4865 }
4866
4867 if(location == -1)
4868 {
4869 return;
4870 }
4871
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004872 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004873
4874 if(context)
4875 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004876 if(context->getListIndex() != 0)
4877 {
4878 UNIMPLEMENTED();
4879 }
4880
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004881 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004882
4883 if(!program)
4884 {
4885 return error(GL_INVALID_OPERATION);
4886 }
4887
4888 if(!program->setUniform2iv(location, count, v))
4889 {
4890 return error(GL_INVALID_OPERATION);
4891 }
4892 }
4893}
4894
Nicolas Capensa9b49372015-01-30 00:33:26 -05004895void APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
Nicolas Capens264f1522015-01-09 17:21:17 -05004896{
4897 GLfloat xyz[3] = {x, y, z};
4898
4899 glUniform3fv(location, 1, (GLfloat*)&xyz);
4900}
4901
Nicolas Capensa9b49372015-01-30 00:33:26 -05004902void APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004903{
Nicolas Capens4be33702015-04-28 15:13:30 -07004904 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004905
4906 if(count < 0)
4907 {
4908 return error(GL_INVALID_VALUE);
4909 }
4910
4911 if(location == -1)
4912 {
4913 return;
4914 }
4915
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004916 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004917
4918 if(context)
4919 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004920 if(context->getListIndex() != 0)
4921 {
4922 UNIMPLEMENTED();
4923 }
4924
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004925 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004926
4927 if(!program)
4928 {
4929 return error(GL_INVALID_OPERATION);
4930 }
4931
4932 if(!program->setUniform3fv(location, count, v))
4933 {
4934 return error(GL_INVALID_OPERATION);
4935 }
4936 }
4937}
4938
Nicolas Capensa9b49372015-01-30 00:33:26 -05004939void APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
Nicolas Capens264f1522015-01-09 17:21:17 -05004940{
4941 GLint xyz[3] = {x, y, z};
4942
4943 glUniform3iv(location, 1, (GLint*)&xyz);
4944}
4945
Nicolas Capensa9b49372015-01-30 00:33:26 -05004946void APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004947{
Nicolas Capens4be33702015-04-28 15:13:30 -07004948 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004949
4950 if(count < 0)
4951 {
4952 return error(GL_INVALID_VALUE);
4953 }
4954
4955 if(location == -1)
4956 {
4957 return;
4958 }
4959
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004960 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004961
4962 if(context)
4963 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004964 if(context->getListIndex() != 0)
4965 {
4966 UNIMPLEMENTED();
4967 }
4968
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004969 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004970
4971 if(!program)
4972 {
4973 return error(GL_INVALID_OPERATION);
4974 }
4975
4976 if(!program->setUniform3iv(location, count, v))
4977 {
4978 return error(GL_INVALID_OPERATION);
4979 }
4980 }
4981}
4982
Nicolas Capensa9b49372015-01-30 00:33:26 -05004983void APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Nicolas Capens264f1522015-01-09 17:21:17 -05004984{
4985 GLfloat xyzw[4] = {x, y, z, w};
4986
4987 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4988}
4989
Nicolas Capensa9b49372015-01-30 00:33:26 -05004990void APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004991{
Nicolas Capens4be33702015-04-28 15:13:30 -07004992 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004993
4994 if(count < 0)
4995 {
4996 return error(GL_INVALID_VALUE);
4997 }
4998
4999 if(location == -1)
5000 {
5001 return;
5002 }
5003
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005004 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005005
5006 if(context)
5007 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005008 if(context->getListIndex() != 0)
5009 {
5010 UNIMPLEMENTED();
5011 }
5012
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005013 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005014
5015 if(!program)
5016 {
5017 return error(GL_INVALID_OPERATION);
5018 }
5019
5020 if(!program->setUniform4fv(location, count, v))
5021 {
5022 return error(GL_INVALID_OPERATION);
5023 }
5024 }
5025}
5026
Nicolas Capensa9b49372015-01-30 00:33:26 -05005027void APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
Nicolas Capens264f1522015-01-09 17:21:17 -05005028{
5029 GLint xyzw[4] = {x, y, z, w};
5030
5031 glUniform4iv(location, 1, (GLint*)&xyzw);
5032}
5033
Nicolas Capensa9b49372015-01-30 00:33:26 -05005034void APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05005035{
Nicolas Capens4be33702015-04-28 15:13:30 -07005036 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05005037
5038 if(count < 0)
5039 {
5040 return error(GL_INVALID_VALUE);
5041 }
5042
5043 if(location == -1)
5044 {
5045 return;
5046 }
5047
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005048 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005049
5050 if(context)
5051 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005052 if(context->getListIndex() != 0)
5053 {
5054 UNIMPLEMENTED();
5055 }
5056
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005057 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005058
5059 if(!program)
5060 {
5061 return error(GL_INVALID_OPERATION);
5062 }
5063
5064 if(!program->setUniform4iv(location, count, v))
5065 {
5066 return error(GL_INVALID_OPERATION);
5067 }
5068 }
5069}
5070
Nicolas Capensa9b49372015-01-30 00:33:26 -05005071void APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005072{
Nicolas Capens4be33702015-04-28 15:13:30 -07005073 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005074 location, count, transpose, value);
5075
5076 if(count < 0 || transpose != GL_FALSE)
5077 {
5078 return error(GL_INVALID_VALUE);
5079 }
5080
5081 if(location == -1)
5082 {
5083 return;
5084 }
5085
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005086 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005087
5088 if(context)
5089 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005090 if(context->getListIndex() != 0)
5091 {
5092 UNIMPLEMENTED();
5093 }
5094
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005095 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005096
5097 if(!program)
5098 {
5099 return error(GL_INVALID_OPERATION);
5100 }
5101
5102 if(!program->setUniformMatrix2fv(location, count, value))
5103 {
5104 return error(GL_INVALID_OPERATION);
5105 }
5106 }
5107}
5108
Nicolas Capensa9b49372015-01-30 00:33:26 -05005109void APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005110{
Nicolas Capens4be33702015-04-28 15:13:30 -07005111 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005112 location, count, transpose, value);
5113
5114 if(count < 0 || transpose != GL_FALSE)
5115 {
5116 return error(GL_INVALID_VALUE);
5117 }
5118
5119 if(location == -1)
5120 {
5121 return;
5122 }
5123
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005124 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005125
5126 if(context)
5127 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005128 if(context->getListIndex() != 0)
5129 {
5130 UNIMPLEMENTED();
5131 }
5132
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005133 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005134
5135 if(!program)
5136 {
5137 return error(GL_INVALID_OPERATION);
5138 }
5139
5140 if(!program->setUniformMatrix3fv(location, count, value))
5141 {
5142 return error(GL_INVALID_OPERATION);
5143 }
5144 }
5145}
5146
Nicolas Capensa9b49372015-01-30 00:33:26 -05005147void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005148{
Nicolas Capens4be33702015-04-28 15:13:30 -07005149 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005150 location, count, transpose, value);
5151
5152 if(count < 0 || transpose != GL_FALSE)
5153 {
5154 return error(GL_INVALID_VALUE);
5155 }
5156
5157 if(location == -1)
5158 {
5159 return;
5160 }
5161
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005162 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005163
5164 if(context)
5165 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005166 if(context->getListIndex() != 0)
5167 {
5168 UNIMPLEMENTED();
5169 }
5170
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005171 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005172
5173 if(!program)
5174 {
5175 return error(GL_INVALID_OPERATION);
5176 }
5177
5178 if(!program->setUniformMatrix4fv(location, count, value))
5179 {
5180 return error(GL_INVALID_OPERATION);
5181 }
5182 }
5183}
5184
Nicolas Capensa9b49372015-01-30 00:33:26 -05005185void APIENTRY glUseProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05005186{
5187 TRACE("(GLuint program = %d)", program);
5188
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005189 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005190
5191 if(context)
5192 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005193 if(context->getListIndex() != 0)
5194 {
5195 UNIMPLEMENTED();
5196 }
5197
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005198 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05005199
5200 if(!programObject && program != 0)
5201 {
5202 if(context->getShader(program))
5203 {
5204 return error(GL_INVALID_OPERATION);
5205 }
5206 else
5207 {
5208 return error(GL_INVALID_VALUE);
5209 }
5210 }
5211
5212 if(program != 0 && !programObject->isLinked())
5213 {
5214 return error(GL_INVALID_OPERATION);
5215 }
5216
5217 context->useProgram(program);
5218 }
5219}
5220
Nicolas Capensa9b49372015-01-30 00:33:26 -05005221void APIENTRY glValidateProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05005222{
5223 TRACE("(GLuint program = %d)", program);
5224
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005225 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005226
5227 if(context)
5228 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005229 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05005230
5231 if(!programObject)
5232 {
5233 if(context->getShader(program))
5234 {
5235 return error(GL_INVALID_OPERATION);
5236 }
5237 else
5238 {
5239 return error(GL_INVALID_VALUE);
5240 }
5241 }
5242
5243 programObject->validate();
5244 }
5245}
5246
Nicolas Capensa9b49372015-01-30 00:33:26 -05005247void APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
Nicolas Capens264f1522015-01-09 17:21:17 -05005248{
5249 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
5250
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005251 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005252 {
5253 return error(GL_INVALID_VALUE);
5254 }
5255
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005256 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005257
5258 if(context)
5259 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005260 if(context->getListIndex() != 0)
5261 {
5262 UNIMPLEMENTED();
5263 }
5264
5265 //GLfloat vals[4] = { x, 0, 0, 1 };
5266 context->setVertexAttrib(index, x, 0, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005267 }
5268}
5269
Nicolas Capensa9b49372015-01-30 00:33:26 -05005270void APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005271{
Nicolas Capens4be33702015-04-28 15:13:30 -07005272 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
Nicolas Capens264f1522015-01-09 17:21:17 -05005273
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005274 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005275 {
5276 return error(GL_INVALID_VALUE);
5277 }
5278
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005279 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005280
5281 if(context)
5282 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005283 if(context->getListIndex() != 0)
5284 {
5285 UNIMPLEMENTED();
5286 }
5287
5288 //GLfloat vals[4] = { values[0], 0, 0, 1 };
5289 context->setVertexAttrib(index, values[0], 0, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005290 }
5291}
5292
Nicolas Capensa9b49372015-01-30 00:33:26 -05005293void APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
Nicolas Capens264f1522015-01-09 17:21:17 -05005294{
5295 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
5296
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005297 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005298 {
5299 return error(GL_INVALID_VALUE);
5300 }
5301
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005302 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005303
5304 if(context)
5305 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005306 if(context->getListIndex() != 0)
5307 {
5308 UNIMPLEMENTED();
5309 }
5310
5311 //GLfloat vals[4] = { x, y, 0, 1 };
5312 context->setVertexAttrib(index, x, y, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005313 }
5314}
5315
Nicolas Capensa9b49372015-01-30 00:33:26 -05005316void APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005317{
Nicolas Capens4be33702015-04-28 15:13:30 -07005318 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
Nicolas Capens264f1522015-01-09 17:21:17 -05005319
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005320 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005321 {
5322 return error(GL_INVALID_VALUE);
5323 }
5324
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005325 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005326
5327 if(context)
5328 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005329 if(context->getListIndex() != 0)
5330 {
5331 UNIMPLEMENTED();
5332 }
5333
5334 //GLfloat vals[4] = { };
5335 context->setVertexAttrib(index, values[0], values[1], 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005336 }
5337}
5338
Nicolas Capensa9b49372015-01-30 00:33:26 -05005339void APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
Nicolas Capens264f1522015-01-09 17:21:17 -05005340{
5341 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
5342
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005343 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005344 {
5345 return error(GL_INVALID_VALUE);
5346 }
5347
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005348 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005349
5350 if(context)
5351 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005352 if(context->getListIndex() != 0)
5353 {
5354 UNIMPLEMENTED();
5355 }
5356
5357 //GLfloat vals[4] = { x, y, z, 1 };
5358 context->setVertexAttrib(index, x, y, z, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005359 }
5360}
5361
Nicolas Capensa9b49372015-01-30 00:33:26 -05005362void APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005363{
Nicolas Capens4be33702015-04-28 15:13:30 -07005364 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
Nicolas Capens264f1522015-01-09 17:21:17 -05005365
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005366 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005367 {
5368 return error(GL_INVALID_VALUE);
5369 }
5370
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005371 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005372
5373 if(context)
5374 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005375 if(context->getListIndex() != 0)
5376 {
5377 UNIMPLEMENTED();
5378 }
5379
5380 //GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5381 context->setVertexAttrib(index, values[0], values[1], values[2], 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005382 }
5383}
5384
Nicolas Capensa9b49372015-01-30 00:33:26 -05005385void APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Nicolas Capens264f1522015-01-09 17:21:17 -05005386{
5387 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
5388
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005389 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005390 {
5391 return error(GL_INVALID_VALUE);
5392 }
5393
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005394 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005395
5396 if(context)
5397 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005398 if(context->getListIndex() != 0)
5399 {
5400 UNIMPLEMENTED();
5401 }
5402
5403 //GLfloat vals[4] = { x, y, z, w };
5404 context->setVertexAttrib(index, x, y, z, w);
Nicolas Capens264f1522015-01-09 17:21:17 -05005405 }
5406}
5407
Nicolas Capensa9b49372015-01-30 00:33:26 -05005408void APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005409{
Nicolas Capens4be33702015-04-28 15:13:30 -07005410 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
Nicolas Capens264f1522015-01-09 17:21:17 -05005411
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005412 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005413 {
5414 return error(GL_INVALID_VALUE);
5415 }
5416
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005417 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005418
5419 if(context)
5420 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005421 if(context->getListIndex() != 0)
5422 {
5423 UNIMPLEMENTED();
5424 }
5425
5426 context->setVertexAttrib(index, values[0], values[1], values[2], values[3]);
Nicolas Capens264f1522015-01-09 17:21:17 -05005427 }
5428}
5429
Nicolas Capensa9b49372015-01-30 00:33:26 -05005430void APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
Nicolas Capens264f1522015-01-09 17:21:17 -05005431{
5432 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07005433 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005434 index, size, type, normalized, stride, ptr);
5435
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005436 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005437 {
5438 return error(GL_INVALID_VALUE);
5439 }
5440
5441 if(size < 1 || size > 4)
5442 {
5443 return error(GL_INVALID_VALUE);
5444 }
5445
5446 switch(type)
5447 {
5448 case GL_BYTE:
5449 case GL_UNSIGNED_BYTE:
5450 case GL_SHORT:
5451 case GL_UNSIGNED_SHORT:
5452 case GL_FIXED:
5453 case GL_FLOAT:
5454 break;
5455 default:
5456 return error(GL_INVALID_ENUM);
5457 }
5458
5459 if(stride < 0)
5460 {
5461 return error(GL_INVALID_VALUE);
5462 }
5463
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005464 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005465
5466 if(context)
5467 {
5468 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
5469 }
5470}
5471
Nicolas Capensa9b49372015-01-30 00:33:26 -05005472void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05005473{
5474 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
5475
5476 if(width < 0 || height < 0)
5477 {
5478 return error(GL_INVALID_VALUE);
5479 }
5480
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005481 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005482
5483 if(context)
5484 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005485 if(context->getListIndex() != 0)
5486 {
5487 UNIMPLEMENTED();
5488 }
5489
Nicolas Capens264f1522015-01-09 17:21:17 -05005490 context->setViewportParams(x, y, width, height);
5491 }
5492}
5493
Nicolas Capensa9b49372015-01-30 00:33:26 -05005494void APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
Nicolas Capens264f1522015-01-09 17:21:17 -05005495 GLbitfield mask, GLenum filter)
5496{
5497 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5498 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5499 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5500 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5501
5502 switch(filter)
5503 {
5504 case GL_NEAREST:
5505 break;
5506 default:
5507 return error(GL_INVALID_ENUM);
5508 }
5509
5510 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5511 {
5512 return error(GL_INVALID_VALUE);
5513 }
5514
5515 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5516 {
5517 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5518 return error(GL_INVALID_OPERATION);
5519 }
5520
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005521 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005522
5523 if(context)
5524 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005525 if(context->getListIndex() != 0)
5526 {
5527 UNIMPLEMENTED();
5528 }
5529
Nicolas Capens7cc75e12015-01-29 14:44:24 -05005530 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
Nicolas Capens264f1522015-01-09 17:21:17 -05005531 {
5532 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5533 return error(GL_INVALID_OPERATION);
5534 }
5535
5536 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5537 }
5538}
5539
Nicolas Capensa9b49372015-01-30 00:33:26 -05005540void APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
Nicolas Capens264f1522015-01-09 17:21:17 -05005541 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
5542{
5543 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5544 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07005545 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005546 target, level, internalformat, width, height, depth, border, format, type, pixels);
5547
5548 UNIMPLEMENTED(); // FIXME
5549}
5550
Nicolas Capensa9b49372015-01-30 00:33:26 -05005551void WINAPI GlmfBeginGlsBlock()
Nicolas Capens264f1522015-01-09 17:21:17 -05005552{
Nicolas Capensa9b49372015-01-30 00:33:26 -05005553 UNIMPLEMENTED();
5554}
5555
5556void WINAPI GlmfCloseMetaFile()
5557{
5558 UNIMPLEMENTED();
5559}
5560
5561void WINAPI GlmfEndGlsBlock()
5562{
5563 UNIMPLEMENTED();
5564}
5565
5566void WINAPI GlmfEndPlayback()
5567{
5568 UNIMPLEMENTED();
5569}
5570
5571void WINAPI GlmfInitPlayback()
5572{
5573 UNIMPLEMENTED();
5574}
5575
5576void WINAPI GlmfPlayGlsRecord()
5577{
5578 UNIMPLEMENTED();
5579}
5580
5581void APIENTRY glAccum(GLenum op, GLfloat value)
5582{
5583 UNIMPLEMENTED();
5584}
5585
5586void APIENTRY glAlphaFunc(GLenum func, GLclampf ref)
5587{
5588 TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);
5589
5590 gl::Context *context = gl::getContext();
5591
5592 if(context)
Nicolas Capens264f1522015-01-09 17:21:17 -05005593 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005594 if(context->getListIndex() != 0)
5595 {
5596 UNIMPLEMENTED();
5597 }
5598
5599 context->alphaFunc(func, ref);
Nicolas Capens264f1522015-01-09 17:21:17 -05005600 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05005601}
Nicolas Capens264f1522015-01-09 17:21:17 -05005602
Nicolas Capensa9b49372015-01-30 00:33:26 -05005603GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
5604{
5605 UNIMPLEMENTED();
5606 return GL_FALSE;
5607}
Nicolas Capens264f1522015-01-09 17:21:17 -05005608
Nicolas Capensa9b49372015-01-30 00:33:26 -05005609void APIENTRY glArrayElement(GLint i)
5610{
5611 UNIMPLEMENTED();
5612}
5613
5614void APIENTRY glBegin(GLenum mode)
5615{
5616 TRACE("(GLenum mode = 0x%X)", mode);
5617
5618 switch(mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05005619 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005620 case GL_POINTS:
5621 case GL_LINES:
5622 case GL_LINE_STRIP:
5623 case GL_LINE_LOOP:
5624 case GL_TRIANGLES:
5625 case GL_TRIANGLE_STRIP:
5626 case GL_TRIANGLE_FAN:
5627 case GL_QUADS:
5628 case GL_QUAD_STRIP:
5629 case GL_POLYGON:
Nicolas Capens264f1522015-01-09 17:21:17 -05005630 break;
5631 default:
5632 return error(GL_INVALID_ENUM);
5633 }
5634
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005635 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005636
5637 if(context)
5638 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005639 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05005640 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005641 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05005642 }
5643
Nicolas Capensa9b49372015-01-30 00:33:26 -05005644 context->begin(mode);
Nicolas Capens264f1522015-01-09 17:21:17 -05005645 }
5646}
5647
Nicolas Capensa9b49372015-01-30 00:33:26 -05005648void APIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
Nicolas Capens264f1522015-01-09 17:21:17 -05005649{
Nicolas Capens264f1522015-01-09 17:21:17 -05005650 UNIMPLEMENTED();
5651}
5652
Nicolas Capensa9b49372015-01-30 00:33:26 -05005653void APIENTRY glCallList(GLuint list)
Nicolas Capens264f1522015-01-09 17:21:17 -05005654{
Nicolas Capensa9b49372015-01-30 00:33:26 -05005655 TRACE("(GLuint list = %d)", list);
5656
5657 if(list == 0)
5658 {
5659 return error(GL_INVALID_VALUE);
5660 }
5661
5662 gl::Context *context = gl::getContext();
5663
5664 if(context)
5665 {
5666 if(context->getListIndex() != 0)
5667 {
5668 UNIMPLEMENTED();
5669 }
5670
5671 context->callList(list);
5672 }
5673}
5674
5675void APIENTRY glCallLists(GLsizei n, GLenum type, const GLvoid *lists)
5676{
5677 TRACE("(GLsizei n = %d, GLenum type = 0x%X, const GLvoid *lists)", n, type);
5678
5679 gl::Context *context = gl::getContext();
5680
5681 if(context)
5682 {
5683 if(context->getListIndex() != 0)
5684 {
5685 UNIMPLEMENTED();
5686 }
5687
5688 for(int i = 0; i < n; i++)
5689 {
5690 switch(type)
5691 {
5692 case GL_UNSIGNED_INT: context->callList(((unsigned int*)lists)[i]); break;
5693 default:
5694 UNIMPLEMENTED();
5695 UNREACHABLE();
5696 }
5697 }
5698 }
5699}
5700
5701void APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
5702{
5703 UNIMPLEMENTED();
5704}
5705
5706void APIENTRY glClearDepth(GLclampd depth)
5707{
5708 TRACE("(GLclampd depth = %d)", depth);
5709
5710 glClearDepthf((float)depth); // FIXME
5711}
5712
5713void APIENTRY glClearIndex(GLfloat c)
5714{
5715 UNIMPLEMENTED();
5716}
5717
5718void APIENTRY glClipPlane(GLenum plane, const GLdouble *equation)
5719{
5720 UNIMPLEMENTED();
5721}
5722
5723void APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue)
5724{
5725 UNIMPLEMENTED();
5726}
5727
5728void APIENTRY glColor3bv(const GLbyte *v)
5729{
5730 UNIMPLEMENTED();
5731}
5732
5733void APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue)
5734{
5735 UNIMPLEMENTED();
5736}
5737
5738void APIENTRY glColor3dv(const GLdouble *v)
5739{
5740 UNIMPLEMENTED();
5741}
5742
5743void APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue)
5744{
5745 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f)", red, green, blue);
5746
5747 gl::Context *context = gl::getContext();
5748
5749 if(context)
5750 {
5751 if(context->getListIndex() != 0)
5752 {
5753 UNIMPLEMENTED();
5754 }
5755
5756 //context->color(red, green, blue, 1.0f);
5757 //GLfloat vals[4] = {};
5758 context->setVertexAttrib(sw::Color0, red, green, blue, 1);
5759 }
5760}
5761
5762void APIENTRY glColor3fv(const GLfloat *v)
5763{
5764 UNIMPLEMENTED();
5765}
5766
5767void APIENTRY glColor3i(GLint red, GLint green, GLint blue)
5768{
5769 UNIMPLEMENTED();
5770}
5771
5772void APIENTRY glColor3iv(const GLint *v)
5773{
5774 UNIMPLEMENTED();
5775}
5776
5777void APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue)
5778{
5779 UNIMPLEMENTED();
5780}
5781
5782void APIENTRY glColor3sv(const GLshort *v)
5783{
5784 UNIMPLEMENTED();
5785}
5786
5787void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue)
5788{
5789 UNIMPLEMENTED();
5790}
5791
5792void APIENTRY glColor3ubv(const GLubyte *v)
5793{
5794 UNIMPLEMENTED();
5795}
5796
5797void APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue)
5798{
5799 UNIMPLEMENTED();
5800}
5801
5802void APIENTRY glColor3uiv(const GLuint *v)
5803{
5804 UNIMPLEMENTED();
5805}
5806
5807void APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue)
5808{
5809 UNIMPLEMENTED();
5810}
5811
5812void APIENTRY glColor3usv(const GLushort *v)
5813{
5814 UNIMPLEMENTED();
5815}
5816
5817void APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
5818{
5819 UNIMPLEMENTED();
5820}
5821
5822void APIENTRY glColor4bv(const GLbyte *v)
5823{
5824 UNIMPLEMENTED();
5825}
5826
5827void APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
5828{
5829 UNIMPLEMENTED();
5830}
5831
5832void APIENTRY glColor4dv(const GLdouble *v)
5833{
5834 UNIMPLEMENTED();
5835}
5836
5837void APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
5838{
5839 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);
5840
5841 gl::Context *context = gl::getContext();
5842
5843 if(context)
5844 {
5845 if(context->getListIndex() != 0)
5846 {
5847 UNIMPLEMENTED();
5848 }
5849
5850 //context->color(red, green, blue, alpha);
5851 //GLfloat vals[4] = {red, green, blue, alpha};
5852 context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
5853 }
5854}
5855
5856void APIENTRY glColor4fv(const GLfloat *v)
5857{
5858 UNIMPLEMENTED();
5859}
5860
5861void APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha)
5862{
5863 UNIMPLEMENTED();
5864}
5865
5866void APIENTRY glColor4iv(const GLint *v)
5867{
5868 UNIMPLEMENTED();
5869}
5870
5871void APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
5872{
5873 UNIMPLEMENTED();
5874}
5875
5876void APIENTRY glColor4sv(const GLshort *v)
5877{
5878 UNIMPLEMENTED();
5879}
5880
5881void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
5882{
5883 UNIMPLEMENTED();
5884}
5885
5886void APIENTRY glColor4ubv(const GLubyte *v)
5887{
5888 UNIMPLEMENTED();
5889}
5890
5891void APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
5892{
5893 UNIMPLEMENTED();
5894}
5895
5896void APIENTRY glColor4uiv(const GLuint *v)
5897{
5898 UNIMPLEMENTED();
5899}
5900
5901void APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
5902{
5903 UNIMPLEMENTED();
5904}
5905
5906void APIENTRY glColor4usv(const GLushort *v)
5907{
5908 UNIMPLEMENTED();
5909}
5910
5911void APIENTRY glColorMaterial(GLenum face, GLenum mode)
5912{
5913 TRACE("(GLenum face = 0x%X, GLenum mode = 0x%X)", face, mode);
5914
5915 // FIXME: Validate enums
5916
5917 gl::Context *context = gl::getContext();
5918
5919 if(context)
5920 {
5921 if(context->getListIndex() != 0)
5922 {
5923 UNIMPLEMENTED();
5924 }
5925
5926 switch(face)
5927 {
5928 case GL_FRONT:
5929 context->setColorMaterialMode(mode); // FIXME: Front only
5930 break;
5931 case GL_FRONT_AND_BACK:
5932 context->setColorMaterialMode(mode);
5933 break;
5934 default:
5935 UNIMPLEMENTED();
5936 return error(GL_INVALID_ENUM);
5937 }
5938 }
5939}
5940
5941void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
5942{
5943 TRACE("(*)");
5944
5945 glVertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
5946}
5947
5948void APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
5949{
5950 UNIMPLEMENTED();
5951}
5952
5953void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)
5954{
5955 UNIMPLEMENTED();
5956}
5957
5958void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
5959{
5960 UNIMPLEMENTED();
5961}
5962
5963void APIENTRY glDebugEntry()
5964{
5965 UNIMPLEMENTED();
5966}
5967
5968void APIENTRY glDeleteLists(GLuint list, GLsizei range)
5969{
5970 TRACE("(GLuint list = %d, GLsizei range = %d)", list, range);
5971
5972 if(range < 0)
5973 {
5974 return error(GL_INVALID_VALUE);
5975 }
5976
5977 gl::Context *context = gl::getContext();
5978
5979 if(context)
5980 {
Alexis Hetuf7be67f2015-02-11 16:11:07 -05005981 for(GLuint i = list; i < list + range; i++)
Nicolas Capensa9b49372015-01-30 00:33:26 -05005982 {
5983 context->deleteList(i);
5984 }
5985 }
5986}
5987
5988void APIENTRY glDepthRange(GLclampd zNear, GLclampd zFar)
5989{
5990 UNIMPLEMENTED();
5991}
5992
5993void APIENTRY glDisableClientState(GLenum array)
5994{
5995 TRACE("(GLenum array = 0x%X)", array);
5996
5997 gl::Context *context = gl::getContext();
5998
5999 if(context)
6000 {
6001 GLenum texture = context->getClientActiveTexture();
6002
6003 switch(array)
6004 {
6005 case GL_VERTEX_ARRAY: context->setEnableVertexAttribArray(sw::Position, false); break;
6006 case GL_COLOR_ARRAY: context->setEnableVertexAttribArray(sw::Color0, false); break;
6007 case GL_TEXTURE_COORD_ARRAY: context->setEnableVertexAttribArray(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
6008 case GL_NORMAL_ARRAY: context->setEnableVertexAttribArray(sw::Normal, false); break;
6009 default: UNIMPLEMENTED();
6010 }
6011 }
6012}
6013
6014void APIENTRY glDrawBuffer(GLenum mode)
6015{
6016 UNIMPLEMENTED();
6017}
6018
6019void APIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
6020{
6021 UNIMPLEMENTED();
6022}
6023
6024void APIENTRY glEdgeFlag(GLboolean flag)
6025{
6026 UNIMPLEMENTED();
6027}
6028
6029void APIENTRY glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)
6030{
6031 UNIMPLEMENTED();
6032}
6033
6034void APIENTRY glEdgeFlagv(const GLboolean *flag)
6035{
6036 UNIMPLEMENTED();
6037}
6038
6039void APIENTRY glEnableClientState(GLenum array)
6040{
6041 TRACE("(GLenum array = 0x%X)", array);
6042
6043 gl::Context *context = gl::getContext();
6044
6045 if(context)
6046 {
6047 GLenum texture = context->getClientActiveTexture();
6048
6049 switch(array)
6050 {
6051 case GL_VERTEX_ARRAY: context->setEnableVertexAttribArray(sw::Position, true); break;
6052 case GL_COLOR_ARRAY: context->setEnableVertexAttribArray(sw::Color0, true); break;
6053 case GL_TEXTURE_COORD_ARRAY: context->setEnableVertexAttribArray(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
6054 case GL_NORMAL_ARRAY: context->setEnableVertexAttribArray(sw::Normal, true); break;
6055 default: UNIMPLEMENTED();
6056 }
6057 }
6058}
6059
6060void APIENTRY glEnd()
6061{
6062 TRACE("()");
6063
6064 gl::Context *context = gl::getContext();
6065
6066 if(context)
6067 {
6068 if(context->getListIndex() != 0)
6069 {
6070 UNIMPLEMENTED();
6071 }
6072
6073 context->end();
6074 }
6075}
6076
6077void APIENTRY glEndList()
6078{
6079 TRACE("()");
6080
6081 gl::Context *context = gl::getContext();
6082
6083 if(context)
6084 {
6085 context->endList();
6086 }
6087}
6088
6089void APIENTRY glEvalCoord1d(GLdouble u)
6090{
6091 UNIMPLEMENTED();
6092}
6093
6094void APIENTRY glEvalCoord1dv(const GLdouble *u)
6095{
6096 UNIMPLEMENTED();
6097}
6098
6099void APIENTRY glEvalCoord1f(GLfloat u)
6100{
6101 UNIMPLEMENTED();
6102}
6103
6104void APIENTRY glEvalCoord1fv(const GLfloat *u)
6105{
6106 UNIMPLEMENTED();
6107}
6108
6109void APIENTRY glEvalCoord2d(GLdouble u, GLdouble v)
6110{
6111 UNIMPLEMENTED();
6112}
6113
6114void APIENTRY glEvalCoord2dv(const GLdouble *u)
6115{
6116 UNIMPLEMENTED();
6117}
6118
6119void APIENTRY glEvalCoord2f(GLfloat u, GLfloat v)
6120{
6121 UNIMPLEMENTED();
6122}
6123
6124void APIENTRY glEvalCoord2fv(const GLfloat *u)
6125{
6126 UNIMPLEMENTED();
6127}
6128
6129void APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2)
6130{
6131 UNIMPLEMENTED();
6132}
6133
6134void APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
6135{
6136 UNIMPLEMENTED();
6137}
6138
6139void APIENTRY glEvalPoint1(GLint i)
6140{
6141 UNIMPLEMENTED();
6142}
6143
6144void APIENTRY glEvalPoint2(GLint i, GLint j)
6145{
6146 UNIMPLEMENTED();
6147}
6148
6149void APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
6150{
6151 UNIMPLEMENTED();
6152}
6153
6154void APIENTRY glFogf(GLenum pname, GLfloat param)
6155{
6156 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
6157
6158 gl::Context *context = gl::getContext();
6159
6160 if(context)
6161 {
6162 if(context->getListIndex() != 0)
6163 {
6164 UNIMPLEMENTED();
6165 }
6166
6167 gl::Device *device = gl::getDevice(); // FIXME
6168
6169 switch(pname)
6170 {
6171 case GL_FOG_START: device->setFogStart(param); break;
6172 case GL_FOG_END: device->setFogEnd(param); break;
6173 default:
6174 UNIMPLEMENTED();
6175 return error(GL_INVALID_ENUM);
6176 }
6177 }
6178}
6179
6180void APIENTRY glFogfv(GLenum pname, const GLfloat *params)
6181{
6182 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
6183
6184 gl::Context *context = gl::getContext();
6185
6186 if(context)
6187 {
6188 if(context->getListIndex() != 0)
6189 {
6190 UNIMPLEMENTED();
6191 }
6192
6193 switch(pname)
6194 {
6195 case GL_FOG_COLOR:
6196 {
6197 gl::Device *device = gl::getDevice(); // FIXME
6198 device->setFogColor(sw::Color<float>(params[0], params[1], params[2], params[3]));
6199 }
6200 break;
6201 default:
6202 UNIMPLEMENTED();
6203 return error(GL_INVALID_ENUM);
6204 }
6205 }
6206}
6207
6208void APIENTRY glFogi(GLenum pname, GLint param)
6209{
6210 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
6211
6212 gl::Context *context = gl::getContext();
6213
6214 if(context)
6215 {
6216 if(context->getListIndex() != 0)
6217 {
6218 UNIMPLEMENTED();
6219 }
6220
6221 switch(pname)
6222 {
6223 case GL_FOG_MODE:
6224 {
6225 gl::Device *device = gl::getDevice(); // FIXME
6226 switch(param)
6227 {
6228 case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
6229 default:
6230 UNIMPLEMENTED();
6231 return error(GL_INVALID_ENUM);
6232 }
6233 }
6234 break;
6235 default:
6236 UNIMPLEMENTED();
6237 return error(GL_INVALID_ENUM);
6238 }
6239 }
6240}
6241
6242void APIENTRY glFogiv(GLenum pname, const GLint *params)
6243{
6244 UNIMPLEMENTED();
6245}
6246
6247void APIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
6248{
Nicolas Capens74626012015-03-11 21:49:44 -04006249 TRACE("(GLdouble left = %f, GLdouble right = %f, GLdouble bottom = %f, GLdouble top = %f, GLdouble zNear = %f, GLdouble zFar = %f)", left, right, bottom, top, zNear, zFar);
Maxime Gregoirefec81292015-03-04 14:44:36 -05006250
6251 gl::Context *context = gl::getContext();
6252
6253 if(context)
6254 {
6255 if(context->getListIndex() != 0)
6256 {
6257 UNIMPLEMENTED();
6258 }
6259
6260 context->frustum(left, right, bottom, top, zNear, zFar);
6261 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05006262}
6263
6264GLuint APIENTRY glGenLists(GLsizei range)
6265{
6266 TRACE("(GLsizei range = %d)", range);
6267
6268 if(range < 0)
6269 {
6270 return error(GL_INVALID_VALUE, 0);
6271 }
6272
6273 gl::Context *context = gl::getContext();
6274
6275 if(context)
6276 {
6277 return context->genLists(range);
6278 }
6279
6280 return 0;
6281}
6282
6283void APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation)
6284{
6285 UNIMPLEMENTED();
6286}
6287
6288void APIENTRY glGetDoublev(GLenum pname, GLdouble *params)
6289{
6290 UNIMPLEMENTED();
6291}
6292
6293void APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
6294{
6295 UNIMPLEMENTED();
6296}
6297
6298void APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params)
6299{
6300 UNIMPLEMENTED();
6301}
6302
6303void APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v)
6304{
6305 UNIMPLEMENTED();
6306}
6307
6308void APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v)
6309{
6310 UNIMPLEMENTED();
6311}
6312
6313void APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v)
6314{
6315 UNIMPLEMENTED();
6316}
6317
6318void APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
6319{
6320 UNIMPLEMENTED();
6321}
6322
6323void APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params)
6324{
6325 UNIMPLEMENTED();
6326}
6327
6328void APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values)
6329{
6330 UNIMPLEMENTED();
6331}
6332
6333void APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values)
6334{
6335 UNIMPLEMENTED();
6336}
6337
6338void APIENTRY glGetPixelMapusv(GLenum map, GLushort *values)
6339{
6340 UNIMPLEMENTED();
6341}
6342
6343void APIENTRY glGetPointerv(GLenum pname, GLvoid* *params)
6344{
6345 UNIMPLEMENTED();
6346}
6347
6348void APIENTRY glGetPolygonStipple(GLubyte *mask)
6349{
6350 UNIMPLEMENTED();
6351}
6352
6353void APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
6354{
6355 UNIMPLEMENTED();
6356}
6357
6358void APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params)
6359{
6360 UNIMPLEMENTED();
6361}
6362
6363void APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
6364{
6365 UNIMPLEMENTED();
6366}
6367
6368void APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
6369{
6370 UNIMPLEMENTED();
6371}
6372
6373void APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
6374{
6375 UNIMPLEMENTED();
6376}
6377
6378void APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
6379{
Nicolas Capens4be33702015-04-28 15:13:30 -07006380 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum format = 0x%X, GLenum type = 0x%X, GLint *pixels%p)", target, level, format, type, pixels);
Nicolas Capensa9b49372015-01-30 00:33:26 -05006381
6382 gl::Context *context = gl::getContext();
6383
6384 if(context)
6385 {
6386 gl::Texture *texture;
6387
6388 switch(target)
6389 {
6390 case GL_TEXTURE_2D:
6391 texture = context->getTexture2D(target);
6392 break;
6393 case GL_TEXTURE_CUBE_MAP:
6394 texture = context->getTextureCubeMap();
6395 break;
6396 default:
6397 UNIMPLEMENTED();
6398 return error(GL_INVALID_ENUM);
6399 }
6400
6401 if(format == texture->getFormat(target, level) && type == texture->getType(target, level))
6402 {
6403 gl::Image *image = texture->getRenderTarget(target, level);
6404 void *source = image->lock(0, 0, sw::LOCK_READONLY);
6405 memcpy(pixels, source, image->getPitch() * image->getHeight());
6406 image->unlock();
6407 }
6408 else
6409 {
6410 UNIMPLEMENTED();
6411 }
6412 }
6413}
6414
6415void APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
6416{
6417 UNIMPLEMENTED();
6418}
6419
6420void APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
6421{
Nicolas Capens4be33702015-04-28 15:13:30 -07006422 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLint *params = %p)", target, level, pname, params);
Nicolas Capensa9b49372015-01-30 00:33:26 -05006423
6424 gl::Context *context = gl::getContext();
6425
6426 if(context)
6427 {
6428 gl::Texture *texture;
6429
6430 switch(target)
6431 {
6432 case GL_TEXTURE_2D:
6433 case GL_PROXY_TEXTURE_2D:
6434 texture = context->getTexture2D(target);
6435 break;
6436 case GL_TEXTURE_CUBE_MAP:
6437 texture = context->getTextureCubeMap();
6438 break;
6439 default:
6440 UNIMPLEMENTED();
6441 return error(GL_INVALID_ENUM);
6442 }
6443
6444 switch(pname)
6445 {
6446 case GL_TEXTURE_MAG_FILTER:
6447 *params = texture->getMagFilter();
6448 break;
6449 case GL_TEXTURE_MIN_FILTER:
6450 *params = texture->getMinFilter();
6451 break;
6452 case GL_TEXTURE_WRAP_S:
6453 *params = texture->getWrapS();
6454 break;
6455 case GL_TEXTURE_WRAP_T:
6456 *params = texture->getWrapT();
6457 break;
6458 case GL_TEXTURE_WIDTH:
6459 *params = texture->getWidth(target, level);
6460 break;
6461 case GL_TEXTURE_HEIGHT:
6462 *params = texture->getHeight(target, level);
6463 break;
6464 case GL_TEXTURE_INTERNAL_FORMAT:
6465 *params = texture->getInternalFormat(target, level);
6466 break;
6467 case GL_TEXTURE_BORDER_COLOR:
6468 UNIMPLEMENTED();
6469 break;
6470 case GL_TEXTURE_BORDER:
6471 UNIMPLEMENTED();
6472 break;
6473 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6474 *params = (GLint)texture->getMaxAnisotropy();
6475 break;
6476 default:
6477 return error(GL_INVALID_ENUM);
6478 }
6479 }
6480}
6481
6482void APIENTRY glIndexMask(GLuint mask)
6483{
6484 UNIMPLEMENTED();
6485}
6486
6487void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
6488{
6489 UNIMPLEMENTED();
6490}
6491
6492void APIENTRY glIndexd(GLdouble c)
6493{
6494 UNIMPLEMENTED();
6495}
6496
6497void APIENTRY glIndexdv(const GLdouble *c)
6498{
6499 UNIMPLEMENTED();
6500}
6501
6502void APIENTRY glIndexf(GLfloat c)
6503{
6504 UNIMPLEMENTED();
6505}
6506
6507void APIENTRY glIndexfv(const GLfloat *c)
6508{
6509 UNIMPLEMENTED();
6510}
6511
6512void APIENTRY glIndexi(GLint c)
6513{
6514 UNIMPLEMENTED();
6515}
6516
6517void APIENTRY glIndexiv(const GLint *c)
6518{
6519 UNIMPLEMENTED();
6520}
6521
6522void APIENTRY glIndexs(GLshort c)
6523{
6524 UNIMPLEMENTED();
6525}
6526
6527void APIENTRY glIndexsv(const GLshort *c)
6528{
6529 UNIMPLEMENTED();
6530}
6531
6532void APIENTRY glIndexub(GLubyte c)
6533{
6534 UNIMPLEMENTED();
6535}
6536
6537void APIENTRY glIndexubv(const GLubyte *c)
6538{
6539 UNIMPLEMENTED();
6540}
6541
6542void APIENTRY glInitNames(void)
6543{
6544 UNIMPLEMENTED();
6545}
6546
6547void APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
6548{
6549 UNIMPLEMENTED();
6550}
6551
6552GLboolean APIENTRY glIsList(GLuint list)
6553{
6554 UNIMPLEMENTED();
6555 return GL_FALSE;
6556}
6557
6558void APIENTRY glLightModelf(GLenum pname, GLfloat param)
6559{
6560 UNIMPLEMENTED();
6561}
6562
6563void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
6564{
6565 TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
6566
6567 gl::Context *context = gl::getContext();
6568
6569 if(context)
6570 {
6571 if(context->getListIndex() != 0)
6572 {
6573 UNIMPLEMENTED();
6574 }
6575
6576 gl::Device *device = gl::getDevice(); // FIXME
6577
6578 switch(pname)
6579 {
6580 case GL_LIGHT_MODEL_AMBIENT:
6581 device->setGlobalAmbient(sw::Color<float>(params[0], params[1], params[2], params[3]));
6582 break;
6583 default:
6584 UNIMPLEMENTED();
6585 return error(GL_INVALID_ENUM);
6586 }
6587 }
6588}
6589
6590void APIENTRY glLightModeli(GLenum pname, GLint param)
6591{
6592 UNIMPLEMENTED();
6593}
6594
6595void APIENTRY glLightModeliv(GLenum pname, const GLint *params)
6596{
6597 TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
6598 UNIMPLEMENTED();
6599}
6600
6601void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
6602{
6603 UNIMPLEMENTED();
6604}
6605
6606void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
6607{
6608 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
6609
6610 gl::Context *context = gl::getContext();
6611
6612 if(context)
6613 {
6614 if(context->getListIndex() != 0)
6615 {
6616 UNIMPLEMENTED();
6617 }
6618
6619 gl::Device *device = gl::getDevice(); // FIXME
6620
6621 switch(pname)
6622 {
6623 case GL_AMBIENT: device->setLightAmbient(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6624 case GL_DIFFUSE: device->setLightDiffuse(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6625 case GL_SPECULAR: device->setLightSpecular(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6626 case GL_POSITION:
6627 if(params[3] == 0.0f) // Directional light
6628 {
6629 // Create a very far out point light
6630 float max = std::max(std::max(abs(params[0]), abs(params[1])), abs(params[2]));
6631 device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / max * 1e10f, params[1] / max * 1e10f, params[2] / max * 1e10f));
6632 }
6633 else
6634 {
6635 device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / params[3], params[1] / params[3], params[2] / params[3]));
6636 }
6637 break;
6638 default:
6639 UNIMPLEMENTED();
6640 return error(GL_INVALID_ENUM);
6641 }
6642 }
6643}
6644
6645void APIENTRY glLighti(GLenum light, GLenum pname, GLint param)
6646{
6647 UNIMPLEMENTED();
6648}
6649
6650void APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params)
6651{
6652 UNIMPLEMENTED();
6653}
6654
6655void APIENTRY glLineStipple(GLint factor, GLushort pattern)
6656{
6657 UNIMPLEMENTED();
6658}
6659
6660void APIENTRY glListBase(GLuint base)
6661{
6662 UNIMPLEMENTED();
6663}
6664
6665void APIENTRY glLoadIdentity()
6666{
6667 TRACE("()");
6668
6669 gl::Context *context = gl::getContext();
6670
6671 if(context)
6672 {
6673 if(context->getListIndex() != 0)
6674 {
6675 UNIMPLEMENTED();
6676 }
6677
6678 context->loadIdentity();
6679 }
6680}
6681
6682void APIENTRY glLoadMatrixd(const GLdouble *m)
6683{
6684 UNIMPLEMENTED();
6685}
6686
6687void APIENTRY glLoadMatrixf(const GLfloat *m)
6688{
6689 UNIMPLEMENTED();
6690}
6691
6692void APIENTRY glLoadName(GLuint name)
6693{
6694 UNIMPLEMENTED();
6695}
6696
6697void APIENTRY glLogicOp(GLenum opcode)
6698{
6699 UNIMPLEMENTED();
6700}
6701
6702void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
6703{
6704 UNIMPLEMENTED();
6705}
6706
6707void APIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
6708{
6709 UNIMPLEMENTED();
6710}
6711
6712void APIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)
6713{
6714 UNIMPLEMENTED();
6715}
6716
6717void APIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)
6718{
6719 UNIMPLEMENTED();
6720}
6721
6722void APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
6723{
6724 UNIMPLEMENTED();
6725}
6726
6727void APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
6728{
6729 UNIMPLEMENTED();
6730}
6731
6732void APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
6733{
6734 UNIMPLEMENTED();
6735}
6736
6737void APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
6738{
6739 UNIMPLEMENTED();
6740}
6741
6742void APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
6743{
6744 UNIMPLEMENTED();
6745}
6746
6747void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
6748{
6749 UNIMPLEMENTED();
6750}
6751
6752void APIENTRY glMateriali(GLenum face, GLenum pname, GLint param)
6753{
6754 UNIMPLEMENTED();
6755}
6756
6757void APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params)
6758{
6759 UNIMPLEMENTED();
6760}
6761
6762void APIENTRY glMatrixMode(GLenum mode)
6763{
6764 TRACE("(*)");
6765
6766 gl::Context *context = gl::getContext();
6767
6768 if(context)
6769 {
6770 if(context->getListIndex() != 0)
6771 {
6772 UNIMPLEMENTED();
6773 }
6774
6775 context->setMatrixMode(mode);
6776 }
6777}
6778
6779void APIENTRY glMultMatrixd(const GLdouble *m)
6780{
Maxime Gregoire53ff8d82015-03-04 14:51:58 -05006781 TRACE("(*)");
6782
6783 gl::Context *context = gl::getContext();
6784
6785 if(context)
6786 {
6787 if(context->getListIndex() != 0)
6788 {
6789 UNIMPLEMENTED();
6790 }
6791
6792 context->multiply(m);
6793 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05006794}
6795
6796void APIENTRY glMultMatrixm(sw::Matrix m)
6797{
6798 gl::Context *context = gl::getContext();
6799
6800 if(context)
6801 {
6802 context->multiply((GLfloat*)m.m);
6803 }
6804}
6805
6806void APIENTRY glMultMatrixf(const GLfloat *m)
6807{
6808 TRACE("(*)");
6809
6810 gl::Context *context = gl::getContext();
6811
6812 if(context)
6813 {
6814 if(context->getListIndex() != 0)
6815 {
6816 return context->listCommand(gl::newCommand(glMultMatrixm, sw::Matrix(m)));
6817 }
6818
6819 context->multiply(m);
6820 }
6821}
6822
6823void APIENTRY glNewList(GLuint list, GLenum mode)
6824{
6825 TRACE("(GLuint list = %d, GLenum mode = 0x%X)", list, mode);
6826
6827 if(list == 0)
6828 {
6829 return error(GL_INVALID_VALUE);
6830 }
6831
6832 switch(mode)
6833 {
6834 case GL_COMPILE:
6835 case GL_COMPILE_AND_EXECUTE:
6836 break;
6837 default:
6838 return error(GL_INVALID_ENUM);
6839 }
6840
6841 gl::Context *context = gl::getContext();
6842
6843 if(context)
6844 {
6845 if(context->getListIndex() != 0)
6846 {
6847 UNIMPLEMENTED();
6848 }
6849
6850 context->newList(list, mode);
6851 }
6852}
6853
6854void APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
6855{
6856 UNIMPLEMENTED();
6857}
6858
6859void APIENTRY glNormal3bv(const GLbyte *v)
6860{
6861 UNIMPLEMENTED();
6862}
6863
6864void APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
6865{
6866 UNIMPLEMENTED();
6867}
6868
6869void APIENTRY glNormal3dv(const GLdouble *v)
6870{
6871 UNIMPLEMENTED();
6872}
6873
6874void APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
6875{
6876 TRACE("(GLfloat nx = %f, GLfloat ny = %f, GLfloat nz = %f)", nx, ny, nz);
6877
6878 gl::Context *context = gl::getContext();
6879
6880 if(context)
6881 {
6882 if(context->getListIndex() != 0)
6883 {
6884 UNIMPLEMENTED();
6885 }
6886
6887 //context->normal(nx, ny, nz);
6888 context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
6889 }
6890}
6891
6892void APIENTRY glNormal3fv(const GLfloat *v)
6893{
6894 UNIMPLEMENTED();
6895}
6896
6897void APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz)
6898{
6899 UNIMPLEMENTED();
6900}
6901
6902void APIENTRY glNormal3iv(const GLint *v)
6903{
6904 UNIMPLEMENTED();
6905}
6906
6907void APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz)
6908{
6909 UNIMPLEMENTED();
6910}
6911
6912void APIENTRY glNormal3sv(const GLshort *v)
6913{
6914 UNIMPLEMENTED();
6915}
6916
6917void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
6918{
6919 TRACE("(*)");
6920
Nicolas Capensa3fac8b2015-05-25 15:57:03 -04006921 glVertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);
Nicolas Capensa9b49372015-01-30 00:33:26 -05006922}
6923
6924void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
6925{
6926 TRACE("(*)");
6927
6928 gl::Context *context = gl::getContext();
6929
6930 if(context)
6931 {
6932 if(context->getListIndex() != 0)
6933 {
6934 UNIMPLEMENTED();
6935 }
6936
6937 context->ortho(left, right, bottom, top, zNear, zFar);
6938 }
6939}
6940
6941void APIENTRY glPassThrough(GLfloat token)
6942{
6943 UNIMPLEMENTED();
6944}
6945
6946void APIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)
6947{
6948 UNIMPLEMENTED();
6949}
6950
6951void APIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)
6952{
6953 UNIMPLEMENTED();
6954}
6955
6956void APIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)
6957{
6958 UNIMPLEMENTED();
6959}
6960
6961void APIENTRY glPixelStoref(GLenum pname, GLfloat param)
6962{
6963 UNIMPLEMENTED();
6964}
6965
6966void APIENTRY glPixelTransferf(GLenum pname, GLfloat param)
6967{
6968 UNIMPLEMENTED();
6969}
6970
6971void APIENTRY glPixelTransferi(GLenum pname, GLint param)
6972{
6973 UNIMPLEMENTED();
6974}
6975
6976void APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
6977{
6978 UNIMPLEMENTED();
6979}
6980
6981void APIENTRY glPointSize(GLfloat size)
6982{
6983 UNIMPLEMENTED();
6984}
6985
6986void APIENTRY glPolygonMode(GLenum face, GLenum mode)
6987{
6988 UNIMPLEMENTED();
6989}
6990
6991void APIENTRY glPolygonStipple(const GLubyte *mask)
6992{
6993 UNIMPLEMENTED();
6994}
6995
6996void APIENTRY glPopAttrib(void)
6997{
6998 UNIMPLEMENTED();
6999}
7000
7001void APIENTRY glPopClientAttrib(void)
7002{
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007003 UNIMPLEMENTED();
Nicolas Capensa9b49372015-01-30 00:33:26 -05007004}
7005
7006void APIENTRY glPopMatrix(void)
7007{
7008 TRACE("()");
7009
7010 gl::Context *context = gl::getContext();
7011
7012 if(context)
7013 {
7014 if(context->getListIndex() != 0)
7015 {
7016 return context->listCommand(gl::newCommand(glPopMatrix));
7017 }
7018
7019 context->popMatrix();
7020 }
7021}
7022
7023void APIENTRY glPopName(void)
7024{
7025 UNIMPLEMENTED();
7026}
7027
7028void APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities)
7029{
7030 UNIMPLEMENTED();
7031}
7032
7033void APIENTRY glPushAttrib(GLbitfield mask)
7034{
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007035 UNIMPLEMENTED();
Nicolas Capensa9b49372015-01-30 00:33:26 -05007036}
7037
7038void APIENTRY glPushClientAttrib(GLbitfield mask)
7039{
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007040 UNIMPLEMENTED();
Nicolas Capensa9b49372015-01-30 00:33:26 -05007041}
7042
7043void APIENTRY glPushMatrix(void)
7044{
7045 TRACE("()");
7046
7047 gl::Context *context = gl::getContext();
7048
7049 if(context)
7050 {
7051 if(context->getListIndex() != 0)
7052 {
7053 return context->listCommand(gl::newCommand(glPushMatrix));
7054 }
7055
7056 context->pushMatrix();
7057 }
7058}
7059
7060void APIENTRY glPushName(GLuint name)
7061{
7062 UNIMPLEMENTED();
7063}
7064
7065void APIENTRY glRasterPos2d(GLdouble x, GLdouble y)
7066{
7067 UNIMPLEMENTED();
7068}
7069
7070void APIENTRY glRasterPos2dv(const GLdouble *v)
7071{
7072 UNIMPLEMENTED();
7073}
7074
7075void APIENTRY glRasterPos2f(GLfloat x, GLfloat y)
7076{
7077 UNIMPLEMENTED();
7078}
7079
7080void APIENTRY glRasterPos2fv(const GLfloat *v)
7081{
7082 UNIMPLEMENTED();
7083}
7084
7085void APIENTRY glRasterPos2i(GLint x, GLint y)
7086{
7087 UNIMPLEMENTED();
7088}
7089
7090void APIENTRY glRasterPos2iv(const GLint *v)
7091{
7092 UNIMPLEMENTED();
7093}
7094
7095void APIENTRY glRasterPos2s(GLshort x, GLshort y)
7096{
7097 UNIMPLEMENTED();
7098}
7099
7100void APIENTRY glRasterPos2sv(const GLshort *v)
7101{
7102 UNIMPLEMENTED();
7103}
7104
7105void APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
7106{
7107 UNIMPLEMENTED();
7108}
7109
7110void APIENTRY glRasterPos3dv(const GLdouble *v)
7111{
7112 UNIMPLEMENTED();
7113}
7114
7115void APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
7116{
7117 UNIMPLEMENTED();
7118}
7119
7120void APIENTRY glRasterPos3fv(const GLfloat *v)
7121{
7122 UNIMPLEMENTED();
7123}
7124
7125void APIENTRY glRasterPos3i(GLint x, GLint y, GLint z)
7126{
7127 UNIMPLEMENTED();
7128}
7129
7130void APIENTRY glRasterPos3iv(const GLint *v)
7131{
7132 UNIMPLEMENTED();
7133}
7134
7135void APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z)
7136{
7137 UNIMPLEMENTED();
7138}
7139
7140void APIENTRY glRasterPos3sv(const GLshort *v)
7141{
7142 UNIMPLEMENTED();
7143}
7144
7145void APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
7146{
7147 UNIMPLEMENTED();
7148}
7149
7150void APIENTRY glRasterPos4dv(const GLdouble *v)
7151{
7152 UNIMPLEMENTED();
7153}
7154
7155void APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
7156{
7157 UNIMPLEMENTED();
7158}
7159
7160void APIENTRY glRasterPos4fv(const GLfloat *v)
7161{
7162 UNIMPLEMENTED();
7163}
7164
7165void APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w)
7166{
7167 UNIMPLEMENTED();
7168}
7169
7170void APIENTRY glRasterPos4iv(const GLint *v)
7171{
7172 UNIMPLEMENTED();
7173}
7174
7175void APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
7176{
7177 UNIMPLEMENTED();
7178}
7179
7180void APIENTRY glRasterPos4sv(const GLshort *v)
7181{
7182 UNIMPLEMENTED();
7183}
7184
7185void APIENTRY glReadBuffer(GLenum mode)
7186{
7187 UNIMPLEMENTED();
7188}
7189
7190void APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
7191{
7192 UNIMPLEMENTED();
7193}
7194
7195void APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2)
7196{
7197 UNIMPLEMENTED();
7198}
7199
7200void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
7201{
7202 UNIMPLEMENTED();
7203}
7204
7205void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2)
7206{
7207 UNIMPLEMENTED();
7208}
7209
7210void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2)
7211{
7212 UNIMPLEMENTED();
7213}
7214
7215void APIENTRY glRectiv(const GLint *v1, const GLint *v2)
7216{
7217 UNIMPLEMENTED();
7218}
7219
7220void APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
7221{
7222 UNIMPLEMENTED();
7223}
7224
7225void APIENTRY glRectsv(const GLshort *v1, const GLshort *v2)
7226{
7227 UNIMPLEMENTED();
7228}
7229
7230GLint APIENTRY glRenderMode(GLenum mode)
7231{
7232 UNIMPLEMENTED();
7233 return 0;
7234}
7235
7236void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
7237{
7238 UNIMPLEMENTED();
7239}
7240
7241void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
7242{
7243 TRACE("(*)");
7244
7245 gl::Context *context = gl::getContext();
7246
7247 if(context)
7248 {
7249 if(context->getListIndex() != 0)
7250 {
7251 UNIMPLEMENTED();
7252 }
7253
7254 context->rotate(angle, x, y, z);
7255 }
7256}
7257
7258void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)
7259{
7260 UNIMPLEMENTED();
7261}
7262
7263void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
7264{
7265 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7266
7267 gl::Context *context = gl::getContext();
7268
7269 if(context)
7270 {
7271 if(context->getListIndex() != 0)
7272 {
7273 return context->listCommand(gl::newCommand(glScalef, x, y, z));
7274 }
7275
7276 context->scale(x, y, z);
7277 }
7278}
7279
7280void APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer)
7281{
7282 UNIMPLEMENTED();
7283}
7284
7285void APIENTRY glShadeModel(GLenum mode)
7286{
7287 TRACE("(*)");
7288
7289 gl::Context *context = gl::getContext();
7290
7291 if(context)
7292 {
7293 if(context->getListIndex() != 0)
7294 {
7295 UNIMPLEMENTED();
7296 }
7297
7298 context->setShadeModel(mode);
7299 }
7300}
7301
7302void APIENTRY glTexCoord1d(GLdouble s)
7303{
7304 UNIMPLEMENTED();
7305}
7306
7307void APIENTRY glTexCoord1dv(const GLdouble *v)
7308{
7309 UNIMPLEMENTED();
7310}
7311
7312void APIENTRY glTexCoord1f(GLfloat s)
7313{
7314 UNIMPLEMENTED();
7315}
7316
7317void APIENTRY glTexCoord1fv(const GLfloat *v)
7318{
7319 UNIMPLEMENTED();
7320}
7321
7322void APIENTRY glTexCoord1i(GLint s)
7323{
7324 UNIMPLEMENTED();
7325}
7326
7327void APIENTRY glTexCoord1iv(const GLint *v)
7328{
7329 UNIMPLEMENTED();
7330}
7331
7332void APIENTRY glTexCoord1s(GLshort s)
7333{
7334 UNIMPLEMENTED();
7335}
7336
7337void APIENTRY glTexCoord1sv(const GLshort *v)
7338{
7339 UNIMPLEMENTED();
7340}
7341
7342void APIENTRY glTexCoord2d(GLdouble s, GLdouble t)
7343{
7344 UNIMPLEMENTED();
7345}
7346
7347void APIENTRY glTexCoord2dv(const GLdouble *v)
7348{
7349 UNIMPLEMENTED();
7350}
7351
7352void APIENTRY glTexCoord2f(GLfloat s, GLfloat t)
7353{
7354 TRACE("(GLfloat s = %f, GLfloat t = %f)", s, t);
7355
7356 gl::Context *context = gl::getContext();
7357
7358 if(context)
7359 {
7360 if(context->getListIndex() != 0)
7361 {
7362 UNIMPLEMENTED();
7363 }
7364
7365 //context->texCoord(s, t, 0.0f, 1.0f);
7366 unsigned int texture = context->getActiveTexture();
7367 context->setVertexAttrib(sw::TexCoord0/* + texture*/, s, t, 0.0f, 1.0f);
7368 }
7369}
7370
7371void APIENTRY glTexCoord2fv(const GLfloat *v)
7372{
7373 UNIMPLEMENTED();
7374}
7375
7376void APIENTRY glTexCoord2i(GLint s, GLint t)
7377{
7378 UNIMPLEMENTED();
7379}
7380
7381void APIENTRY glTexCoord2iv(const GLint *v)
7382{
7383 UNIMPLEMENTED();
7384}
7385
7386void APIENTRY glTexCoord2s(GLshort s, GLshort t)
7387{
7388 UNIMPLEMENTED();
7389}
7390
7391void APIENTRY glTexCoord2sv(const GLshort *v)
7392{
7393 UNIMPLEMENTED();
7394}
7395
7396void APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
7397{
7398 UNIMPLEMENTED();
7399}
7400
7401void APIENTRY glTexCoord3dv(const GLdouble *v)
7402{
7403 UNIMPLEMENTED();
7404}
7405
7406void APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
7407{
7408 UNIMPLEMENTED();
7409}
7410
7411void APIENTRY glTexCoord3fv(const GLfloat *v)
7412{
7413 UNIMPLEMENTED();
7414}
7415
7416void APIENTRY glTexCoord3i(GLint s, GLint t, GLint r)
7417{
7418 UNIMPLEMENTED();
7419}
7420
7421void APIENTRY glTexCoord3iv(const GLint *v)
7422{
7423 UNIMPLEMENTED();
7424}
7425
7426void APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r)
7427{
7428 UNIMPLEMENTED();
7429}
7430
7431void APIENTRY glTexCoord3sv(const GLshort *v)
7432{
7433 UNIMPLEMENTED();
7434}
7435
7436void APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
7437{
7438 UNIMPLEMENTED();
7439}
7440
7441void APIENTRY glTexCoord4dv(const GLdouble *v)
7442{
7443 UNIMPLEMENTED();
7444}
7445
7446void APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
7447{
7448 UNIMPLEMENTED();
7449}
7450
7451void APIENTRY glTexCoord4fv(const GLfloat *v)
7452{
7453 UNIMPLEMENTED();
7454}
7455
7456void APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q)
7457{
7458 UNIMPLEMENTED();
7459}
7460
7461void APIENTRY glTexCoord4iv(const GLint *v)
7462{
7463 UNIMPLEMENTED();
7464}
7465
7466void APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
7467{
7468 UNIMPLEMENTED();
7469}
7470
7471void APIENTRY glTexCoord4sv(const GLshort *v)
7472{
7473 UNIMPLEMENTED();
7474}
7475
7476void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
7477{
7478 TRACE("(*)");
7479
7480 gl::Context *context = gl::getContext();
7481
7482 if(context)
7483 {
7484 GLenum texture = context->getClientActiveTexture();
7485
7486 glVertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
7487 }
7488}
7489
7490void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
7491{
7492 UNIMPLEMENTED();
7493}
7494
7495void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
7496{
7497 UNIMPLEMENTED();
7498}
7499
7500void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
7501{
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007502 UNIMPLEMENTED();
Nicolas Capensa9b49372015-01-30 00:33:26 -05007503}
7504
7505void APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
7506{
7507 UNIMPLEMENTED();
7508}
7509
7510void APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param)
7511{
7512 UNIMPLEMENTED();
7513}
7514
7515void APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
7516{
7517 UNIMPLEMENTED();
7518}
7519
7520void APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param)
7521{
7522 UNIMPLEMENTED();
7523}
7524
7525void APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
7526{
7527 UNIMPLEMENTED();
7528}
7529
7530void APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param)
7531{
7532 UNIMPLEMENTED();
7533}
7534
7535void APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params)
7536{
7537 UNIMPLEMENTED();
7538}
7539
7540void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
7541{
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007542 UNIMPLEMENTED();
Nicolas Capensa9b49372015-01-30 00:33:26 -05007543}
7544
7545void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
7546{
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007547 UNIMPLEMENTED();
Nicolas Capensa9b49372015-01-30 00:33:26 -05007548}
7549
7550void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)
7551{
7552 TRACE("(*)");
7553
7554 gl::Context *context = gl::getContext();
7555
7556 if(context)
7557 {
7558 if(context->getListIndex() != 0)
7559 {
7560 return context->listCommand(gl::newCommand(glTranslated, x, y, z));
7561 }
7562
7563 context->translate(x, y, z); // FIXME
7564 }
7565}
7566
7567void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
7568{
7569 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7570
7571 gl::Context *context = gl::getContext();
7572
7573 if(context)
7574 {
7575 if(context->getListIndex() != 0)
7576 {
7577 return context->listCommand(gl::newCommand(glTranslatef, x, y, z));
7578 }
7579
7580 context->translate(x, y, z);
7581 }
7582}
7583
7584void APIENTRY glVertex2d(GLdouble x, GLdouble y)
7585{
7586 UNIMPLEMENTED();
7587}
7588
7589void APIENTRY glVertex2dv(const GLdouble *v)
7590{
7591 UNIMPLEMENTED();
7592}
7593
7594void APIENTRY glVertex2f(GLfloat x, GLfloat y)
7595{
7596 UNIMPLEMENTED();
7597}
7598
7599void APIENTRY glVertex2fv(const GLfloat *v)
7600{
7601 UNIMPLEMENTED();
7602}
7603
7604void APIENTRY glVertex2i(GLint x, GLint y)
7605{
7606 UNIMPLEMENTED();
7607}
7608
7609void APIENTRY glVertex2iv(const GLint *v)
7610{
7611 UNIMPLEMENTED();
7612}
7613
7614void APIENTRY glVertex2s(GLshort x, GLshort y)
7615{
7616 UNIMPLEMENTED();
7617}
7618
7619void APIENTRY glVertex2sv(const GLshort *v)
7620{
7621 UNIMPLEMENTED();
7622}
7623
7624void APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
7625{
7626 UNIMPLEMENTED();
7627}
7628
7629void APIENTRY glVertex3dv(const GLdouble *v)
7630{
7631 UNIMPLEMENTED();
7632}
7633
7634void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
7635{
7636 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7637
7638 gl::Context *context = gl::getContext();
7639
7640 if(context)
7641 {
7642 if(context->getListIndex() != 0)
7643 {
7644 UNIMPLEMENTED();
7645 }
7646
7647 context->position(x, y, z, 1.0f);
7648 }
7649}
7650
7651void APIENTRY glVertex3fv(const GLfloat *v)
7652{
7653 UNIMPLEMENTED();
7654}
7655
7656void APIENTRY glVertex3i(GLint x, GLint y, GLint z)
7657{
7658 UNIMPLEMENTED();
7659}
7660
7661void APIENTRY glVertex3iv(const GLint *v)
7662{
7663 UNIMPLEMENTED();
7664}
7665
7666void APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z)
7667{
7668 UNIMPLEMENTED();
7669}
7670
7671void APIENTRY glVertex3sv(const GLshort *v)
7672{
7673 UNIMPLEMENTED();
7674}
7675
7676void APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
7677{
7678 UNIMPLEMENTED();
7679}
7680
7681void APIENTRY glVertex4dv(const GLdouble *v)
7682{
7683 UNIMPLEMENTED();
7684}
7685
7686void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
7687{
7688 UNIMPLEMENTED();
7689}
7690
7691void APIENTRY glVertex4fv(const GLfloat *v)
7692{
7693 UNIMPLEMENTED();
7694}
7695
7696void APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w)
7697{
7698 UNIMPLEMENTED();
7699}
7700
7701void APIENTRY glVertex4iv(const GLint *v)
7702{
7703 UNIMPLEMENTED();
7704}
7705
7706void APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
7707{
7708 UNIMPLEMENTED();
7709}
7710
7711void APIENTRY glVertex4sv(const GLshort *v)
7712{
7713 UNIMPLEMENTED();
7714}
7715
7716void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
7717{
Nicolas Capens4be33702015-04-28 15:13:30 -07007718 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
Nicolas Capensa9b49372015-01-30 00:33:26 -05007719
7720 glVertexAttribPointer(sw::Position, size, type, false, stride, pointer);
7721}
7722
7723void APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) {UNIMPLEMENTED();}
7724void APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}
7725void APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}
7726void APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
7727
7728void APIENTRY glClientActiveTexture(GLenum texture)
7729{
7730 TRACE("(GLenum texture = 0x%X)", texture);
7731
7732 switch(texture)
7733 {
7734 case GL_TEXTURE0:
7735 case GL_TEXTURE1:
7736 break;
7737 default:
7738 UNIMPLEMENTED();
7739 UNREACHABLE();
7740 }
7741
7742 gl::Context *context = gl::getContext();
7743
7744 if(context)
7745 {
7746 context->clientActiveTexture(texture);
7747 }
7748}
7749
7750void APIENTRY glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7751void APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7752void APIENTRY glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7753void APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7754void APIENTRY glGetCompressedTexImage(GLenum target, GLint level, void *img) {UNIMPLEMENTED();}
7755void APIENTRY glMultiTexCoord1f(GLenum target, GLfloat s) {UNIMPLEMENTED();}
7756void APIENTRY glMultiTexCoord1d(GLenum target, GLdouble s) {UNIMPLEMENTED();}
7757
7758void APIENTRY glMultiTexCoord2f(GLenum texture, GLfloat s, GLfloat t)
7759{
7760 TRACE("(GLenum texture = 0x%X, GLfloat s = %f, GLfloat t = %f)", texture, s, t);
7761
7762 gl::Context *context = gl::getContext();
7763
7764 if(context)
7765 {
7766 if(context->getListIndex() != 0)
7767 {
7768 UNIMPLEMENTED();
7769 }
7770
7771 //context->texCoord(s, t, 0.0f, 1.0f);
7772 context->setVertexAttrib(sw::TexCoord0 + (texture - GL_TEXTURE0), s, t, 0.0f, 1.0f);
7773 }
7774}
7775
7776void APIENTRY glMultiTexCoord2d(GLenum target, GLdouble s, GLdouble t) {UNIMPLEMENTED();}
7777void APIENTRY glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {UNIMPLEMENTED();}
7778void APIENTRY glMultiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r) {UNIMPLEMENTED();}
7779void APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {UNIMPLEMENTED();}
7780void APIENTRY glMultiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) {UNIMPLEMENTED();}
7781void APIENTRY glLoadTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
7782void APIENTRY glLoadTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
7783void APIENTRY glMultTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
7784void APIENTRY glMultTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
7785void APIENTRY glFogCoordf(GLfloat coord) {UNIMPLEMENTED();}
7786void APIENTRY glFogCoordd(GLdouble coord) {UNIMPLEMENTED();}
7787void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
7788void APIENTRY glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) {UNIMPLEMENTED();}
7789void APIENTRY glPointParameteri(GLenum pname, GLint param) {UNIMPLEMENTED();}
7790void APIENTRY glPointParameterf(GLenum pname, GLfloat param) {UNIMPLEMENTED();}
7791void APIENTRY glPointParameteriv(GLenum pname, const GLint *params) {UNIMPLEMENTED();}
7792void APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params) {UNIMPLEMENTED();}
7793void APIENTRY glSecondaryColor3b(GLbyte red, GLbyte green, GLbyte blue) {UNIMPLEMENTED();}
7794void APIENTRY glSecondaryColor3f(GLfloat red, GLfloat green, GLfloat blue) {UNIMPLEMENTED();}
7795void APIENTRY glSecondaryColor3d(GLdouble red, GLdouble green, GLdouble blue) {UNIMPLEMENTED();}
7796void APIENTRY glSecondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue) {UNIMPLEMENTED();}
7797void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
7798void APIENTRY glWindowPos2f(GLfloat x, GLfloat y) {UNIMPLEMENTED();}
7799void APIENTRY glWindowPos2d(GLdouble x, GLdouble y) {UNIMPLEMENTED();}
7800void APIENTRY glWindowPos2i(GLint x, GLint y) {UNIMPLEMENTED();}
7801void APIENTRY glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) {UNIMPLEMENTED();}
7802void APIENTRY glWindowPos3d(GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
7803void APIENTRY glWindowPos3i(GLint x, GLint y, GLint z) {UNIMPLEMENTED();}
7804void APIENTRY glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data) {UNIMPLEMENTED();}
7805void *APIENTRY glMapBuffer(GLenum target, GLenum access) {UNIMPLEMENTED(); return 0;}
7806GLboolean APIENTRY glUnmapBuffer(GLenum target) {UNIMPLEMENTED(); return GL_FALSE;}
7807void APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params) {UNIMPLEMENTED();}
7808void APIENTRY glGenQueries(GLsizei n, GLuint *ids) {UNIMPLEMENTED();}
7809void APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids) {UNIMPLEMENTED();}
7810GLboolean APIENTRY glIsQuery(GLuint id) {UNIMPLEMENTED(); return 0;}
7811void APIENTRY glBeginQuery(GLenum target, GLuint id) {UNIMPLEMENTED();}
7812void APIENTRY glEndQuery(GLenum target) {UNIMPLEMENTED();}
7813void APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params) {UNIMPLEMENTED();}
7814void APIENTRY glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) {UNIMPLEMENTED();}
7815void APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) {UNIMPLEMENTED();}
7816void APIENTRY glVertexAttrib1s(GLuint index, GLshort x) {UNIMPLEMENTED();}
7817void APIENTRY glVertexAttrib1d(GLuint index, GLdouble x) {UNIMPLEMENTED();}
7818void APIENTRY glVertexAttrib2s(GLuint index, GLshort x, GLshort y) {UNIMPLEMENTED();}
7819void APIENTRY glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y) {UNIMPLEMENTED();}
7820void APIENTRY glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z) {UNIMPLEMENTED();}
7821void APIENTRY glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
7822void APIENTRY glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) {UNIMPLEMENTED();}
7823void APIENTRY glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {UNIMPLEMENTED();}
7824void APIENTRY glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {UNIMPLEMENTED();}
7825void APIENTRY glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {UNIMPLEMENTED();}
7826void APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs) {UNIMPLEMENTED();}
7827void APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7828void APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7829void APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7830void APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7831void APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7832void APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7833
7834void APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {UNIMPLEMENTED();}
7835void APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
7836void APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {UNIMPLEMENTED();}
7837
7838BOOL WINAPI wglSwapIntervalEXT(int interval)
7839{
7840 gl::Surface *drawSurface = static_cast<gl::Surface*>(gl::getCurrentDrawSurface());
7841
7842 if(drawSurface)
7843 {
7844 drawSurface->setSwapInterval(interval);
7845 return TRUE;
7846 }
7847
7848 SetLastError(ERROR_DC_NOT_FOUND);
7849 return FALSE;
7850}
7851
7852int WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)
7853{
7854 TRACE("(*)");
7855
7856 return 1;
7857}
7858
7859BOOL WINAPI wglCopyContext(HGLRC, HGLRC, UINT)
7860{
7861 UNIMPLEMENTED();
7862 return FALSE;
7863}
7864
7865HGLRC WINAPI wglCreateContext(HDC hdc)
7866{
7867 TRACE("(*)");
7868
7869 gl::Display *display = gl::Display::getDisplay(hdc);
7870 display->initialize();
7871
7872 gl::Context *context = display->createContext(nullptr);
7873
7874 return (HGLRC)context;
7875}
7876
7877HGLRC WINAPI wglCreateLayerContext(HDC, int)
7878{
7879 UNIMPLEMENTED();
7880 return 0;
7881}
7882
7883BOOL WINAPI wglDeleteContext(HGLRC context)
7884{
7885 gl::Display *display = gl::getDisplay();
7886
7887 if(display && context)
7888 {
7889 display->destroyContext(reinterpret_cast<gl::Context*>(context));
7890
7891 return TRUE;
7892 }
7893
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007894 return FALSE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05007895}
7896
7897BOOL WINAPI wglDescribeLayerPlane(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR)
7898{
7899 UNIMPLEMENTED();
7900 return FALSE;
7901}
7902
7903int WINAPI wglDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
7904{
7905 TRACE("(*)");
7906
7907 ASSERT(nBytes == sizeof(PIXELFORMATDESCRIPTOR)); // FIXME
7908
7909 ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
7910 ppfd->nVersion = 1;
7911 ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
7912 ppfd->iPixelType = PFD_TYPE_RGBA;
7913 ppfd->cColorBits = 32;
7914 ppfd->cRedBits = 8;
7915 ppfd->cRedShift = 16;
7916 ppfd->cGreenBits = 8;
7917 ppfd->cGreenShift = 8;
7918 ppfd->cBlueBits = 8;
7919 ppfd->cBlueShift = 0;
7920 ppfd->cAlphaBits = 0;
7921 ppfd->cAlphaShift = 24;
7922 ppfd->cAccumBits = 0;
7923 ppfd->cAccumRedBits = 0;
7924 ppfd->cAccumGreenBits = 0;
7925 ppfd->cAccumBlueBits = 0;
7926 ppfd->cAccumAlphaBits = 0;
7927 ppfd->cDepthBits = 24;
7928 ppfd->cStencilBits = 0;
7929 ppfd->cAuxBuffers = 0;
7930 ppfd->iLayerType = 0;
7931 ppfd->bReserved = 0;
7932 ppfd->dwLayerMask = 0;
7933 ppfd->dwVisibleMask = 0;
7934 ppfd->dwDamageMask = 0;
7935
7936 return 1;
7937}
7938
7939HGLRC WINAPI wglGetCurrentContext(VOID)
7940{
7941 TRACE("(*)");
7942 return (HGLRC)gl::getContext();
7943}
7944
7945HDC WINAPI wglGetCurrentDC(VOID)
7946{
7947 TRACE("(*)");
7948 gl::Display *display = gl::getDisplay();
7949 return display ? display->getNativeDisplay() : 0;
7950}
7951
7952void WINAPI wglGetDefaultProcAddress()
7953{
7954 UNIMPLEMENTED();
7955}
7956
7957int WINAPI wglGetLayerPaletteEntries(HDC, int, int, int, COLORREF*)
7958{
7959 UNIMPLEMENTED();
7960 return 0;
7961}
7962
7963void WINAPI wglGetPixelFormat()
7964{
7965 UNIMPLEMENTED();
7966}
7967
7968const char *WINAPI wglGetExtensionsStringARB(HDC hdc)
7969{
7970 TRACE("(*)");
7971
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007972 return "GL_ARB_framebuffer_object "
7973 "WGL_EXT_extensions_string "
7974 "WGL_EXT_swap_control";
Nicolas Capensa9b49372015-01-30 00:33:26 -05007975}
7976
7977const char *WINAPI wglGetExtensionsStringEXT()
7978{
7979 TRACE("(*)");
7980 return wglGetExtensionsStringARB(0);
7981}
7982
7983PROC WINAPI wglGetProcAddress(LPCSTR lpszProc)
7984{
7985 TRACE("(LPCSTR lpszProc = \"%s\")", lpszProc);
7986
Nicolas Capens264f1522015-01-09 17:21:17 -05007987 struct Extension
7988 {
7989 const char *name;
Nicolas Capensa9b49372015-01-30 00:33:26 -05007990 PROC address;
Nicolas Capens264f1522015-01-09 17:21:17 -05007991 };
7992
7993 static const Extension glExtensions[] =
7994 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05007995 #define EXT(function) {#function, (PROC)function}
7996
7997 // Core 2.1
7998 EXT(glDrawRangeElements),
7999 EXT(glTexImage3D),
8000 EXT(glTexSubImage3D),
8001 EXT(glCopyTexSubImage3D),
8002 EXT(glActiveTexture),
8003 EXT(glClientActiveTexture),
8004 EXT(glCompressedTexImage1D),
8005 EXT(glCompressedTexImage2D),
8006 EXT(glCompressedTexImage3D),
8007 EXT(glCompressedTexSubImage1D),
8008 EXT(glCompressedTexSubImage2D),
8009 EXT(glCompressedTexSubImage3D),
8010 EXT(glGetCompressedTexImage),
8011 EXT(glMultiTexCoord1f),
8012 EXT(glMultiTexCoord1d),
8013 EXT(glMultiTexCoord2f),
8014 EXT(glMultiTexCoord2d),
8015 EXT(glMultiTexCoord3f),
8016 EXT(glMultiTexCoord3d),
8017 EXT(glMultiTexCoord4f),
8018 EXT(glMultiTexCoord4d),
8019 EXT(glLoadTransposeMatrixf),
8020 EXT(glLoadTransposeMatrixd),
8021 EXT(glMultTransposeMatrixf),
8022 EXT(glMultTransposeMatrixd),
8023 EXT(glSampleCoverage),
8024 EXT(glBlendEquation),
8025 EXT(glBlendColor),
8026 EXT(glFogCoordf),
8027 EXT(glFogCoordd),
8028 EXT(glFogCoordPointer),
8029 EXT(glMultiDrawArrays),
8030 EXT(glPointParameteri),
8031 EXT(glPointParameterf),
8032 EXT(glPointParameteriv),
8033 EXT(glPointParameterfv),
8034 EXT(glSecondaryColor3b),
8035 EXT(glSecondaryColor3f),
8036 EXT(glSecondaryColor3d),
8037 EXT(glSecondaryColor3ub),
8038 EXT(glSecondaryColorPointer),
8039 EXT(glBlendFuncSeparate),
8040 EXT(glWindowPos2f),
8041 EXT(glWindowPos2d),
8042 EXT(glWindowPos2i),
8043 EXT(glWindowPos3f),
8044 EXT(glWindowPos3d),
8045 EXT(glWindowPos3i),
8046 EXT(glBindBuffer),
8047 EXT(glDeleteBuffers),
8048 EXT(glGenBuffers),
8049 EXT(glIsBuffer),
8050 EXT(glBufferData),
8051 EXT(glBufferSubData),
8052 EXT(glGetBufferSubData),
8053 EXT(glMapBuffer),
8054 EXT(glUnmapBuffer),
8055 EXT(glGetBufferParameteriv),
8056 EXT(glGetBufferPointerv),
8057 EXT(glGenQueries),
8058 EXT(glDeleteQueries),
8059 EXT(glIsQuery),
8060 EXT(glBeginQuery),
8061 EXT(glEndQuery),
8062 EXT(glGetQueryiv),
8063 EXT(glGetQueryObjectiv),
8064 EXT(glGetQueryObjectuiv),
8065 EXT(glShaderSource),
8066 EXT(glCreateShader),
8067 EXT(glIsShader),
8068 EXT(glCompileShader),
8069 EXT(glDeleteShader),
8070 EXT(glCreateProgram),
8071 EXT(glIsProgram),
8072 EXT(glAttachShader),
8073 EXT(glDetachShader),
8074 EXT(glLinkProgram),
8075 EXT(glUseProgram),
8076 EXT(glValidateProgram),
8077 EXT(glDeleteProgram),
8078 EXT(glUniform1f),
8079 EXT(glUniform2f),
8080 EXT(glUniform3f),
8081 EXT(glUniform4f),
8082 EXT(glUniform1i),
8083 EXT(glUniform2i),
8084 EXT(glUniform3i),
8085 EXT(glUniform4i),
8086 EXT(glUniform1fv),
8087 EXT(glUniform2fv),
8088 EXT(glUniform3fv),
8089 EXT(glUniform4fv),
8090 EXT(glUniform1iv),
8091 EXT(glUniform2iv),
8092 EXT(glUniform3iv),
8093 EXT(glUniform4iv),
8094 EXT(glUniformMatrix2fv),
8095 EXT(glUniformMatrix3fv),
8096 EXT(glUniformMatrix4fv),
8097 EXT(glGetShaderiv),
8098 EXT(glGetProgramiv),
8099 EXT(glGetShaderInfoLog),
8100 EXT(glGetProgramInfoLog),
8101 EXT(glGetAttachedShaders),
8102 EXT(glGetUniformLocation),
8103 EXT(glGetActiveUniform),
8104 EXT(glGetUniformfv),
8105 EXT(glGetUniformiv),
8106 EXT(glGetShaderSource),
8107 EXT(glVertexAttrib1s),
8108 EXT(glVertexAttrib1f),
8109 EXT(glVertexAttrib1d),
8110 EXT(glVertexAttrib2s),
8111 EXT(glVertexAttrib2f),
8112 EXT(glVertexAttrib2d),
8113 EXT(glVertexAttrib3s),
8114 EXT(glVertexAttrib3f),
8115 EXT(glVertexAttrib3d),
8116 EXT(glVertexAttrib4s),
8117 EXT(glVertexAttrib4f),
8118 EXT(glVertexAttrib4d),
8119 EXT(glVertexAttrib4Nub),
8120 EXT(glVertexAttribPointer),
8121 EXT(glEnableVertexAttribArray),
8122 EXT(glDisableVertexAttribArray),
8123 EXT(glGetVertexAttribfv),
8124 EXT(glGetVertexAttribdv),
8125 EXT(glGetVertexAttribiv),
8126 EXT(glGetVertexAttribPointerv),
8127 EXT(glBindAttribLocation),
8128 EXT(glGetActiveAttrib),
8129 EXT(glGetAttribLocation),
8130 EXT(glDrawBuffers),
8131 EXT(glStencilOpSeparate),
8132 EXT(glStencilFuncSeparate),
8133 EXT(glStencilMaskSeparate),
8134 EXT(glBlendEquationSeparate),
8135 EXT(glUniformMatrix2x3fv),
8136 EXT(glUniformMatrix3x2fv),
8137 EXT(glUniformMatrix2x4fv),
8138 EXT(glUniformMatrix4x2fv),
8139 EXT(glUniformMatrix3x4fv),
8140 EXT(glUniformMatrix4x3fv),
8141 EXT(glGenFencesNV),
8142 EXT(glDeleteFencesNV),
8143 EXT(glSetFenceNV),
8144 EXT(glTestFenceNV),
8145 EXT(glFinishFenceNV),
8146 EXT(glIsFenceNV),
8147 EXT(glGetFenceivNV),
8148
8149 EXT(glIsRenderbuffer),
8150 EXT(glBindRenderbuffer),
8151 EXT(glDeleteRenderbuffers),
8152 EXT(glGenRenderbuffers),
8153 EXT(glRenderbufferStorage),
8154 EXT(glGetRenderbufferParameteriv),
8155 EXT(glIsFramebuffer),
8156 EXT(glBindFramebuffer),
8157 EXT(glDeleteFramebuffers),
8158 EXT(glGenFramebuffers),
8159 EXT(glCheckFramebufferStatus),
8160 EXT(glFramebufferTexture1D),
8161 EXT(glFramebufferTexture2D),
8162 EXT(glFramebufferTexture3D),
8163 EXT(glFramebufferRenderbuffer),
8164 EXT(glGetFramebufferAttachmentParameteriv),
8165 EXT(glGenerateMipmap),
8166 EXT(glReleaseShaderCompiler),
8167 EXT(glShaderBinary),
8168 EXT(glGetShaderPrecisionFormat),
8169 EXT(glDepthRangef),
8170 EXT(glClearDepthf),
Nicolas Capens264f1522015-01-09 17:21:17 -05008171
Nicolas Capensa9b49372015-01-30 00:33:26 -05008172 // ARB
8173 EXT(wglGetExtensionsStringARB),
8174 EXT(glIsRenderbuffer),
8175 EXT(glBindRenderbuffer),
8176 EXT(glDeleteRenderbuffers),
8177 EXT(glGenRenderbuffers),
8178 EXT(glRenderbufferStorage),
8179 EXT(glRenderbufferStorageMultisample),
8180 EXT(glGetRenderbufferParameteriv),
8181 EXT(glIsFramebuffer),
8182 EXT(glBindFramebuffer),
8183 EXT(glDeleteFramebuffers),
8184 EXT(glGenFramebuffers),
8185 EXT(glCheckFramebufferStatus),
8186 EXT(glFramebufferTexture1D),
8187 EXT(glFramebufferTexture2D),
8188 EXT(glFramebufferTexture3D),
8189 EXT(glFramebufferTextureLayer),
8190 EXT(glFramebufferRenderbuffer),
8191 EXT(glGetFramebufferAttachmentParameteriv),
8192 EXT(glBlitFramebuffer),
8193 EXT(glGenerateMipmap),
Nicolas Capens264f1522015-01-09 17:21:17 -05008194
Nicolas Capensa9b49372015-01-30 00:33:26 -05008195 // EXT
8196 EXT(wglSwapIntervalEXT),
8197 EXT(wglGetExtensionsStringEXT),
8198 #undef EXT
Nicolas Capens264f1522015-01-09 17:21:17 -05008199 };
8200
8201 for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
8202 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05008203 if(strcmp(lpszProc, glExtensions[ext].name) == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05008204 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05008205 return (PROC)glExtensions[ext].address;
Nicolas Capens264f1522015-01-09 17:21:17 -05008206 }
8207 }
8208
Nicolas Capensa9b49372015-01-30 00:33:26 -05008209 FARPROC proc = GetProcAddress(GetModuleHandle("opengl32.dll"), lpszProc); // FIXME?
8210
8211 if(proc)
8212 {
8213 return proc;
8214 }
8215
8216 TRACE("(LPCSTR lpszProc = \"%s\") NOT FOUND!!!", lpszProc);
8217
Maxime Grégoiredff6d002015-07-16 10:26:45 -04008218 return 0;
Nicolas Capens264f1522015-01-09 17:21:17 -05008219}
8220
Nicolas Capensa9b49372015-01-30 00:33:26 -05008221BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
8222{
8223 TRACE("(*)");
8224
8225 if(hdc && hglrc)
8226 {
8227 gl::Display *display = (gl::Display*)gl::Display::getDisplay(hdc);
8228 gl::makeCurrent((gl::Context*)hglrc, display, display->getPrimarySurface());
8229 gl::setCurrentDrawSurface(display->getPrimarySurface());
8230 gl::setCurrentDisplay(display);
8231 }
8232 else
8233 {
8234 gl::makeCurrent(0, 0, 0);
8235 }
8236
8237 return TRUE;
8238}
8239
8240BOOL WINAPI wglRealizeLayerPalette(HDC, int, BOOL)
8241{
8242 UNIMPLEMENTED();
8243 return FALSE;
8244}
8245
8246int WINAPI wglSetLayerPaletteEntries(HDC, int, int, int, CONST COLORREF*)
8247{
8248 UNIMPLEMENTED();
8249 return 0;
8250}
8251
8252BOOL WINAPI wglSetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
8253{
8254 TRACE("(*)");
8255 //UNIMPLEMENTED();
8256
8257 return TRUE;
8258}
8259
Maxime Grégoiredff6d002015-07-16 10:26:45 -04008260BOOL WINAPI wglShareLists(HGLRC, HGLRC)
Nicolas Capensa9b49372015-01-30 00:33:26 -05008261{
Maxime Grégoiredff6d002015-07-16 10:26:45 -04008262 UNIMPLEMENTED();
8263 return FALSE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008264}
8265
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008266BOOL WINAPI wglSwapBuffers(HDC hdc)
Nicolas Capensa9b49372015-01-30 00:33:26 -05008267{
8268 TRACE("(*)");
8269
8270 gl::Display *display = gl::getDisplay();
8271
8272 if(display)
8273 {
8274 display->getPrimarySurface()->swap();
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008275 return TRUE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008276 }
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008277
8278 return FALSE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008279}
8280
8281BOOL WINAPI wglSwapLayerBuffers(HDC, UINT)
8282{
8283 UNIMPLEMENTED();
8284 return FALSE;
8285}
8286
8287DWORD WINAPI wglSwapMultipleBuffers(UINT, CONST WGLSWAP*)
8288{
8289 UNIMPLEMENTED();
8290 return 0;
8291}
8292
8293BOOL WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD)
8294{
8295 UNIMPLEMENTED();
8296 return FALSE;
8297}
8298
8299BOOL WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD)
8300{
8301 UNIMPLEMENTED();
8302 return FALSE;
8303}
8304
8305BOOL WINAPI wglUseFontOutlinesA(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
8306{
8307 UNIMPLEMENTED();
8308 return FALSE;
8309}
8310
8311BOOL WINAPI wglUseFontOutlinesW(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
8312{
8313 UNIMPLEMENTED();
8314 return FALSE;
8315}
8316
8317void APIENTRY Register(const char *licenseKey)
Nicolas Capens264f1522015-01-09 17:21:17 -05008318{
8319 RegisterLicenseKey(licenseKey);
8320}
8321
8322}