blob: 9c2cae4f403458e1ba532a1a4bd1c0b0fc2923c8 [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
58 if(format != GL_NONE && format != texture->getFormat(target, level))
59 {
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 {
1655 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;
Nicolas Capensa9b49372015-01-30 00:33:26 -05001664 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:
3096 return (GLubyte*)"TransGaming Inc.";
3097 case GL_RENDERER:
3098 return (GLubyte*)"SwiftShader";
3099 case GL_VERSION:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003100 return (GLubyte*)"2.1 SwiftShader "VERSION_STRING;
Nicolas Capens264f1522015-01-09 17:21:17 -05003101 case GL_SHADING_LANGUAGE_VERSION:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003102 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*)
Nicolas Capensa9b49372015-01-30 00:33:26 -05003109 "GL_ARB_framebuffer_object "
Nicolas Capens264f1522015-01-09 17:21:17 -05003110 "GL_EXT_blend_minmax "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003111 "GL_EXT_depth_texture "
3112 "GL_EXT_depth_texture_cube_map "
3113 "GL_EXT_element_index_uint "
3114 "GL_EXT_packed_depth_stencil "
3115 "GL_EXT_rgb8_rgba8 "
3116 "GL_EXT_standard_derivatives "
3117 "GL_EXT_texture_float "
3118 "GL_EXT_texture_float_linear "
3119 "GL_EXT_texture_half_float "
3120 "GL_EXT_texture_half_float_linear "
3121 "GL_EXT_texture_npot "
Nicolas Capens264f1522015-01-09 17:21:17 -05003122 "GL_EXT_occlusion_query_boolean "
3123 "GL_EXT_read_format_bgra "
3124 #if (S3TC_SUPPORT)
3125 "GL_EXT_texture_compression_dxt1 "
3126 #endif
Nicolas Capensa9b49372015-01-30 00:33:26 -05003127 "GL_EXT_blend_func_separate "
3128 "GL_EXT_secondary_color "
Nicolas Capens264f1522015-01-09 17:21:17 -05003129 "GL_EXT_texture_filter_anisotropic "
3130 "GL_EXT_texture_format_BGRA8888 "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003131 "GL_EXT_framebuffer_blit "
3132 "GL_EXT_framebuffer_multisample "
Nicolas Capens264f1522015-01-09 17:21:17 -05003133 #if (S3TC_SUPPORT)
Nicolas Capensa9b49372015-01-30 00:33:26 -05003134 "GL_EXT_texture_compression_dxt3 "
3135 "GL_EXT_texture_compression_dxt5 "
Nicolas Capens264f1522015-01-09 17:21:17 -05003136 #endif
3137 "GL_NV_fence";
3138 default:
3139 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3140 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05003141
3142 return NULL;
Nicolas Capens264f1522015-01-09 17:21:17 -05003143}
3144
Nicolas Capensa9b49372015-01-30 00:33:26 -05003145void APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003146{
Nicolas Capens4be33702015-04-28 15:13:30 -07003147 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003148
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003149 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003150
3151 if(context)
3152 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003153 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05003154
3155 switch(target)
3156 {
3157 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003158 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05003159 break;
3160 case GL_TEXTURE_CUBE_MAP:
3161 texture = context->getTextureCubeMap();
3162 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003163 default:
3164 return error(GL_INVALID_ENUM);
3165 }
3166
3167 switch(pname)
3168 {
3169 case GL_TEXTURE_MAG_FILTER:
3170 *params = (GLfloat)texture->getMagFilter();
3171 break;
3172 case GL_TEXTURE_MIN_FILTER:
3173 *params = (GLfloat)texture->getMinFilter();
3174 break;
3175 case GL_TEXTURE_WRAP_S:
3176 *params = (GLfloat)texture->getWrapS();
3177 break;
3178 case GL_TEXTURE_WRAP_T:
3179 *params = (GLfloat)texture->getWrapT();
3180 break;
3181 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3182 *params = texture->getMaxAnisotropy();
3183 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003184 default:
3185 return error(GL_INVALID_ENUM);
3186 }
3187 }
3188}
3189
Nicolas Capensa9b49372015-01-30 00:33:26 -05003190void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003191{
Nicolas Capens4be33702015-04-28 15:13:30 -07003192 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003193
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003194 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003195
3196 if(context)
3197 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003198 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05003199
3200 switch(target)
3201 {
3202 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003203 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05003204 break;
3205 case GL_TEXTURE_CUBE_MAP:
3206 texture = context->getTextureCubeMap();
3207 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003208 default:
3209 return error(GL_INVALID_ENUM);
3210 }
3211
3212 switch(pname)
3213 {
3214 case GL_TEXTURE_MAG_FILTER:
3215 *params = texture->getMagFilter();
3216 break;
3217 case GL_TEXTURE_MIN_FILTER:
3218 *params = texture->getMinFilter();
3219 break;
3220 case GL_TEXTURE_WRAP_S:
3221 *params = texture->getWrapS();
3222 break;
3223 case GL_TEXTURE_WRAP_T:
3224 *params = texture->getWrapT();
3225 break;
3226 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3227 *params = (GLint)texture->getMaxAnisotropy();
3228 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003229 default:
3230 return error(GL_INVALID_ENUM);
3231 }
3232 }
3233}
3234
Nicolas Capensa9b49372015-01-30 00:33:26 -05003235void APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003236{
Nicolas Capens4be33702015-04-28 15:13:30 -07003237 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003238 program, location, bufSize, params);
3239
3240 if(bufSize < 0)
3241 {
3242 return error(GL_INVALID_VALUE);
3243 }
3244
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003245 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003246
3247 if(context)
3248 {
3249 if(program == 0)
3250 {
3251 return error(GL_INVALID_VALUE);
3252 }
3253
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003254 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003255
3256 if(!programObject || !programObject->isLinked())
3257 {
3258 return error(GL_INVALID_OPERATION);
3259 }
3260
3261 if(!programObject->getUniformfv(location, &bufSize, params))
3262 {
3263 return error(GL_INVALID_OPERATION);
3264 }
3265 }
3266}
3267
Nicolas Capensa9b49372015-01-30 00:33:26 -05003268void APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003269{
Nicolas Capens4be33702015-04-28 15:13:30 -07003270 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003271
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003272 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003273
3274 if(context)
3275 {
3276 if(program == 0)
3277 {
3278 return error(GL_INVALID_VALUE);
3279 }
3280
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003281 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003282
3283 if(!programObject || !programObject->isLinked())
3284 {
3285 return error(GL_INVALID_OPERATION);
3286 }
3287
3288 if(!programObject->getUniformfv(location, NULL, params))
3289 {
3290 return error(GL_INVALID_OPERATION);
3291 }
3292 }
3293}
3294
Nicolas Capensa9b49372015-01-30 00:33:26 -05003295void APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003296{
Nicolas Capens4be33702015-04-28 15:13:30 -07003297 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003298 program, location, bufSize, params);
3299
3300 if(bufSize < 0)
3301 {
3302 return error(GL_INVALID_VALUE);
3303 }
3304
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003305 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003306
3307 if(context)
3308 {
3309 if(program == 0)
3310 {
3311 return error(GL_INVALID_VALUE);
3312 }
3313
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003314 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003315
3316 if(!programObject || !programObject->isLinked())
3317 {
3318 return error(GL_INVALID_OPERATION);
3319 }
3320
3321 if(!programObject)
3322 {
3323 return error(GL_INVALID_OPERATION);
3324 }
3325
3326 if(!programObject->getUniformiv(location, &bufSize, params))
3327 {
3328 return error(GL_INVALID_OPERATION);
3329 }
3330 }
3331}
3332
Nicolas Capensa9b49372015-01-30 00:33:26 -05003333void APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003334{
Nicolas Capens4be33702015-04-28 15:13:30 -07003335 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003336
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003337 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003338
3339 if(context)
3340 {
3341 if(program == 0)
3342 {
3343 return error(GL_INVALID_VALUE);
3344 }
3345
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003346 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003347
3348 if(!programObject || !programObject->isLinked())
3349 {
3350 return error(GL_INVALID_OPERATION);
3351 }
3352
3353 if(!programObject)
3354 {
3355 return error(GL_INVALID_OPERATION);
3356 }
3357
3358 if(!programObject->getUniformiv(location, NULL, params))
3359 {
3360 return error(GL_INVALID_OPERATION);
3361 }
3362 }
3363}
3364
Nicolas Capensa9b49372015-01-30 00:33:26 -05003365int APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003366{
3367 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
3368
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003369 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003370
3371 if(strstr(name, "gl_") == name)
3372 {
3373 return -1;
3374 }
3375
3376 if(context)
3377 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003378 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003379
3380 if(!programObject)
3381 {
3382 if(context->getShader(program))
3383 {
3384 return error(GL_INVALID_OPERATION, -1);
3385 }
3386 else
3387 {
3388 return error(GL_INVALID_VALUE, -1);
3389 }
3390 }
3391
3392 if(!programObject->isLinked())
3393 {
3394 return error(GL_INVALID_OPERATION, -1);
3395 }
3396
3397 return programObject->getUniformLocation(name);
3398 }
3399
3400 return -1;
3401}
3402
Nicolas Capensa9b49372015-01-30 00:33:26 -05003403void APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003404{
Nicolas Capens4be33702015-04-28 15:13:30 -07003405 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003406
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003407 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003408
3409 if(context)
3410 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003411 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003412 {
3413 return error(GL_INVALID_VALUE);
3414 }
3415
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003416 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
Nicolas Capens264f1522015-01-09 17:21:17 -05003417
3418 switch(pname)
3419 {
3420 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3421 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3422 break;
3423 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3424 *params = (GLfloat)attribState.mSize;
3425 break;
3426 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3427 *params = (GLfloat)attribState.mStride;
3428 break;
3429 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3430 *params = (GLfloat)attribState.mType;
3431 break;
3432 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3433 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
3434 break;
3435 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003436 *params = (GLfloat)attribState.mBoundBuffer.name();
Nicolas Capens264f1522015-01-09 17:21:17 -05003437 break;
3438 case GL_CURRENT_VERTEX_ATTRIB:
3439 for(int i = 0; i < 4; ++i)
3440 {
3441 params[i] = attribState.mCurrentValue[i];
3442 }
3443 break;
3444 default: return error(GL_INVALID_ENUM);
3445 }
3446 }
3447}
3448
Nicolas Capensa9b49372015-01-30 00:33:26 -05003449void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003450{
Nicolas Capens4be33702015-04-28 15:13:30 -07003451 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003452
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003453 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003454
3455 if(context)
3456 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003457 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003458 {
3459 return error(GL_INVALID_VALUE);
3460 }
3461
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003462 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
Nicolas Capens264f1522015-01-09 17:21:17 -05003463
3464 switch(pname)
3465 {
3466 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3467 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3468 break;
3469 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3470 *params = attribState.mSize;
3471 break;
3472 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3473 *params = attribState.mStride;
3474 break;
3475 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3476 *params = attribState.mType;
3477 break;
3478 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3479 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
3480 break;
3481 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003482 *params = attribState.mBoundBuffer.name();
Nicolas Capens264f1522015-01-09 17:21:17 -05003483 break;
3484 case GL_CURRENT_VERTEX_ATTRIB:
3485 for(int i = 0; i < 4; ++i)
3486 {
3487 float currentValue = attribState.mCurrentValue[i];
3488 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3489 }
3490 break;
3491 default: return error(GL_INVALID_ENUM);
3492 }
3493 }
3494}
3495
Nicolas Capensa9b49372015-01-30 00:33:26 -05003496void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003497{
Nicolas Capens4be33702015-04-28 15:13:30 -07003498 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003499
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003500 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003501
3502 if(context)
3503 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003504 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003505 {
3506 return error(GL_INVALID_VALUE);
3507 }
3508
3509 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3510 {
3511 return error(GL_INVALID_ENUM);
3512 }
3513
3514 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
3515 }
3516}
3517
Nicolas Capensa9b49372015-01-30 00:33:26 -05003518void APIENTRY glHint(GLenum target, GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05003519{
3520 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
3521
3522 switch(mode)
3523 {
3524 case GL_FASTEST:
3525 case GL_NICEST:
3526 case GL_DONT_CARE:
3527 break;
3528 default:
3529 return error(GL_INVALID_ENUM);
3530 }
3531
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003532 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003533 switch(target)
3534 {
3535 case GL_GENERATE_MIPMAP_HINT:
3536 if(context) context->setGenerateMipmapHint(mode);
3537 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05003538 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
Nicolas Capens264f1522015-01-09 17:21:17 -05003539 if(context) context->setFragmentShaderDerivativeHint(mode);
3540 break;
3541 default:
3542 return error(GL_INVALID_ENUM);
3543 }
3544}
3545
Nicolas Capensa9b49372015-01-30 00:33:26 -05003546GLboolean APIENTRY glIsBuffer(GLuint buffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003547{
3548 TRACE("(GLuint buffer = %d)", buffer);
3549
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003550 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003551
3552 if(context && buffer)
3553 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003554 gl::Buffer *bufferObject = context->getBuffer(buffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003555
3556 if(bufferObject)
3557 {
3558 return GL_TRUE;
3559 }
3560 }
3561
3562 return GL_FALSE;
3563}
3564
Nicolas Capensa9b49372015-01-30 00:33:26 -05003565GLboolean APIENTRY glIsEnabled(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05003566{
3567 TRACE("(GLenum cap = 0x%X)", cap);
3568
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003569 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003570
3571 if(context)
3572 {
3573 switch(cap)
3574 {
3575 case GL_CULL_FACE: return context->isCullFaceEnabled();
3576 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3577 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3578 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3579 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3580 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3581 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3582 case GL_BLEND: return context->isBlendEnabled();
3583 case GL_DITHER: return context->isDitherEnabled();
3584 default:
3585 return error(GL_INVALID_ENUM, false);
3586 }
3587 }
3588
3589 return false;
3590}
3591
Nicolas Capensa9b49372015-01-30 00:33:26 -05003592GLboolean APIENTRY glIsFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05003593{
3594 TRACE("(GLuint fence = %d)", fence);
3595
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003596 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003597
3598 if(context)
3599 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003600 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05003601
3602 if(fenceObject == NULL)
3603 {
3604 return GL_FALSE;
3605 }
3606
3607 return fenceObject->isFence();
3608 }
3609
3610 return GL_FALSE;
3611}
3612
Nicolas Capensa9b49372015-01-30 00:33:26 -05003613GLboolean APIENTRY glIsFramebuffer(GLuint framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003614{
3615 TRACE("(GLuint framebuffer = %d)", framebuffer);
3616
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003617 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003618
3619 if(context && framebuffer)
3620 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003621 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003622
3623 if(framebufferObject)
3624 {
3625 return GL_TRUE;
3626 }
3627 }
3628
3629 return GL_FALSE;
3630}
3631
Nicolas Capensa9b49372015-01-30 00:33:26 -05003632GLboolean APIENTRY glIsProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05003633{
3634 TRACE("(GLuint program = %d)", program);
3635
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003636 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003637
3638 if(context && program)
3639 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003640 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003641
3642 if(programObject)
3643 {
3644 return GL_TRUE;
3645 }
3646 }
3647
3648 return GL_FALSE;
3649}
3650
Nicolas Capensa9b49372015-01-30 00:33:26 -05003651GLboolean APIENTRY glIsQueryEXT(GLuint name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003652{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003653 TRACE("(GLuint name = %d)", name);
Nicolas Capens264f1522015-01-09 17:21:17 -05003654
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003655 if(name == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05003656 {
3657 return GL_FALSE;
3658 }
3659
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003660 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003661
3662 if(context)
3663 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003664 gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
Nicolas Capens264f1522015-01-09 17:21:17 -05003665
3666 if(queryObject)
3667 {
3668 return GL_TRUE;
3669 }
3670 }
3671
3672 return GL_FALSE;
3673}
3674
Nicolas Capensa9b49372015-01-30 00:33:26 -05003675GLboolean APIENTRY glIsRenderbuffer(GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003676{
3677 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
3678
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003679 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003680
3681 if(context && renderbuffer)
3682 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003683 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003684
3685 if(renderbufferObject)
3686 {
3687 return GL_TRUE;
3688 }
3689 }
3690
3691 return GL_FALSE;
3692}
3693
Nicolas Capensa9b49372015-01-30 00:33:26 -05003694GLboolean APIENTRY glIsShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05003695{
3696 TRACE("(GLuint shader = %d)", shader);
3697
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003698 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003699
3700 if(context && shader)
3701 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003702 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003703
3704 if(shaderObject)
3705 {
3706 return GL_TRUE;
3707 }
3708 }
3709
3710 return GL_FALSE;
3711}
3712
Nicolas Capensa9b49372015-01-30 00:33:26 -05003713GLboolean APIENTRY glIsTexture(GLuint texture)
Nicolas Capens264f1522015-01-09 17:21:17 -05003714{
3715 TRACE("(GLuint texture = %d)", texture);
3716
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003717 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003718
3719 if(context && texture)
3720 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003721 gl::Texture *textureObject = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -05003722
3723 if(textureObject)
3724 {
3725 return GL_TRUE;
3726 }
3727 }
3728
3729 return GL_FALSE;
3730}
3731
Nicolas Capensa9b49372015-01-30 00:33:26 -05003732void APIENTRY glLineWidth(GLfloat width)
Nicolas Capens264f1522015-01-09 17:21:17 -05003733{
3734 TRACE("(GLfloat width = %f)", width);
3735
3736 if(width <= 0.0f)
3737 {
3738 return error(GL_INVALID_VALUE);
3739 }
3740
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003741 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003742
3743 if(context)
3744 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003745 if(context->getListIndex() != 0)
3746 {
3747 UNIMPLEMENTED();
3748 }
3749
Nicolas Capens264f1522015-01-09 17:21:17 -05003750 context->setLineWidth(width);
3751 }
3752}
3753
Nicolas Capensa9b49372015-01-30 00:33:26 -05003754void APIENTRY glLinkProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05003755{
3756 TRACE("(GLuint program = %d)", program);
3757
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003758 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003759
3760 if(context)
3761 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003762 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003763
3764 if(!programObject)
3765 {
3766 if(context->getShader(program))
3767 {
3768 return error(GL_INVALID_OPERATION);
3769 }
3770 else
3771 {
3772 return error(GL_INVALID_VALUE);
3773 }
3774 }
3775
3776 programObject->link();
3777 }
3778}
3779
Nicolas Capensa9b49372015-01-30 00:33:26 -05003780void APIENTRY glPixelStorei(GLenum pname, GLint param)
Nicolas Capens264f1522015-01-09 17:21:17 -05003781{
3782 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
3783
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003784 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003785
3786 if(context)
3787 {
3788 switch(pname)
3789 {
3790 case GL_UNPACK_ALIGNMENT:
3791 if(param != 1 && param != 2 && param != 4 && param != 8)
3792 {
3793 return error(GL_INVALID_VALUE);
3794 }
3795 context->setUnpackAlignment(param);
3796 break;
3797 case GL_PACK_ALIGNMENT:
3798 if(param != 1 && param != 2 && param != 4 && param != 8)
3799 {
3800 return error(GL_INVALID_VALUE);
3801 }
3802 context->setPackAlignment(param);
3803 break;
3804 default:
3805 return error(GL_INVALID_ENUM);
3806 }
3807 }
3808}
3809
Nicolas Capensa9b49372015-01-30 00:33:26 -05003810void APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
Nicolas Capens264f1522015-01-09 17:21:17 -05003811{
3812 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
3813
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003814 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003815
3816 if(context)
3817 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003818 if(context->getListIndex() != 0)
3819 {
3820 UNIMPLEMENTED();
3821 }
3822
Nicolas Capens264f1522015-01-09 17:21:17 -05003823 context->setPolygonOffsetParams(factor, units);
3824 }
3825}
3826
Nicolas Capensa9b49372015-01-30 00:33:26 -05003827void APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -05003828 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
3829{
3830 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07003831 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003832 x, y, width, height, format, type, bufSize, data);
3833
3834 if(width < 0 || height < 0 || bufSize < 0)
3835 {
3836 return error(GL_INVALID_VALUE);
3837 }
3838
3839 if(!validReadFormatType(format, type))
3840 {
3841 return error(GL_INVALID_OPERATION);
3842 }
3843
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003844 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003845
3846 if(context)
3847 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003848 if(context->getListIndex() != 0)
3849 {
3850 UNIMPLEMENTED();
3851 }
3852
Nicolas Capens264f1522015-01-09 17:21:17 -05003853 context->readPixels(x, y, width, height, format, type, &bufSize, data);
3854 }
3855}
3856
Nicolas Capensa9b49372015-01-30 00:33:26 -05003857void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
Nicolas Capens264f1522015-01-09 17:21:17 -05003858{
3859 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07003860 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003861 x, y, width, height, format, type, pixels);
3862
3863 if(width < 0 || height < 0)
3864 {
3865 return error(GL_INVALID_VALUE);
3866 }
3867
3868 if(!validReadFormatType(format, type))
3869 {
3870 return error(GL_INVALID_OPERATION);
3871 }
3872
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003873 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003874
3875 if(context)
3876 {
3877 context->readPixels(x, y, width, height, format, type, NULL, pixels);
3878 }
3879}
3880
Nicolas Capensa9b49372015-01-30 00:33:26 -05003881void APIENTRY glReleaseShaderCompiler(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05003882{
3883 TRACE("()");
3884
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003885 gl::Shader::releaseCompiler();
Nicolas Capens264f1522015-01-09 17:21:17 -05003886}
3887
Nicolas Capensa9b49372015-01-30 00:33:26 -05003888void APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05003889{
3890 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3891 target, samples, internalformat, width, height);
3892
3893 switch(target)
3894 {
3895 case GL_RENDERBUFFER:
3896 break;
3897 default:
3898 return error(GL_INVALID_ENUM);
3899 }
3900
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003901 if(!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
Nicolas Capens264f1522015-01-09 17:21:17 -05003902 {
3903 return error(GL_INVALID_ENUM);
3904 }
3905
3906 if(width < 0 || height < 0 || samples < 0)
3907 {
3908 return error(GL_INVALID_VALUE);
3909 }
3910
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003911 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003912
3913 if(context)
3914 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003915 if(context->getListIndex() != 0)
3916 {
3917 UNIMPLEMENTED();
3918 }
3919
3920 if(width > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003921 height > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
3922 samples > gl::IMPLEMENTATION_MAX_SAMPLES)
Nicolas Capens264f1522015-01-09 17:21:17 -05003923 {
3924 return error(GL_INVALID_VALUE);
3925 }
3926
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003927 GLuint handle = context->getRenderbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05003928 if(handle == 0)
3929 {
3930 return error(GL_INVALID_OPERATION);
3931 }
3932
3933 switch(internalformat)
3934 {
3935 case GL_DEPTH_COMPONENT16:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003936 case GL_DEPTH_COMPONENT24:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003937 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003938 break;
3939 case GL_RGBA4:
3940 case GL_RGB5_A1:
3941 case GL_RGB565:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003942 case GL_RGB8_EXT:
3943 case GL_RGBA8_EXT:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003944 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003945 break;
3946 case GL_STENCIL_INDEX8:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003947 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003948 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05003949 case GL_DEPTH24_STENCIL8_EXT:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003950 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003951 break;
3952 default:
3953 return error(GL_INVALID_ENUM);
3954 }
3955 }
3956}
3957
Nicolas Capensa9b49372015-01-30 00:33:26 -05003958void APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05003959{
3960 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
3961}
3962
Nicolas Capensa9b49372015-01-30 00:33:26 -05003963void APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
Nicolas Capens264f1522015-01-09 17:21:17 -05003964{
3965 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
3966
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003967 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003968
3969 if(context)
3970 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003971 if(context->getListIndex() != 0)
3972 {
3973 UNIMPLEMENTED();
3974 }
3975
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003976 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
Nicolas Capens264f1522015-01-09 17:21:17 -05003977 }
3978}
3979
Nicolas Capensa9b49372015-01-30 00:33:26 -05003980void APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
Nicolas Capens264f1522015-01-09 17:21:17 -05003981{
3982 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
3983
3984 if(condition != GL_ALL_COMPLETED_NV)
3985 {
3986 return error(GL_INVALID_ENUM);
3987 }
3988
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003989 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003990
3991 if(context)
3992 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003993 if(context->getListIndex() != 0)
3994 {
3995 UNIMPLEMENTED();
3996 }
3997
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003998 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05003999
4000 if(fenceObject == NULL)
4001 {
4002 return error(GL_INVALID_OPERATION);
4003 }
4004
4005 fenceObject->setFence(condition);
4006 }
4007}
4008
Nicolas Capensa9b49372015-01-30 00:33:26 -05004009void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05004010{
4011 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4012
4013 if(width < 0 || height < 0)
4014 {
4015 return error(GL_INVALID_VALUE);
4016 }
4017
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004018 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004019
4020 if(context)
4021 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004022 if(context->getListIndex() != 0)
4023 {
4024 UNIMPLEMENTED();
4025 }
4026
Nicolas Capens264f1522015-01-09 17:21:17 -05004027 context->setScissorParams(x, y, width, height);
4028 }
4029}
4030
Nicolas Capensa9b49372015-01-30 00:33:26 -05004031void APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
Nicolas Capens264f1522015-01-09 17:21:17 -05004032{
Nicolas Capens4be33702015-04-28 15:13:30 -07004033 TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
4034 "const GLvoid* binary = %p, GLsizei length = %d)",
Nicolas Capens264f1522015-01-09 17:21:17 -05004035 n, shaders, binaryformat, binary, length);
4036
4037 // No binary shader formats are supported.
4038 return error(GL_INVALID_ENUM);
4039}
4040
Nicolas Capensa9b49372015-01-30 00:33:26 -05004041void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
Nicolas Capens264f1522015-01-09 17:21:17 -05004042{
Nicolas Capens4be33702015-04-28 15:13:30 -07004043 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05004044 shader, count, string, length);
4045
4046 if(count < 0)
4047 {
4048 return error(GL_INVALID_VALUE);
4049 }
4050
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004051 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004052
4053 if(context)
4054 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004055 if(context->getListIndex() != 0)
4056 {
4057 UNIMPLEMENTED();
4058 }
4059
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004060 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05004061
4062 if(!shaderObject)
4063 {
4064 if(context->getProgram(shader))
4065 {
4066 return error(GL_INVALID_OPERATION);
4067 }
4068 else
4069 {
4070 return error(GL_INVALID_VALUE);
4071 }
4072 }
4073
4074 shaderObject->setSource(count, string, length);
4075 }
4076}
4077
Nicolas Capensa9b49372015-01-30 00:33:26 -05004078void APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004079{
4080 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4081}
4082
Nicolas Capensa9b49372015-01-30 00:33:26 -05004083void APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004084{
4085 TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
4086
4087 switch(face)
4088 {
4089 case GL_FRONT:
4090 case GL_BACK:
4091 case GL_FRONT_AND_BACK:
4092 break;
4093 default:
4094 return error(GL_INVALID_ENUM);
4095 }
4096
4097 switch(func)
4098 {
4099 case GL_NEVER:
4100 case GL_ALWAYS:
4101 case GL_LESS:
4102 case GL_LEQUAL:
4103 case GL_EQUAL:
4104 case GL_GEQUAL:
4105 case GL_GREATER:
4106 case GL_NOTEQUAL:
4107 break;
4108 default:
4109 return error(GL_INVALID_ENUM);
4110 }
4111
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004112 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004113
4114 if(context)
4115 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004116 if(context->getListIndex() != 0)
4117 {
4118 UNIMPLEMENTED();
4119 }
4120
Nicolas Capens264f1522015-01-09 17:21:17 -05004121 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4122 {
4123 context->setStencilParams(func, ref, mask);
4124 }
4125
4126 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4127 {
4128 context->setStencilBackParams(func, ref, mask);
4129 }
4130 }
4131}
4132
Nicolas Capensa9b49372015-01-30 00:33:26 -05004133void APIENTRY glStencilMask(GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004134{
4135 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4136}
4137
Nicolas Capensa9b49372015-01-30 00:33:26 -05004138void APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004139{
4140 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
4141
4142 switch(face)
4143 {
4144 case GL_FRONT:
4145 case GL_BACK:
4146 case GL_FRONT_AND_BACK:
4147 break;
4148 default:
4149 return error(GL_INVALID_ENUM);
4150 }
4151
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004152 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004153
4154 if(context)
4155 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004156 if(context->getListIndex() != 0)
4157 {
4158 UNIMPLEMENTED();
4159 }
4160
Nicolas Capens264f1522015-01-09 17:21:17 -05004161 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4162 {
4163 context->setStencilWritemask(mask);
4164 }
4165
4166 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4167 {
4168 context->setStencilBackWritemask(mask);
4169 }
4170 }
4171}
4172
Nicolas Capensa9b49372015-01-30 00:33:26 -05004173void APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
Nicolas Capens264f1522015-01-09 17:21:17 -05004174{
4175 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4176}
4177
Nicolas Capensa9b49372015-01-30 00:33:26 -05004178void APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
Nicolas Capens264f1522015-01-09 17:21:17 -05004179{
4180 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4181 face, fail, zfail, zpass);
4182
4183 switch(face)
4184 {
4185 case GL_FRONT:
4186 case GL_BACK:
4187 case GL_FRONT_AND_BACK:
4188 break;
4189 default:
4190 return error(GL_INVALID_ENUM);
4191 }
4192
4193 switch(fail)
4194 {
4195 case GL_ZERO:
4196 case GL_KEEP:
4197 case GL_REPLACE:
4198 case GL_INCR:
4199 case GL_DECR:
4200 case GL_INVERT:
4201 case GL_INCR_WRAP:
4202 case GL_DECR_WRAP:
4203 break;
4204 default:
4205 return error(GL_INVALID_ENUM);
4206 }
4207
4208 switch(zfail)
4209 {
4210 case GL_ZERO:
4211 case GL_KEEP:
4212 case GL_REPLACE:
4213 case GL_INCR:
4214 case GL_DECR:
4215 case GL_INVERT:
4216 case GL_INCR_WRAP:
4217 case GL_DECR_WRAP:
4218 break;
4219 default:
4220 return error(GL_INVALID_ENUM);
4221 }
4222
4223 switch(zpass)
4224 {
4225 case GL_ZERO:
4226 case GL_KEEP:
4227 case GL_REPLACE:
4228 case GL_INCR:
4229 case GL_DECR:
4230 case GL_INVERT:
4231 case GL_INCR_WRAP:
4232 case GL_DECR_WRAP:
4233 break;
4234 default:
4235 return error(GL_INVALID_ENUM);
4236 }
4237
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004238 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004239
4240 if(context)
4241 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004242 if(context->getListIndex() != 0)
4243 {
4244 UNIMPLEMENTED();
4245 }
4246
Nicolas Capens264f1522015-01-09 17:21:17 -05004247 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4248 {
4249 context->setStencilOperations(fail, zfail, zpass);
4250 }
4251
4252 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4253 {
4254 context->setStencilBackOperations(fail, zfail, zpass);
4255 }
4256 }
4257}
4258
Nicolas Capensa9b49372015-01-30 00:33:26 -05004259GLboolean APIENTRY glTestFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05004260{
4261 TRACE("(GLuint fence = %d)", fence);
4262
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004263 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004264
4265 if(context)
4266 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004267 if(context->getListIndex() != 0)
4268 {
4269 UNIMPLEMENTED();
4270 }
4271
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004272 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05004273
4274 if(fenceObject == NULL)
4275 {
4276 return error(GL_INVALID_OPERATION, GL_TRUE);
4277 }
4278
4279 return fenceObject->testFence();
4280 }
4281
4282 return GL_TRUE;
4283}
4284
Nicolas Capensa9b49372015-01-30 00:33:26 -05004285void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -05004286 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4287{
4288 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004289 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05004290 target, level, internalformat, width, height, border, format, type, pixels);
4291
4292 if(!validImageSize(level, width, height))
4293 {
4294 return error(GL_INVALID_VALUE);
4295 }
4296
4297 if(internalformat != format)
4298 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004299 //TRACE("UNIMPLEMENTED!!");
4300 //return error(GL_INVALID_OPERATION);
Nicolas Capens264f1522015-01-09 17:21:17 -05004301 }
4302
4303 switch(format)
4304 {
4305 case GL_ALPHA:
4306 case GL_LUMINANCE:
4307 case GL_LUMINANCE_ALPHA:
4308 switch(type)
4309 {
4310 case GL_UNSIGNED_BYTE:
4311 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004312 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004313 break;
4314 default:
4315 return error(GL_INVALID_ENUM);
4316 }
4317 break;
4318 case GL_RGB:
4319 switch(type)
4320 {
4321 case GL_UNSIGNED_BYTE:
4322 case GL_UNSIGNED_SHORT_5_6_5:
4323 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004324 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004325 break;
4326 default:
4327 return error(GL_INVALID_ENUM);
4328 }
4329 break;
4330 case GL_RGBA:
4331 switch(type)
4332 {
4333 case GL_UNSIGNED_BYTE:
4334 case GL_UNSIGNED_SHORT_4_4_4_4:
4335 case GL_UNSIGNED_SHORT_5_5_5_1:
4336 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004337 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004338 break;
4339 default:
4340 return error(GL_INVALID_ENUM);
4341 }
4342 break;
4343 case GL_BGRA_EXT:
4344 switch(type)
4345 {
4346 case GL_UNSIGNED_BYTE:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004347 case GL_UNSIGNED_SHORT_5_6_5:
4348 case GL_UNSIGNED_INT_8_8_8_8_REV:
Nicolas Capens264f1522015-01-09 17:21:17 -05004349 break;
4350 default:
4351 return error(GL_INVALID_ENUM);
4352 }
4353 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004354 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
Nicolas Capens264f1522015-01-09 17:21:17 -05004355 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004356 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
4357 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
4358 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004359 case GL_DEPTH_COMPONENT:
4360 switch(type)
4361 {
4362 case GL_UNSIGNED_SHORT:
4363 case GL_UNSIGNED_INT:
4364 break;
4365 default:
4366 return error(GL_INVALID_ENUM);
4367 }
4368 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004369 case GL_DEPTH_STENCIL_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004370 switch(type)
4371 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004372 case GL_UNSIGNED_INT_24_8_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004373 break;
4374 default:
4375 return error(GL_INVALID_ENUM);
4376 }
4377 break;
4378 default:
4379 return error(GL_INVALID_VALUE);
4380 }
4381
4382 if(border != 0)
4383 {
4384 return error(GL_INVALID_VALUE);
4385 }
4386
Nicolas Capensa9b49372015-01-30 00:33:26 -05004387 switch(target)
4388 {
4389 case GL_TEXTURE_2D:
4390 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4391 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4392 {
4393 return error(GL_INVALID_VALUE);
4394 }
4395 break;
4396 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4397 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4398 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4399 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4400 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4401 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4402 if(width != height)
4403 {
4404 return error(GL_INVALID_VALUE);
4405 }
4406
4407 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
4408 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
4409 {
4410 return error(GL_INVALID_VALUE);
4411 }
4412 break;
4413 case GL_PROXY_TEXTURE_2D:
4414 pixels = 0;
4415
4416 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4417 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4418 {
4419 //UNIMPLEMENTED();
4420 width = 0;
4421 height = 0;
4422 internalformat = GL_NONE;
4423 format = GL_NONE;
4424 type = GL_NONE;
4425
4426 //return;// error(GL_INVALID_VALUE);
4427 }
4428 break;
4429 default:
4430 return error(GL_INVALID_ENUM);
4431 }
4432
4433 if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4434 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
4435 format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
4436 format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
4437 {
4438 if(S3TC_SUPPORT)
4439 {
4440 return error(GL_INVALID_OPERATION);
4441 }
4442 else
4443 {
4444 return error(GL_INVALID_ENUM);
4445 }
4446 }
4447
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004448 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004449
4450 if(context)
4451 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004452 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05004453 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004454 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05004455 }
4456
Nicolas Capensa9b49372015-01-30 00:33:26 -05004457 if(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D)
Nicolas Capens264f1522015-01-09 17:21:17 -05004458 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004459 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004460
4461 if(!texture)
4462 {
4463 return error(GL_INVALID_OPERATION);
4464 }
4465
4466 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
4467 }
4468 else
4469 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004470 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05004471
4472 if(!texture)
4473 {
4474 return error(GL_INVALID_OPERATION);
4475 }
4476
4477 texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
4478 }
4479 }
4480}
4481
Nicolas Capensa9b49372015-01-30 00:33:26 -05004482void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
Nicolas Capens264f1522015-01-09 17:21:17 -05004483{
4484 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
4485
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004486 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004487
4488 if(context)
4489 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004490 if(context->getListIndex() != 0)
4491 {
4492 UNIMPLEMENTED();
4493 }
4494
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004495 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05004496
4497 switch(target)
4498 {
4499 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004500 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004501 break;
4502 case GL_TEXTURE_CUBE_MAP:
4503 texture = context->getTextureCubeMap();
4504 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004505 default:
4506 return error(GL_INVALID_ENUM);
4507 }
4508
4509 switch(pname)
4510 {
4511 case GL_TEXTURE_WRAP_S:
4512 if(!texture->setWrapS((GLenum)param))
4513 {
4514 return error(GL_INVALID_ENUM);
4515 }
4516 break;
4517 case GL_TEXTURE_WRAP_T:
4518 if(!texture->setWrapT((GLenum)param))
4519 {
4520 return error(GL_INVALID_ENUM);
4521 }
4522 break;
4523 case GL_TEXTURE_MIN_FILTER:
4524 if(!texture->setMinFilter((GLenum)param))
4525 {
4526 return error(GL_INVALID_ENUM);
4527 }
4528 break;
4529 case GL_TEXTURE_MAG_FILTER:
4530 if(!texture->setMagFilter((GLenum)param))
4531 {
4532 return error(GL_INVALID_ENUM);
4533 }
4534 break;
4535 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4536 if(!texture->setMaxAnisotropy(param))
4537 {
4538 return error(GL_INVALID_VALUE);
4539 }
4540 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004541 case GL_TEXTURE_MIN_LOD:
4542 //TRACE("() UNIMPLEMENTED!!"); // FIXME
4543 //UNIMPLEMENTED();
4544 break;
4545 case GL_TEXTURE_MAX_LOD:
4546 //TRACE("() UNIMPLEMENTED!!"); // FIXME
4547 //UNIMPLEMENTED();
4548 break;
4549 case GL_TEXTURE_LOD_BIAS:
4550 if(param != 0.0f)
4551 {
4552 UNIMPLEMENTED();
4553 }
4554 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004555 default:
4556 return error(GL_INVALID_ENUM);
4557 }
4558 }
4559}
4560
Nicolas Capensa9b49372015-01-30 00:33:26 -05004561void APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05004562{
4563 glTexParameterf(target, pname, *params);
4564}
4565
Nicolas Capensa9b49372015-01-30 00:33:26 -05004566void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
Nicolas Capens264f1522015-01-09 17:21:17 -05004567{
4568 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
4569
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004570 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004571
4572 if(context)
4573 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004574 if(context->getListIndex() != 0)
4575 {
4576 UNIMPLEMENTED();
4577 }
4578
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004579 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05004580
4581 switch(target)
4582 {
4583 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004584 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004585 break;
4586 case GL_TEXTURE_CUBE_MAP:
4587 texture = context->getTextureCubeMap();
4588 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004589 default:
4590 return error(GL_INVALID_ENUM);
4591 }
4592
4593 switch(pname)
4594 {
4595 case GL_TEXTURE_WRAP_S:
4596 if(!texture->setWrapS((GLenum)param))
4597 {
4598 return error(GL_INVALID_ENUM);
4599 }
4600 break;
4601 case GL_TEXTURE_WRAP_T:
4602 if(!texture->setWrapT((GLenum)param))
4603 {
4604 return error(GL_INVALID_ENUM);
4605 }
4606 break;
4607 case GL_TEXTURE_MIN_FILTER:
4608 if(!texture->setMinFilter((GLenum)param))
4609 {
4610 return error(GL_INVALID_ENUM);
4611 }
4612 break;
4613 case GL_TEXTURE_MAG_FILTER:
4614 if(!texture->setMagFilter((GLenum)param))
4615 {
4616 return error(GL_INVALID_ENUM);
4617 }
4618 break;
4619 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4620 if(!texture->setMaxAnisotropy((GLfloat)param))
4621 {
4622 return error(GL_INVALID_VALUE);
4623 }
4624 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004625 case GL_TEXTURE_MAX_LEVEL:
4626 if(!texture->setMaxLevel(param))
4627 {
4628 return error(GL_INVALID_ENUM);
4629 }
4630 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004631 default:
4632 return error(GL_INVALID_ENUM);
4633 }
4634 }
4635}
4636
Nicolas Capensa9b49372015-01-30 00:33:26 -05004637void APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05004638{
4639 glTexParameteri(target, pname, *params);
4640}
4641
Nicolas Capensa9b49372015-01-30 00:33:26 -05004642void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4643 GLenum format, GLenum type, const GLvoid* pixels)
Nicolas Capens264f1522015-01-09 17:21:17 -05004644{
4645 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4646 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004647 "const GLvoid* pixels = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05004648 target, level, xoffset, yoffset, width, height, format, type, pixels);
4649
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004650 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05004651 {
4652 return error(GL_INVALID_ENUM);
4653 }
4654
4655 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
4656 {
4657 return error(GL_INVALID_VALUE);
4658 }
4659
4660 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4661 {
4662 return error(GL_INVALID_VALUE);
4663 }
4664
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004665 if(!gl::CheckTextureFormatType(format, type))
Nicolas Capens264f1522015-01-09 17:21:17 -05004666 {
4667 return error(GL_INVALID_ENUM);
4668 }
4669
4670 if(width == 0 || height == 0 || pixels == NULL)
4671 {
4672 return;
4673 }
4674
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004675 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004676
4677 if(context)
4678 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004679 if(context->getListIndex() != 0)
4680 {
4681 UNIMPLEMENTED();
4682 }
4683
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004684 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -05004685 {
4686 return error(GL_INVALID_VALUE);
4687 }
4688
4689 if(target == GL_TEXTURE_2D)
4690 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004691 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004692
4693 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
4694 {
4695 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4696 }
4697 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004698 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05004699 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004700 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05004701
4702 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
4703 {
4704 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4705 }
4706 }
4707 else
4708 {
4709 UNREACHABLE();
4710 }
4711 }
4712}
4713
Nicolas Capensa9b49372015-01-30 00:33:26 -05004714void APIENTRY glUniform1f(GLint location, GLfloat x)
Nicolas Capens264f1522015-01-09 17:21:17 -05004715{
4716 glUniform1fv(location, 1, &x);
4717}
4718
Nicolas Capensa9b49372015-01-30 00:33:26 -05004719void APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004720{
Nicolas Capens4be33702015-04-28 15:13:30 -07004721 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004722
4723 if(count < 0)
4724 {
4725 return error(GL_INVALID_VALUE);
4726 }
4727
4728 if(location == -1)
4729 {
4730 return;
4731 }
4732
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004733 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004734
4735 if(context)
4736 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004737 if(context->getListIndex() != 0)
4738 {
4739 UNIMPLEMENTED();
4740 }
4741
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004742 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004743
4744 if(!program)
4745 {
4746 return error(GL_INVALID_OPERATION);
4747 }
4748
4749 if(!program->setUniform1fv(location, count, v))
4750 {
4751 return error(GL_INVALID_OPERATION);
4752 }
4753 }
4754}
4755
Nicolas Capensa9b49372015-01-30 00:33:26 -05004756void APIENTRY glUniform1i(GLint location, GLint x)
Nicolas Capens264f1522015-01-09 17:21:17 -05004757{
4758 glUniform1iv(location, 1, &x);
4759}
4760
Nicolas Capensa9b49372015-01-30 00:33:26 -05004761void APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004762{
Nicolas Capens4be33702015-04-28 15:13:30 -07004763 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004764
4765 if(count < 0)
4766 {
4767 return error(GL_INVALID_VALUE);
4768 }
4769
4770 if(location == -1)
4771 {
4772 return;
4773 }
4774
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004775 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004776
4777 if(context)
4778 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004779 if(context->getListIndex() != 0)
4780 {
4781 UNIMPLEMENTED();
4782 }
4783
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004784 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004785
4786 if(!program)
4787 {
4788 return error(GL_INVALID_OPERATION);
4789 }
4790
4791 if(!program->setUniform1iv(location, count, v))
4792 {
4793 return error(GL_INVALID_OPERATION);
4794 }
4795 }
4796}
4797
Nicolas Capensa9b49372015-01-30 00:33:26 -05004798void APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
Nicolas Capens264f1522015-01-09 17:21:17 -05004799{
4800 GLfloat xy[2] = {x, y};
4801
4802 glUniform2fv(location, 1, (GLfloat*)&xy);
4803}
4804
Nicolas Capensa9b49372015-01-30 00:33:26 -05004805void APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004806{
Nicolas Capens4be33702015-04-28 15:13:30 -07004807 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004808
4809 if(count < 0)
4810 {
4811 return error(GL_INVALID_VALUE);
4812 }
4813
4814 if(location == -1)
4815 {
4816 return;
4817 }
4818
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004819 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004820
4821 if(context)
4822 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004823 if(context->getListIndex() != 0)
4824 {
4825 UNIMPLEMENTED();
4826 }
4827
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004828 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004829
4830 if(!program)
4831 {
4832 return error(GL_INVALID_OPERATION);
4833 }
4834
4835 if(!program->setUniform2fv(location, count, v))
4836 {
4837 return error(GL_INVALID_OPERATION);
4838 }
4839 }
4840}
4841
Nicolas Capensa9b49372015-01-30 00:33:26 -05004842void APIENTRY glUniform2i(GLint location, GLint x, GLint y)
Nicolas Capens264f1522015-01-09 17:21:17 -05004843{
4844 GLint xy[4] = {x, y};
4845
4846 glUniform2iv(location, 1, (GLint*)&xy);
4847}
4848
Nicolas Capensa9b49372015-01-30 00:33:26 -05004849void APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004850{
Nicolas Capens4be33702015-04-28 15:13:30 -07004851 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004852
4853 if(count < 0)
4854 {
4855 return error(GL_INVALID_VALUE);
4856 }
4857
4858 if(location == -1)
4859 {
4860 return;
4861 }
4862
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004863 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004864
4865 if(context)
4866 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004867 if(context->getListIndex() != 0)
4868 {
4869 UNIMPLEMENTED();
4870 }
4871
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004872 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004873
4874 if(!program)
4875 {
4876 return error(GL_INVALID_OPERATION);
4877 }
4878
4879 if(!program->setUniform2iv(location, count, v))
4880 {
4881 return error(GL_INVALID_OPERATION);
4882 }
4883 }
4884}
4885
Nicolas Capensa9b49372015-01-30 00:33:26 -05004886void APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
Nicolas Capens264f1522015-01-09 17:21:17 -05004887{
4888 GLfloat xyz[3] = {x, y, z};
4889
4890 glUniform3fv(location, 1, (GLfloat*)&xyz);
4891}
4892
Nicolas Capensa9b49372015-01-30 00:33:26 -05004893void APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004894{
Nicolas Capens4be33702015-04-28 15:13:30 -07004895 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004896
4897 if(count < 0)
4898 {
4899 return error(GL_INVALID_VALUE);
4900 }
4901
4902 if(location == -1)
4903 {
4904 return;
4905 }
4906
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004907 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004908
4909 if(context)
4910 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004911 if(context->getListIndex() != 0)
4912 {
4913 UNIMPLEMENTED();
4914 }
4915
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004916 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004917
4918 if(!program)
4919 {
4920 return error(GL_INVALID_OPERATION);
4921 }
4922
4923 if(!program->setUniform3fv(location, count, v))
4924 {
4925 return error(GL_INVALID_OPERATION);
4926 }
4927 }
4928}
4929
Nicolas Capensa9b49372015-01-30 00:33:26 -05004930void APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
Nicolas Capens264f1522015-01-09 17:21:17 -05004931{
4932 GLint xyz[3] = {x, y, z};
4933
4934 glUniform3iv(location, 1, (GLint*)&xyz);
4935}
4936
Nicolas Capensa9b49372015-01-30 00:33:26 -05004937void APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004938{
Nicolas Capens4be33702015-04-28 15:13:30 -07004939 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004940
4941 if(count < 0)
4942 {
4943 return error(GL_INVALID_VALUE);
4944 }
4945
4946 if(location == -1)
4947 {
4948 return;
4949 }
4950
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004951 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004952
4953 if(context)
4954 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004955 if(context->getListIndex() != 0)
4956 {
4957 UNIMPLEMENTED();
4958 }
4959
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004960 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004961
4962 if(!program)
4963 {
4964 return error(GL_INVALID_OPERATION);
4965 }
4966
4967 if(!program->setUniform3iv(location, count, v))
4968 {
4969 return error(GL_INVALID_OPERATION);
4970 }
4971 }
4972}
4973
Nicolas Capensa9b49372015-01-30 00:33:26 -05004974void APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Nicolas Capens264f1522015-01-09 17:21:17 -05004975{
4976 GLfloat xyzw[4] = {x, y, z, w};
4977
4978 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4979}
4980
Nicolas Capensa9b49372015-01-30 00:33:26 -05004981void APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004982{
Nicolas Capens4be33702015-04-28 15:13:30 -07004983 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004984
4985 if(count < 0)
4986 {
4987 return error(GL_INVALID_VALUE);
4988 }
4989
4990 if(location == -1)
4991 {
4992 return;
4993 }
4994
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004995 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004996
4997 if(context)
4998 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004999 if(context->getListIndex() != 0)
5000 {
5001 UNIMPLEMENTED();
5002 }
5003
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005004 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005005
5006 if(!program)
5007 {
5008 return error(GL_INVALID_OPERATION);
5009 }
5010
5011 if(!program->setUniform4fv(location, count, v))
5012 {
5013 return error(GL_INVALID_OPERATION);
5014 }
5015 }
5016}
5017
Nicolas Capensa9b49372015-01-30 00:33:26 -05005018void APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
Nicolas Capens264f1522015-01-09 17:21:17 -05005019{
5020 GLint xyzw[4] = {x, y, z, w};
5021
5022 glUniform4iv(location, 1, (GLint*)&xyzw);
5023}
5024
Nicolas Capensa9b49372015-01-30 00:33:26 -05005025void APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05005026{
Nicolas Capens4be33702015-04-28 15:13:30 -07005027 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05005028
5029 if(count < 0)
5030 {
5031 return error(GL_INVALID_VALUE);
5032 }
5033
5034 if(location == -1)
5035 {
5036 return;
5037 }
5038
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005039 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005040
5041 if(context)
5042 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005043 if(context->getListIndex() != 0)
5044 {
5045 UNIMPLEMENTED();
5046 }
5047
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005048 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005049
5050 if(!program)
5051 {
5052 return error(GL_INVALID_OPERATION);
5053 }
5054
5055 if(!program->setUniform4iv(location, count, v))
5056 {
5057 return error(GL_INVALID_OPERATION);
5058 }
5059 }
5060}
5061
Nicolas Capensa9b49372015-01-30 00:33:26 -05005062void APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005063{
Nicolas Capens4be33702015-04-28 15:13:30 -07005064 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005065 location, count, transpose, value);
5066
5067 if(count < 0 || transpose != GL_FALSE)
5068 {
5069 return error(GL_INVALID_VALUE);
5070 }
5071
5072 if(location == -1)
5073 {
5074 return;
5075 }
5076
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005077 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005078
5079 if(context)
5080 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005081 if(context->getListIndex() != 0)
5082 {
5083 UNIMPLEMENTED();
5084 }
5085
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005086 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005087
5088 if(!program)
5089 {
5090 return error(GL_INVALID_OPERATION);
5091 }
5092
5093 if(!program->setUniformMatrix2fv(location, count, value))
5094 {
5095 return error(GL_INVALID_OPERATION);
5096 }
5097 }
5098}
5099
Nicolas Capensa9b49372015-01-30 00:33:26 -05005100void APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005101{
Nicolas Capens4be33702015-04-28 15:13:30 -07005102 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005103 location, count, transpose, value);
5104
5105 if(count < 0 || transpose != GL_FALSE)
5106 {
5107 return error(GL_INVALID_VALUE);
5108 }
5109
5110 if(location == -1)
5111 {
5112 return;
5113 }
5114
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005115 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005116
5117 if(context)
5118 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005119 if(context->getListIndex() != 0)
5120 {
5121 UNIMPLEMENTED();
5122 }
5123
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005124 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005125
5126 if(!program)
5127 {
5128 return error(GL_INVALID_OPERATION);
5129 }
5130
5131 if(!program->setUniformMatrix3fv(location, count, value))
5132 {
5133 return error(GL_INVALID_OPERATION);
5134 }
5135 }
5136}
5137
Nicolas Capensa9b49372015-01-30 00:33:26 -05005138void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005139{
Nicolas Capens4be33702015-04-28 15:13:30 -07005140 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005141 location, count, transpose, value);
5142
5143 if(count < 0 || transpose != GL_FALSE)
5144 {
5145 return error(GL_INVALID_VALUE);
5146 }
5147
5148 if(location == -1)
5149 {
5150 return;
5151 }
5152
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005153 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005154
5155 if(context)
5156 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005157 if(context->getListIndex() != 0)
5158 {
5159 UNIMPLEMENTED();
5160 }
5161
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005162 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005163
5164 if(!program)
5165 {
5166 return error(GL_INVALID_OPERATION);
5167 }
5168
5169 if(!program->setUniformMatrix4fv(location, count, value))
5170 {
5171 return error(GL_INVALID_OPERATION);
5172 }
5173 }
5174}
5175
Nicolas Capensa9b49372015-01-30 00:33:26 -05005176void APIENTRY glUseProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05005177{
5178 TRACE("(GLuint program = %d)", program);
5179
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005180 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005181
5182 if(context)
5183 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005184 if(context->getListIndex() != 0)
5185 {
5186 UNIMPLEMENTED();
5187 }
5188
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005189 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05005190
5191 if(!programObject && program != 0)
5192 {
5193 if(context->getShader(program))
5194 {
5195 return error(GL_INVALID_OPERATION);
5196 }
5197 else
5198 {
5199 return error(GL_INVALID_VALUE);
5200 }
5201 }
5202
5203 if(program != 0 && !programObject->isLinked())
5204 {
5205 return error(GL_INVALID_OPERATION);
5206 }
5207
5208 context->useProgram(program);
5209 }
5210}
5211
Nicolas Capensa9b49372015-01-30 00:33:26 -05005212void APIENTRY glValidateProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05005213{
5214 TRACE("(GLuint program = %d)", program);
5215
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005216 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005217
5218 if(context)
5219 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005220 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05005221
5222 if(!programObject)
5223 {
5224 if(context->getShader(program))
5225 {
5226 return error(GL_INVALID_OPERATION);
5227 }
5228 else
5229 {
5230 return error(GL_INVALID_VALUE);
5231 }
5232 }
5233
5234 programObject->validate();
5235 }
5236}
5237
Nicolas Capensa9b49372015-01-30 00:33:26 -05005238void APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
Nicolas Capens264f1522015-01-09 17:21:17 -05005239{
5240 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
5241
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005242 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005243 {
5244 return error(GL_INVALID_VALUE);
5245 }
5246
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005247 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005248
5249 if(context)
5250 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005251 if(context->getListIndex() != 0)
5252 {
5253 UNIMPLEMENTED();
5254 }
5255
5256 //GLfloat vals[4] = { x, 0, 0, 1 };
5257 context->setVertexAttrib(index, x, 0, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005258 }
5259}
5260
Nicolas Capensa9b49372015-01-30 00:33:26 -05005261void APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005262{
Nicolas Capens4be33702015-04-28 15:13:30 -07005263 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
Nicolas Capens264f1522015-01-09 17:21:17 -05005264
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005265 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005266 {
5267 return error(GL_INVALID_VALUE);
5268 }
5269
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005270 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005271
5272 if(context)
5273 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005274 if(context->getListIndex() != 0)
5275 {
5276 UNIMPLEMENTED();
5277 }
5278
5279 //GLfloat vals[4] = { values[0], 0, 0, 1 };
5280 context->setVertexAttrib(index, values[0], 0, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005281 }
5282}
5283
Nicolas Capensa9b49372015-01-30 00:33:26 -05005284void APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
Nicolas Capens264f1522015-01-09 17:21:17 -05005285{
5286 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
5287
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005288 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005289 {
5290 return error(GL_INVALID_VALUE);
5291 }
5292
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005293 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005294
5295 if(context)
5296 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005297 if(context->getListIndex() != 0)
5298 {
5299 UNIMPLEMENTED();
5300 }
5301
5302 //GLfloat vals[4] = { x, y, 0, 1 };
5303 context->setVertexAttrib(index, x, y, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005304 }
5305}
5306
Nicolas Capensa9b49372015-01-30 00:33:26 -05005307void APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005308{
Nicolas Capens4be33702015-04-28 15:13:30 -07005309 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
Nicolas Capens264f1522015-01-09 17:21:17 -05005310
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005311 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005312 {
5313 return error(GL_INVALID_VALUE);
5314 }
5315
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005316 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005317
5318 if(context)
5319 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005320 if(context->getListIndex() != 0)
5321 {
5322 UNIMPLEMENTED();
5323 }
5324
5325 //GLfloat vals[4] = { };
5326 context->setVertexAttrib(index, values[0], values[1], 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005327 }
5328}
5329
Nicolas Capensa9b49372015-01-30 00:33:26 -05005330void APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
Nicolas Capens264f1522015-01-09 17:21:17 -05005331{
5332 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
5333
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005334 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005335 {
5336 return error(GL_INVALID_VALUE);
5337 }
5338
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005339 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005340
5341 if(context)
5342 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005343 if(context->getListIndex() != 0)
5344 {
5345 UNIMPLEMENTED();
5346 }
5347
5348 //GLfloat vals[4] = { x, y, z, 1 };
5349 context->setVertexAttrib(index, x, y, z, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005350 }
5351}
5352
Nicolas Capensa9b49372015-01-30 00:33:26 -05005353void APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005354{
Nicolas Capens4be33702015-04-28 15:13:30 -07005355 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
Nicolas Capens264f1522015-01-09 17:21:17 -05005356
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005357 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005358 {
5359 return error(GL_INVALID_VALUE);
5360 }
5361
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005362 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005363
5364 if(context)
5365 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005366 if(context->getListIndex() != 0)
5367 {
5368 UNIMPLEMENTED();
5369 }
5370
5371 //GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5372 context->setVertexAttrib(index, values[0], values[1], values[2], 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005373 }
5374}
5375
Nicolas Capensa9b49372015-01-30 00:33:26 -05005376void APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Nicolas Capens264f1522015-01-09 17:21:17 -05005377{
5378 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
5379
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005380 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005381 {
5382 return error(GL_INVALID_VALUE);
5383 }
5384
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005385 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005386
5387 if(context)
5388 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005389 if(context->getListIndex() != 0)
5390 {
5391 UNIMPLEMENTED();
5392 }
5393
5394 //GLfloat vals[4] = { x, y, z, w };
5395 context->setVertexAttrib(index, x, y, z, w);
Nicolas Capens264f1522015-01-09 17:21:17 -05005396 }
5397}
5398
Nicolas Capensa9b49372015-01-30 00:33:26 -05005399void APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005400{
Nicolas Capens4be33702015-04-28 15:13:30 -07005401 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
Nicolas Capens264f1522015-01-09 17:21:17 -05005402
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005403 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005404 {
5405 return error(GL_INVALID_VALUE);
5406 }
5407
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005408 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005409
5410 if(context)
5411 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005412 if(context->getListIndex() != 0)
5413 {
5414 UNIMPLEMENTED();
5415 }
5416
5417 context->setVertexAttrib(index, values[0], values[1], values[2], values[3]);
Nicolas Capens264f1522015-01-09 17:21:17 -05005418 }
5419}
5420
Nicolas Capensa9b49372015-01-30 00:33:26 -05005421void APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
Nicolas Capens264f1522015-01-09 17:21:17 -05005422{
5423 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07005424 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005425 index, size, type, normalized, stride, ptr);
5426
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005427 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005428 {
5429 return error(GL_INVALID_VALUE);
5430 }
5431
5432 if(size < 1 || size > 4)
5433 {
5434 return error(GL_INVALID_VALUE);
5435 }
5436
5437 switch(type)
5438 {
5439 case GL_BYTE:
5440 case GL_UNSIGNED_BYTE:
5441 case GL_SHORT:
5442 case GL_UNSIGNED_SHORT:
5443 case GL_FIXED:
5444 case GL_FLOAT:
5445 break;
5446 default:
5447 return error(GL_INVALID_ENUM);
5448 }
5449
5450 if(stride < 0)
5451 {
5452 return error(GL_INVALID_VALUE);
5453 }
5454
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005455 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005456
5457 if(context)
5458 {
5459 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
5460 }
5461}
5462
Nicolas Capensa9b49372015-01-30 00:33:26 -05005463void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05005464{
5465 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
5466
5467 if(width < 0 || height < 0)
5468 {
5469 return error(GL_INVALID_VALUE);
5470 }
5471
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005472 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005473
5474 if(context)
5475 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005476 if(context->getListIndex() != 0)
5477 {
5478 UNIMPLEMENTED();
5479 }
5480
Nicolas Capens264f1522015-01-09 17:21:17 -05005481 context->setViewportParams(x, y, width, height);
5482 }
5483}
5484
Nicolas Capensa9b49372015-01-30 00:33:26 -05005485void 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 -05005486 GLbitfield mask, GLenum filter)
5487{
5488 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5489 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5490 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5491 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5492
5493 switch(filter)
5494 {
5495 case GL_NEAREST:
5496 break;
5497 default:
5498 return error(GL_INVALID_ENUM);
5499 }
5500
5501 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5502 {
5503 return error(GL_INVALID_VALUE);
5504 }
5505
5506 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5507 {
5508 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5509 return error(GL_INVALID_OPERATION);
5510 }
5511
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005512 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005513
5514 if(context)
5515 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005516 if(context->getListIndex() != 0)
5517 {
5518 UNIMPLEMENTED();
5519 }
5520
Nicolas Capens7cc75e12015-01-29 14:44:24 -05005521 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
Nicolas Capens264f1522015-01-09 17:21:17 -05005522 {
5523 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5524 return error(GL_INVALID_OPERATION);
5525 }
5526
5527 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5528 }
5529}
5530
Nicolas Capensa9b49372015-01-30 00:33:26 -05005531void APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
Nicolas Capens264f1522015-01-09 17:21:17 -05005532 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
5533{
5534 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5535 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07005536 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005537 target, level, internalformat, width, height, depth, border, format, type, pixels);
5538
5539 UNIMPLEMENTED(); // FIXME
5540}
5541
Nicolas Capensa9b49372015-01-30 00:33:26 -05005542void WINAPI GlmfBeginGlsBlock()
Nicolas Capens264f1522015-01-09 17:21:17 -05005543{
Nicolas Capensa9b49372015-01-30 00:33:26 -05005544 UNIMPLEMENTED();
5545}
5546
5547void WINAPI GlmfCloseMetaFile()
5548{
5549 UNIMPLEMENTED();
5550}
5551
5552void WINAPI GlmfEndGlsBlock()
5553{
5554 UNIMPLEMENTED();
5555}
5556
5557void WINAPI GlmfEndPlayback()
5558{
5559 UNIMPLEMENTED();
5560}
5561
5562void WINAPI GlmfInitPlayback()
5563{
5564 UNIMPLEMENTED();
5565}
5566
5567void WINAPI GlmfPlayGlsRecord()
5568{
5569 UNIMPLEMENTED();
5570}
5571
5572void APIENTRY glAccum(GLenum op, GLfloat value)
5573{
5574 UNIMPLEMENTED();
5575}
5576
5577void APIENTRY glAlphaFunc(GLenum func, GLclampf ref)
5578{
5579 TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);
5580
5581 gl::Context *context = gl::getContext();
5582
5583 if(context)
Nicolas Capens264f1522015-01-09 17:21:17 -05005584 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005585 if(context->getListIndex() != 0)
5586 {
5587 UNIMPLEMENTED();
5588 }
5589
5590 context->alphaFunc(func, ref);
Nicolas Capens264f1522015-01-09 17:21:17 -05005591 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05005592}
Nicolas Capens264f1522015-01-09 17:21:17 -05005593
Nicolas Capensa9b49372015-01-30 00:33:26 -05005594GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
5595{
5596 UNIMPLEMENTED();
5597 return GL_FALSE;
5598}
Nicolas Capens264f1522015-01-09 17:21:17 -05005599
Nicolas Capensa9b49372015-01-30 00:33:26 -05005600void APIENTRY glArrayElement(GLint i)
5601{
5602 UNIMPLEMENTED();
5603}
5604
5605void APIENTRY glBegin(GLenum mode)
5606{
5607 TRACE("(GLenum mode = 0x%X)", mode);
5608
5609 switch(mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05005610 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005611 case GL_POINTS:
5612 case GL_LINES:
5613 case GL_LINE_STRIP:
5614 case GL_LINE_LOOP:
5615 case GL_TRIANGLES:
5616 case GL_TRIANGLE_STRIP:
5617 case GL_TRIANGLE_FAN:
5618 case GL_QUADS:
5619 case GL_QUAD_STRIP:
5620 case GL_POLYGON:
Nicolas Capens264f1522015-01-09 17:21:17 -05005621 break;
5622 default:
5623 return error(GL_INVALID_ENUM);
5624 }
5625
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005626 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005627
5628 if(context)
5629 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005630 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05005631 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005632 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05005633 }
5634
Nicolas Capensa9b49372015-01-30 00:33:26 -05005635 context->begin(mode);
Nicolas Capens264f1522015-01-09 17:21:17 -05005636 }
5637}
5638
Nicolas Capensa9b49372015-01-30 00:33:26 -05005639void APIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
Nicolas Capens264f1522015-01-09 17:21:17 -05005640{
Nicolas Capens264f1522015-01-09 17:21:17 -05005641 UNIMPLEMENTED();
5642}
5643
Nicolas Capensa9b49372015-01-30 00:33:26 -05005644void APIENTRY glCallList(GLuint list)
Nicolas Capens264f1522015-01-09 17:21:17 -05005645{
Nicolas Capensa9b49372015-01-30 00:33:26 -05005646 TRACE("(GLuint list = %d)", list);
5647
5648 if(list == 0)
5649 {
5650 return error(GL_INVALID_VALUE);
5651 }
5652
5653 gl::Context *context = gl::getContext();
5654
5655 if(context)
5656 {
5657 if(context->getListIndex() != 0)
5658 {
5659 UNIMPLEMENTED();
5660 }
5661
5662 context->callList(list);
5663 }
5664}
5665
5666void APIENTRY glCallLists(GLsizei n, GLenum type, const GLvoid *lists)
5667{
5668 TRACE("(GLsizei n = %d, GLenum type = 0x%X, const GLvoid *lists)", n, type);
5669
5670 gl::Context *context = gl::getContext();
5671
5672 if(context)
5673 {
5674 if(context->getListIndex() != 0)
5675 {
5676 UNIMPLEMENTED();
5677 }
5678
5679 for(int i = 0; i < n; i++)
5680 {
5681 switch(type)
5682 {
5683 case GL_UNSIGNED_INT: context->callList(((unsigned int*)lists)[i]); break;
5684 default:
5685 UNIMPLEMENTED();
5686 UNREACHABLE();
5687 }
5688 }
5689 }
5690}
5691
5692void APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
5693{
5694 UNIMPLEMENTED();
5695}
5696
5697void APIENTRY glClearDepth(GLclampd depth)
5698{
5699 TRACE("(GLclampd depth = %d)", depth);
5700
5701 glClearDepthf((float)depth); // FIXME
5702}
5703
5704void APIENTRY glClearIndex(GLfloat c)
5705{
5706 UNIMPLEMENTED();
5707}
5708
5709void APIENTRY glClipPlane(GLenum plane, const GLdouble *equation)
5710{
5711 UNIMPLEMENTED();
5712}
5713
5714void APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue)
5715{
5716 UNIMPLEMENTED();
5717}
5718
5719void APIENTRY glColor3bv(const GLbyte *v)
5720{
5721 UNIMPLEMENTED();
5722}
5723
5724void APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue)
5725{
5726 UNIMPLEMENTED();
5727}
5728
5729void APIENTRY glColor3dv(const GLdouble *v)
5730{
5731 UNIMPLEMENTED();
5732}
5733
5734void APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue)
5735{
5736 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f)", red, green, blue);
5737
5738 gl::Context *context = gl::getContext();
5739
5740 if(context)
5741 {
5742 if(context->getListIndex() != 0)
5743 {
5744 UNIMPLEMENTED();
5745 }
5746
5747 //context->color(red, green, blue, 1.0f);
5748 //GLfloat vals[4] = {};
5749 context->setVertexAttrib(sw::Color0, red, green, blue, 1);
5750 }
5751}
5752
5753void APIENTRY glColor3fv(const GLfloat *v)
5754{
5755 UNIMPLEMENTED();
5756}
5757
5758void APIENTRY glColor3i(GLint red, GLint green, GLint blue)
5759{
5760 UNIMPLEMENTED();
5761}
5762
5763void APIENTRY glColor3iv(const GLint *v)
5764{
5765 UNIMPLEMENTED();
5766}
5767
5768void APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue)
5769{
5770 UNIMPLEMENTED();
5771}
5772
5773void APIENTRY glColor3sv(const GLshort *v)
5774{
5775 UNIMPLEMENTED();
5776}
5777
5778void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue)
5779{
5780 UNIMPLEMENTED();
5781}
5782
5783void APIENTRY glColor3ubv(const GLubyte *v)
5784{
5785 UNIMPLEMENTED();
5786}
5787
5788void APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue)
5789{
5790 UNIMPLEMENTED();
5791}
5792
5793void APIENTRY glColor3uiv(const GLuint *v)
5794{
5795 UNIMPLEMENTED();
5796}
5797
5798void APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue)
5799{
5800 UNIMPLEMENTED();
5801}
5802
5803void APIENTRY glColor3usv(const GLushort *v)
5804{
5805 UNIMPLEMENTED();
5806}
5807
5808void APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
5809{
5810 UNIMPLEMENTED();
5811}
5812
5813void APIENTRY glColor4bv(const GLbyte *v)
5814{
5815 UNIMPLEMENTED();
5816}
5817
5818void APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
5819{
5820 UNIMPLEMENTED();
5821}
5822
5823void APIENTRY glColor4dv(const GLdouble *v)
5824{
5825 UNIMPLEMENTED();
5826}
5827
5828void APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
5829{
5830 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);
5831
5832 gl::Context *context = gl::getContext();
5833
5834 if(context)
5835 {
5836 if(context->getListIndex() != 0)
5837 {
5838 UNIMPLEMENTED();
5839 }
5840
5841 //context->color(red, green, blue, alpha);
5842 //GLfloat vals[4] = {red, green, blue, alpha};
5843 context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
5844 }
5845}
5846
5847void APIENTRY glColor4fv(const GLfloat *v)
5848{
5849 UNIMPLEMENTED();
5850}
5851
5852void APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha)
5853{
5854 UNIMPLEMENTED();
5855}
5856
5857void APIENTRY glColor4iv(const GLint *v)
5858{
5859 UNIMPLEMENTED();
5860}
5861
5862void APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
5863{
5864 UNIMPLEMENTED();
5865}
5866
5867void APIENTRY glColor4sv(const GLshort *v)
5868{
5869 UNIMPLEMENTED();
5870}
5871
5872void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
5873{
5874 UNIMPLEMENTED();
5875}
5876
5877void APIENTRY glColor4ubv(const GLubyte *v)
5878{
5879 UNIMPLEMENTED();
5880}
5881
5882void APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
5883{
5884 UNIMPLEMENTED();
5885}
5886
5887void APIENTRY glColor4uiv(const GLuint *v)
5888{
5889 UNIMPLEMENTED();
5890}
5891
5892void APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
5893{
5894 UNIMPLEMENTED();
5895}
5896
5897void APIENTRY glColor4usv(const GLushort *v)
5898{
5899 UNIMPLEMENTED();
5900}
5901
5902void APIENTRY glColorMaterial(GLenum face, GLenum mode)
5903{
5904 TRACE("(GLenum face = 0x%X, GLenum mode = 0x%X)", face, mode);
5905
5906 // FIXME: Validate enums
5907
5908 gl::Context *context = gl::getContext();
5909
5910 if(context)
5911 {
5912 if(context->getListIndex() != 0)
5913 {
5914 UNIMPLEMENTED();
5915 }
5916
5917 switch(face)
5918 {
5919 case GL_FRONT:
5920 context->setColorMaterialMode(mode); // FIXME: Front only
5921 break;
5922 case GL_FRONT_AND_BACK:
5923 context->setColorMaterialMode(mode);
5924 break;
5925 default:
5926 UNIMPLEMENTED();
5927 return error(GL_INVALID_ENUM);
5928 }
5929 }
5930}
5931
5932void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
5933{
5934 TRACE("(*)");
5935
5936 glVertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
5937}
5938
5939void APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
5940{
5941 UNIMPLEMENTED();
5942}
5943
5944void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)
5945{
5946 UNIMPLEMENTED();
5947}
5948
5949void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
5950{
5951 UNIMPLEMENTED();
5952}
5953
5954void APIENTRY glDebugEntry()
5955{
5956 UNIMPLEMENTED();
5957}
5958
5959void APIENTRY glDeleteLists(GLuint list, GLsizei range)
5960{
5961 TRACE("(GLuint list = %d, GLsizei range = %d)", list, range);
5962
5963 if(range < 0)
5964 {
5965 return error(GL_INVALID_VALUE);
5966 }
5967
5968 gl::Context *context = gl::getContext();
5969
5970 if(context)
5971 {
Alexis Hetuf7be67f2015-02-11 16:11:07 -05005972 for(GLuint i = list; i < list + range; i++)
Nicolas Capensa9b49372015-01-30 00:33:26 -05005973 {
5974 context->deleteList(i);
5975 }
5976 }
5977}
5978
5979void APIENTRY glDepthRange(GLclampd zNear, GLclampd zFar)
5980{
5981 UNIMPLEMENTED();
5982}
5983
5984void APIENTRY glDisableClientState(GLenum array)
5985{
5986 TRACE("(GLenum array = 0x%X)", array);
5987
5988 gl::Context *context = gl::getContext();
5989
5990 if(context)
5991 {
5992 GLenum texture = context->getClientActiveTexture();
5993
5994 switch(array)
5995 {
5996 case GL_VERTEX_ARRAY: context->setEnableVertexAttribArray(sw::Position, false); break;
5997 case GL_COLOR_ARRAY: context->setEnableVertexAttribArray(sw::Color0, false); break;
5998 case GL_TEXTURE_COORD_ARRAY: context->setEnableVertexAttribArray(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
5999 case GL_NORMAL_ARRAY: context->setEnableVertexAttribArray(sw::Normal, false); break;
6000 default: UNIMPLEMENTED();
6001 }
6002 }
6003}
6004
6005void APIENTRY glDrawBuffer(GLenum mode)
6006{
6007 UNIMPLEMENTED();
6008}
6009
6010void APIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
6011{
6012 UNIMPLEMENTED();
6013}
6014
6015void APIENTRY glEdgeFlag(GLboolean flag)
6016{
6017 UNIMPLEMENTED();
6018}
6019
6020void APIENTRY glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)
6021{
6022 UNIMPLEMENTED();
6023}
6024
6025void APIENTRY glEdgeFlagv(const GLboolean *flag)
6026{
6027 UNIMPLEMENTED();
6028}
6029
6030void APIENTRY glEnableClientState(GLenum array)
6031{
6032 TRACE("(GLenum array = 0x%X)", array);
6033
6034 gl::Context *context = gl::getContext();
6035
6036 if(context)
6037 {
6038 GLenum texture = context->getClientActiveTexture();
6039
6040 switch(array)
6041 {
6042 case GL_VERTEX_ARRAY: context->setEnableVertexAttribArray(sw::Position, true); break;
6043 case GL_COLOR_ARRAY: context->setEnableVertexAttribArray(sw::Color0, true); break;
6044 case GL_TEXTURE_COORD_ARRAY: context->setEnableVertexAttribArray(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
6045 case GL_NORMAL_ARRAY: context->setEnableVertexAttribArray(sw::Normal, true); break;
6046 default: UNIMPLEMENTED();
6047 }
6048 }
6049}
6050
6051void APIENTRY glEnd()
6052{
6053 TRACE("()");
6054
6055 gl::Context *context = gl::getContext();
6056
6057 if(context)
6058 {
6059 if(context->getListIndex() != 0)
6060 {
6061 UNIMPLEMENTED();
6062 }
6063
6064 context->end();
6065 }
6066}
6067
6068void APIENTRY glEndList()
6069{
6070 TRACE("()");
6071
6072 gl::Context *context = gl::getContext();
6073
6074 if(context)
6075 {
6076 context->endList();
6077 }
6078}
6079
6080void APIENTRY glEvalCoord1d(GLdouble u)
6081{
6082 UNIMPLEMENTED();
6083}
6084
6085void APIENTRY glEvalCoord1dv(const GLdouble *u)
6086{
6087 UNIMPLEMENTED();
6088}
6089
6090void APIENTRY glEvalCoord1f(GLfloat u)
6091{
6092 UNIMPLEMENTED();
6093}
6094
6095void APIENTRY glEvalCoord1fv(const GLfloat *u)
6096{
6097 UNIMPLEMENTED();
6098}
6099
6100void APIENTRY glEvalCoord2d(GLdouble u, GLdouble v)
6101{
6102 UNIMPLEMENTED();
6103}
6104
6105void APIENTRY glEvalCoord2dv(const GLdouble *u)
6106{
6107 UNIMPLEMENTED();
6108}
6109
6110void APIENTRY glEvalCoord2f(GLfloat u, GLfloat v)
6111{
6112 UNIMPLEMENTED();
6113}
6114
6115void APIENTRY glEvalCoord2fv(const GLfloat *u)
6116{
6117 UNIMPLEMENTED();
6118}
6119
6120void APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2)
6121{
6122 UNIMPLEMENTED();
6123}
6124
6125void APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
6126{
6127 UNIMPLEMENTED();
6128}
6129
6130void APIENTRY glEvalPoint1(GLint i)
6131{
6132 UNIMPLEMENTED();
6133}
6134
6135void APIENTRY glEvalPoint2(GLint i, GLint j)
6136{
6137 UNIMPLEMENTED();
6138}
6139
6140void APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
6141{
6142 UNIMPLEMENTED();
6143}
6144
6145void APIENTRY glFogf(GLenum pname, GLfloat param)
6146{
6147 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
6148
6149 gl::Context *context = gl::getContext();
6150
6151 if(context)
6152 {
6153 if(context->getListIndex() != 0)
6154 {
6155 UNIMPLEMENTED();
6156 }
6157
6158 gl::Device *device = gl::getDevice(); // FIXME
6159
6160 switch(pname)
6161 {
6162 case GL_FOG_START: device->setFogStart(param); break;
6163 case GL_FOG_END: device->setFogEnd(param); break;
6164 default:
6165 UNIMPLEMENTED();
6166 return error(GL_INVALID_ENUM);
6167 }
6168 }
6169}
6170
6171void APIENTRY glFogfv(GLenum pname, const GLfloat *params)
6172{
6173 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
6174
6175 gl::Context *context = gl::getContext();
6176
6177 if(context)
6178 {
6179 if(context->getListIndex() != 0)
6180 {
6181 UNIMPLEMENTED();
6182 }
6183
6184 switch(pname)
6185 {
6186 case GL_FOG_COLOR:
6187 {
6188 gl::Device *device = gl::getDevice(); // FIXME
6189 device->setFogColor(sw::Color<float>(params[0], params[1], params[2], params[3]));
6190 }
6191 break;
6192 default:
6193 UNIMPLEMENTED();
6194 return error(GL_INVALID_ENUM);
6195 }
6196 }
6197}
6198
6199void APIENTRY glFogi(GLenum pname, GLint param)
6200{
6201 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
6202
6203 gl::Context *context = gl::getContext();
6204
6205 if(context)
6206 {
6207 if(context->getListIndex() != 0)
6208 {
6209 UNIMPLEMENTED();
6210 }
6211
6212 switch(pname)
6213 {
6214 case GL_FOG_MODE:
6215 {
6216 gl::Device *device = gl::getDevice(); // FIXME
6217 switch(param)
6218 {
6219 case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
6220 default:
6221 UNIMPLEMENTED();
6222 return error(GL_INVALID_ENUM);
6223 }
6224 }
6225 break;
6226 default:
6227 UNIMPLEMENTED();
6228 return error(GL_INVALID_ENUM);
6229 }
6230 }
6231}
6232
6233void APIENTRY glFogiv(GLenum pname, const GLint *params)
6234{
6235 UNIMPLEMENTED();
6236}
6237
6238void APIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
6239{
Nicolas Capens74626012015-03-11 21:49:44 -04006240 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 -05006241
6242 gl::Context *context = gl::getContext();
6243
6244 if(context)
6245 {
6246 if(context->getListIndex() != 0)
6247 {
6248 UNIMPLEMENTED();
6249 }
6250
6251 context->frustum(left, right, bottom, top, zNear, zFar);
6252 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05006253}
6254
6255GLuint APIENTRY glGenLists(GLsizei range)
6256{
6257 TRACE("(GLsizei range = %d)", range);
6258
6259 if(range < 0)
6260 {
6261 return error(GL_INVALID_VALUE, 0);
6262 }
6263
6264 gl::Context *context = gl::getContext();
6265
6266 if(context)
6267 {
6268 return context->genLists(range);
6269 }
6270
6271 return 0;
6272}
6273
6274void APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation)
6275{
6276 UNIMPLEMENTED();
6277}
6278
6279void APIENTRY glGetDoublev(GLenum pname, GLdouble *params)
6280{
6281 UNIMPLEMENTED();
6282}
6283
6284void APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
6285{
6286 UNIMPLEMENTED();
6287}
6288
6289void APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params)
6290{
6291 UNIMPLEMENTED();
6292}
6293
6294void APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v)
6295{
6296 UNIMPLEMENTED();
6297}
6298
6299void APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v)
6300{
6301 UNIMPLEMENTED();
6302}
6303
6304void APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v)
6305{
6306 UNIMPLEMENTED();
6307}
6308
6309void APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
6310{
6311 UNIMPLEMENTED();
6312}
6313
6314void APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params)
6315{
6316 UNIMPLEMENTED();
6317}
6318
6319void APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values)
6320{
6321 UNIMPLEMENTED();
6322}
6323
6324void APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values)
6325{
6326 UNIMPLEMENTED();
6327}
6328
6329void APIENTRY glGetPixelMapusv(GLenum map, GLushort *values)
6330{
6331 UNIMPLEMENTED();
6332}
6333
6334void APIENTRY glGetPointerv(GLenum pname, GLvoid* *params)
6335{
6336 UNIMPLEMENTED();
6337}
6338
6339void APIENTRY glGetPolygonStipple(GLubyte *mask)
6340{
6341 UNIMPLEMENTED();
6342}
6343
6344void APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
6345{
6346 UNIMPLEMENTED();
6347}
6348
6349void APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params)
6350{
6351 UNIMPLEMENTED();
6352}
6353
6354void APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
6355{
6356 UNIMPLEMENTED();
6357}
6358
6359void APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
6360{
6361 UNIMPLEMENTED();
6362}
6363
6364void APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
6365{
6366 UNIMPLEMENTED();
6367}
6368
6369void APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
6370{
Nicolas Capens4be33702015-04-28 15:13:30 -07006371 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 -05006372
6373 gl::Context *context = gl::getContext();
6374
6375 if(context)
6376 {
6377 gl::Texture *texture;
6378
6379 switch(target)
6380 {
6381 case GL_TEXTURE_2D:
6382 texture = context->getTexture2D(target);
6383 break;
6384 case GL_TEXTURE_CUBE_MAP:
6385 texture = context->getTextureCubeMap();
6386 break;
6387 default:
6388 UNIMPLEMENTED();
6389 return error(GL_INVALID_ENUM);
6390 }
6391
6392 if(format == texture->getFormat(target, level) && type == texture->getType(target, level))
6393 {
6394 gl::Image *image = texture->getRenderTarget(target, level);
6395 void *source = image->lock(0, 0, sw::LOCK_READONLY);
6396 memcpy(pixels, source, image->getPitch() * image->getHeight());
6397 image->unlock();
6398 }
6399 else
6400 {
6401 UNIMPLEMENTED();
6402 }
6403 }
6404}
6405
6406void APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
6407{
6408 UNIMPLEMENTED();
6409}
6410
6411void APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
6412{
Nicolas Capens4be33702015-04-28 15:13:30 -07006413 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 -05006414
6415 gl::Context *context = gl::getContext();
6416
6417 if(context)
6418 {
6419 gl::Texture *texture;
6420
6421 switch(target)
6422 {
6423 case GL_TEXTURE_2D:
6424 case GL_PROXY_TEXTURE_2D:
6425 texture = context->getTexture2D(target);
6426 break;
6427 case GL_TEXTURE_CUBE_MAP:
6428 texture = context->getTextureCubeMap();
6429 break;
6430 default:
6431 UNIMPLEMENTED();
6432 return error(GL_INVALID_ENUM);
6433 }
6434
6435 switch(pname)
6436 {
6437 case GL_TEXTURE_MAG_FILTER:
6438 *params = texture->getMagFilter();
6439 break;
6440 case GL_TEXTURE_MIN_FILTER:
6441 *params = texture->getMinFilter();
6442 break;
6443 case GL_TEXTURE_WRAP_S:
6444 *params = texture->getWrapS();
6445 break;
6446 case GL_TEXTURE_WRAP_T:
6447 *params = texture->getWrapT();
6448 break;
6449 case GL_TEXTURE_WIDTH:
6450 *params = texture->getWidth(target, level);
6451 break;
6452 case GL_TEXTURE_HEIGHT:
6453 *params = texture->getHeight(target, level);
6454 break;
6455 case GL_TEXTURE_INTERNAL_FORMAT:
6456 *params = texture->getInternalFormat(target, level);
6457 break;
6458 case GL_TEXTURE_BORDER_COLOR:
6459 UNIMPLEMENTED();
6460 break;
6461 case GL_TEXTURE_BORDER:
6462 UNIMPLEMENTED();
6463 break;
6464 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6465 *params = (GLint)texture->getMaxAnisotropy();
6466 break;
6467 default:
6468 return error(GL_INVALID_ENUM);
6469 }
6470 }
6471}
6472
6473void APIENTRY glIndexMask(GLuint mask)
6474{
6475 UNIMPLEMENTED();
6476}
6477
6478void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
6479{
6480 UNIMPLEMENTED();
6481}
6482
6483void APIENTRY glIndexd(GLdouble c)
6484{
6485 UNIMPLEMENTED();
6486}
6487
6488void APIENTRY glIndexdv(const GLdouble *c)
6489{
6490 UNIMPLEMENTED();
6491}
6492
6493void APIENTRY glIndexf(GLfloat c)
6494{
6495 UNIMPLEMENTED();
6496}
6497
6498void APIENTRY glIndexfv(const GLfloat *c)
6499{
6500 UNIMPLEMENTED();
6501}
6502
6503void APIENTRY glIndexi(GLint c)
6504{
6505 UNIMPLEMENTED();
6506}
6507
6508void APIENTRY glIndexiv(const GLint *c)
6509{
6510 UNIMPLEMENTED();
6511}
6512
6513void APIENTRY glIndexs(GLshort c)
6514{
6515 UNIMPLEMENTED();
6516}
6517
6518void APIENTRY glIndexsv(const GLshort *c)
6519{
6520 UNIMPLEMENTED();
6521}
6522
6523void APIENTRY glIndexub(GLubyte c)
6524{
6525 UNIMPLEMENTED();
6526}
6527
6528void APIENTRY glIndexubv(const GLubyte *c)
6529{
6530 UNIMPLEMENTED();
6531}
6532
6533void APIENTRY glInitNames(void)
6534{
6535 UNIMPLEMENTED();
6536}
6537
6538void APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
6539{
6540 UNIMPLEMENTED();
6541}
6542
6543GLboolean APIENTRY glIsList(GLuint list)
6544{
6545 UNIMPLEMENTED();
6546 return GL_FALSE;
6547}
6548
6549void APIENTRY glLightModelf(GLenum pname, GLfloat param)
6550{
6551 UNIMPLEMENTED();
6552}
6553
6554void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
6555{
6556 TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
6557
6558 gl::Context *context = gl::getContext();
6559
6560 if(context)
6561 {
6562 if(context->getListIndex() != 0)
6563 {
6564 UNIMPLEMENTED();
6565 }
6566
6567 gl::Device *device = gl::getDevice(); // FIXME
6568
6569 switch(pname)
6570 {
6571 case GL_LIGHT_MODEL_AMBIENT:
6572 device->setGlobalAmbient(sw::Color<float>(params[0], params[1], params[2], params[3]));
6573 break;
6574 default:
6575 UNIMPLEMENTED();
6576 return error(GL_INVALID_ENUM);
6577 }
6578 }
6579}
6580
6581void APIENTRY glLightModeli(GLenum pname, GLint param)
6582{
6583 UNIMPLEMENTED();
6584}
6585
6586void APIENTRY glLightModeliv(GLenum pname, const GLint *params)
6587{
6588 TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
6589 UNIMPLEMENTED();
6590}
6591
6592void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
6593{
6594 UNIMPLEMENTED();
6595}
6596
6597void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
6598{
6599 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
6600
6601 gl::Context *context = gl::getContext();
6602
6603 if(context)
6604 {
6605 if(context->getListIndex() != 0)
6606 {
6607 UNIMPLEMENTED();
6608 }
6609
6610 gl::Device *device = gl::getDevice(); // FIXME
6611
6612 switch(pname)
6613 {
6614 case GL_AMBIENT: device->setLightAmbient(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6615 case GL_DIFFUSE: device->setLightDiffuse(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6616 case GL_SPECULAR: device->setLightSpecular(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6617 case GL_POSITION:
6618 if(params[3] == 0.0f) // Directional light
6619 {
6620 // Create a very far out point light
6621 float max = std::max(std::max(abs(params[0]), abs(params[1])), abs(params[2]));
6622 device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / max * 1e10f, params[1] / max * 1e10f, params[2] / max * 1e10f));
6623 }
6624 else
6625 {
6626 device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / params[3], params[1] / params[3], params[2] / params[3]));
6627 }
6628 break;
6629 default:
6630 UNIMPLEMENTED();
6631 return error(GL_INVALID_ENUM);
6632 }
6633 }
6634}
6635
6636void APIENTRY glLighti(GLenum light, GLenum pname, GLint param)
6637{
6638 UNIMPLEMENTED();
6639}
6640
6641void APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params)
6642{
6643 UNIMPLEMENTED();
6644}
6645
6646void APIENTRY glLineStipple(GLint factor, GLushort pattern)
6647{
6648 UNIMPLEMENTED();
6649}
6650
6651void APIENTRY glListBase(GLuint base)
6652{
6653 UNIMPLEMENTED();
6654}
6655
6656void APIENTRY glLoadIdentity()
6657{
6658 TRACE("()");
6659
6660 gl::Context *context = gl::getContext();
6661
6662 if(context)
6663 {
6664 if(context->getListIndex() != 0)
6665 {
6666 UNIMPLEMENTED();
6667 }
6668
6669 context->loadIdentity();
6670 }
6671}
6672
6673void APIENTRY glLoadMatrixd(const GLdouble *m)
6674{
6675 UNIMPLEMENTED();
6676}
6677
6678void APIENTRY glLoadMatrixf(const GLfloat *m)
6679{
6680 UNIMPLEMENTED();
6681}
6682
6683void APIENTRY glLoadName(GLuint name)
6684{
6685 UNIMPLEMENTED();
6686}
6687
6688void APIENTRY glLogicOp(GLenum opcode)
6689{
6690 UNIMPLEMENTED();
6691}
6692
6693void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
6694{
6695 UNIMPLEMENTED();
6696}
6697
6698void APIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
6699{
6700 UNIMPLEMENTED();
6701}
6702
6703void APIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)
6704{
6705 UNIMPLEMENTED();
6706}
6707
6708void APIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)
6709{
6710 UNIMPLEMENTED();
6711}
6712
6713void APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
6714{
6715 UNIMPLEMENTED();
6716}
6717
6718void APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
6719{
6720 UNIMPLEMENTED();
6721}
6722
6723void APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
6724{
6725 UNIMPLEMENTED();
6726}
6727
6728void APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
6729{
6730 UNIMPLEMENTED();
6731}
6732
6733void APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
6734{
6735 UNIMPLEMENTED();
6736}
6737
6738void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
6739{
6740 UNIMPLEMENTED();
6741}
6742
6743void APIENTRY glMateriali(GLenum face, GLenum pname, GLint param)
6744{
6745 UNIMPLEMENTED();
6746}
6747
6748void APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params)
6749{
6750 UNIMPLEMENTED();
6751}
6752
6753void APIENTRY glMatrixMode(GLenum mode)
6754{
6755 TRACE("(*)");
6756
6757 gl::Context *context = gl::getContext();
6758
6759 if(context)
6760 {
6761 if(context->getListIndex() != 0)
6762 {
6763 UNIMPLEMENTED();
6764 }
6765
6766 context->setMatrixMode(mode);
6767 }
6768}
6769
6770void APIENTRY glMultMatrixd(const GLdouble *m)
6771{
Maxime Gregoire53ff8d82015-03-04 14:51:58 -05006772 TRACE("(*)");
6773
6774 gl::Context *context = gl::getContext();
6775
6776 if(context)
6777 {
6778 if(context->getListIndex() != 0)
6779 {
6780 UNIMPLEMENTED();
6781 }
6782
6783 context->multiply(m);
6784 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05006785}
6786
6787void APIENTRY glMultMatrixm(sw::Matrix m)
6788{
6789 gl::Context *context = gl::getContext();
6790
6791 if(context)
6792 {
6793 context->multiply((GLfloat*)m.m);
6794 }
6795}
6796
6797void APIENTRY glMultMatrixf(const GLfloat *m)
6798{
6799 TRACE("(*)");
6800
6801 gl::Context *context = gl::getContext();
6802
6803 if(context)
6804 {
6805 if(context->getListIndex() != 0)
6806 {
6807 return context->listCommand(gl::newCommand(glMultMatrixm, sw::Matrix(m)));
6808 }
6809
6810 context->multiply(m);
6811 }
6812}
6813
6814void APIENTRY glNewList(GLuint list, GLenum mode)
6815{
6816 TRACE("(GLuint list = %d, GLenum mode = 0x%X)", list, mode);
6817
6818 if(list == 0)
6819 {
6820 return error(GL_INVALID_VALUE);
6821 }
6822
6823 switch(mode)
6824 {
6825 case GL_COMPILE:
6826 case GL_COMPILE_AND_EXECUTE:
6827 break;
6828 default:
6829 return error(GL_INVALID_ENUM);
6830 }
6831
6832 gl::Context *context = gl::getContext();
6833
6834 if(context)
6835 {
6836 if(context->getListIndex() != 0)
6837 {
6838 UNIMPLEMENTED();
6839 }
6840
6841 context->newList(list, mode);
6842 }
6843}
6844
6845void APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
6846{
6847 UNIMPLEMENTED();
6848}
6849
6850void APIENTRY glNormal3bv(const GLbyte *v)
6851{
6852 UNIMPLEMENTED();
6853}
6854
6855void APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
6856{
6857 UNIMPLEMENTED();
6858}
6859
6860void APIENTRY glNormal3dv(const GLdouble *v)
6861{
6862 UNIMPLEMENTED();
6863}
6864
6865void APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
6866{
6867 TRACE("(GLfloat nx = %f, GLfloat ny = %f, GLfloat nz = %f)", nx, ny, nz);
6868
6869 gl::Context *context = gl::getContext();
6870
6871 if(context)
6872 {
6873 if(context->getListIndex() != 0)
6874 {
6875 UNIMPLEMENTED();
6876 }
6877
6878 //context->normal(nx, ny, nz);
6879 context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
6880 }
6881}
6882
6883void APIENTRY glNormal3fv(const GLfloat *v)
6884{
6885 UNIMPLEMENTED();
6886}
6887
6888void APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz)
6889{
6890 UNIMPLEMENTED();
6891}
6892
6893void APIENTRY glNormal3iv(const GLint *v)
6894{
6895 UNIMPLEMENTED();
6896}
6897
6898void APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz)
6899{
6900 UNIMPLEMENTED();
6901}
6902
6903void APIENTRY glNormal3sv(const GLshort *v)
6904{
6905 UNIMPLEMENTED();
6906}
6907
6908void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
6909{
6910 TRACE("(*)");
6911
6912 glVertexAttribPointer(sw::Normal, 3, type, false, stride, pointer);
6913}
6914
6915void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
6916{
6917 TRACE("(*)");
6918
6919 gl::Context *context = gl::getContext();
6920
6921 if(context)
6922 {
6923 if(context->getListIndex() != 0)
6924 {
6925 UNIMPLEMENTED();
6926 }
6927
6928 context->ortho(left, right, bottom, top, zNear, zFar);
6929 }
6930}
6931
6932void APIENTRY glPassThrough(GLfloat token)
6933{
6934 UNIMPLEMENTED();
6935}
6936
6937void APIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)
6938{
6939 UNIMPLEMENTED();
6940}
6941
6942void APIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)
6943{
6944 UNIMPLEMENTED();
6945}
6946
6947void APIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)
6948{
6949 UNIMPLEMENTED();
6950}
6951
6952void APIENTRY glPixelStoref(GLenum pname, GLfloat param)
6953{
6954 UNIMPLEMENTED();
6955}
6956
6957void APIENTRY glPixelTransferf(GLenum pname, GLfloat param)
6958{
6959 UNIMPLEMENTED();
6960}
6961
6962void APIENTRY glPixelTransferi(GLenum pname, GLint param)
6963{
6964 UNIMPLEMENTED();
6965}
6966
6967void APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
6968{
6969 UNIMPLEMENTED();
6970}
6971
6972void APIENTRY glPointSize(GLfloat size)
6973{
6974 UNIMPLEMENTED();
6975}
6976
6977void APIENTRY glPolygonMode(GLenum face, GLenum mode)
6978{
6979 UNIMPLEMENTED();
6980}
6981
6982void APIENTRY glPolygonStipple(const GLubyte *mask)
6983{
6984 UNIMPLEMENTED();
6985}
6986
6987void APIENTRY glPopAttrib(void)
6988{
6989 UNIMPLEMENTED();
6990}
6991
6992void APIENTRY glPopClientAttrib(void)
6993{
6994 UNIMPLEMENTED();
6995}
6996
6997void APIENTRY glPopMatrix(void)
6998{
6999 TRACE("()");
7000
7001 gl::Context *context = gl::getContext();
7002
7003 if(context)
7004 {
7005 if(context->getListIndex() != 0)
7006 {
7007 return context->listCommand(gl::newCommand(glPopMatrix));
7008 }
7009
7010 context->popMatrix();
7011 }
7012}
7013
7014void APIENTRY glPopName(void)
7015{
7016 UNIMPLEMENTED();
7017}
7018
7019void APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities)
7020{
7021 UNIMPLEMENTED();
7022}
7023
7024void APIENTRY glPushAttrib(GLbitfield mask)
7025{
7026 UNIMPLEMENTED();
7027}
7028
7029void APIENTRY glPushClientAttrib(GLbitfield mask)
7030{
7031 UNIMPLEMENTED();
7032}
7033
7034void APIENTRY glPushMatrix(void)
7035{
7036 TRACE("()");
7037
7038 gl::Context *context = gl::getContext();
7039
7040 if(context)
7041 {
7042 if(context->getListIndex() != 0)
7043 {
7044 return context->listCommand(gl::newCommand(glPushMatrix));
7045 }
7046
7047 context->pushMatrix();
7048 }
7049}
7050
7051void APIENTRY glPushName(GLuint name)
7052{
7053 UNIMPLEMENTED();
7054}
7055
7056void APIENTRY glRasterPos2d(GLdouble x, GLdouble y)
7057{
7058 UNIMPLEMENTED();
7059}
7060
7061void APIENTRY glRasterPos2dv(const GLdouble *v)
7062{
7063 UNIMPLEMENTED();
7064}
7065
7066void APIENTRY glRasterPos2f(GLfloat x, GLfloat y)
7067{
7068 UNIMPLEMENTED();
7069}
7070
7071void APIENTRY glRasterPos2fv(const GLfloat *v)
7072{
7073 UNIMPLEMENTED();
7074}
7075
7076void APIENTRY glRasterPos2i(GLint x, GLint y)
7077{
7078 UNIMPLEMENTED();
7079}
7080
7081void APIENTRY glRasterPos2iv(const GLint *v)
7082{
7083 UNIMPLEMENTED();
7084}
7085
7086void APIENTRY glRasterPos2s(GLshort x, GLshort y)
7087{
7088 UNIMPLEMENTED();
7089}
7090
7091void APIENTRY glRasterPos2sv(const GLshort *v)
7092{
7093 UNIMPLEMENTED();
7094}
7095
7096void APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
7097{
7098 UNIMPLEMENTED();
7099}
7100
7101void APIENTRY glRasterPos3dv(const GLdouble *v)
7102{
7103 UNIMPLEMENTED();
7104}
7105
7106void APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
7107{
7108 UNIMPLEMENTED();
7109}
7110
7111void APIENTRY glRasterPos3fv(const GLfloat *v)
7112{
7113 UNIMPLEMENTED();
7114}
7115
7116void APIENTRY glRasterPos3i(GLint x, GLint y, GLint z)
7117{
7118 UNIMPLEMENTED();
7119}
7120
7121void APIENTRY glRasterPos3iv(const GLint *v)
7122{
7123 UNIMPLEMENTED();
7124}
7125
7126void APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z)
7127{
7128 UNIMPLEMENTED();
7129}
7130
7131void APIENTRY glRasterPos3sv(const GLshort *v)
7132{
7133 UNIMPLEMENTED();
7134}
7135
7136void APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
7137{
7138 UNIMPLEMENTED();
7139}
7140
7141void APIENTRY glRasterPos4dv(const GLdouble *v)
7142{
7143 UNIMPLEMENTED();
7144}
7145
7146void APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
7147{
7148 UNIMPLEMENTED();
7149}
7150
7151void APIENTRY glRasterPos4fv(const GLfloat *v)
7152{
7153 UNIMPLEMENTED();
7154}
7155
7156void APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w)
7157{
7158 UNIMPLEMENTED();
7159}
7160
7161void APIENTRY glRasterPos4iv(const GLint *v)
7162{
7163 UNIMPLEMENTED();
7164}
7165
7166void APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
7167{
7168 UNIMPLEMENTED();
7169}
7170
7171void APIENTRY glRasterPos4sv(const GLshort *v)
7172{
7173 UNIMPLEMENTED();
7174}
7175
7176void APIENTRY glReadBuffer(GLenum mode)
7177{
7178 UNIMPLEMENTED();
7179}
7180
7181void APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
7182{
7183 UNIMPLEMENTED();
7184}
7185
7186void APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2)
7187{
7188 UNIMPLEMENTED();
7189}
7190
7191void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
7192{
7193 UNIMPLEMENTED();
7194}
7195
7196void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2)
7197{
7198 UNIMPLEMENTED();
7199}
7200
7201void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2)
7202{
7203 UNIMPLEMENTED();
7204}
7205
7206void APIENTRY glRectiv(const GLint *v1, const GLint *v2)
7207{
7208 UNIMPLEMENTED();
7209}
7210
7211void APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
7212{
7213 UNIMPLEMENTED();
7214}
7215
7216void APIENTRY glRectsv(const GLshort *v1, const GLshort *v2)
7217{
7218 UNIMPLEMENTED();
7219}
7220
7221GLint APIENTRY glRenderMode(GLenum mode)
7222{
7223 UNIMPLEMENTED();
7224 return 0;
7225}
7226
7227void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
7228{
7229 UNIMPLEMENTED();
7230}
7231
7232void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
7233{
7234 TRACE("(*)");
7235
7236 gl::Context *context = gl::getContext();
7237
7238 if(context)
7239 {
7240 if(context->getListIndex() != 0)
7241 {
7242 UNIMPLEMENTED();
7243 }
7244
7245 context->rotate(angle, x, y, z);
7246 }
7247}
7248
7249void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)
7250{
7251 UNIMPLEMENTED();
7252}
7253
7254void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
7255{
7256 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7257
7258 gl::Context *context = gl::getContext();
7259
7260 if(context)
7261 {
7262 if(context->getListIndex() != 0)
7263 {
7264 return context->listCommand(gl::newCommand(glScalef, x, y, z));
7265 }
7266
7267 context->scale(x, y, z);
7268 }
7269}
7270
7271void APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer)
7272{
7273 UNIMPLEMENTED();
7274}
7275
7276void APIENTRY glShadeModel(GLenum mode)
7277{
7278 TRACE("(*)");
7279
7280 gl::Context *context = gl::getContext();
7281
7282 if(context)
7283 {
7284 if(context->getListIndex() != 0)
7285 {
7286 UNIMPLEMENTED();
7287 }
7288
7289 context->setShadeModel(mode);
7290 }
7291}
7292
7293void APIENTRY glTexCoord1d(GLdouble s)
7294{
7295 UNIMPLEMENTED();
7296}
7297
7298void APIENTRY glTexCoord1dv(const GLdouble *v)
7299{
7300 UNIMPLEMENTED();
7301}
7302
7303void APIENTRY glTexCoord1f(GLfloat s)
7304{
7305 UNIMPLEMENTED();
7306}
7307
7308void APIENTRY glTexCoord1fv(const GLfloat *v)
7309{
7310 UNIMPLEMENTED();
7311}
7312
7313void APIENTRY glTexCoord1i(GLint s)
7314{
7315 UNIMPLEMENTED();
7316}
7317
7318void APIENTRY glTexCoord1iv(const GLint *v)
7319{
7320 UNIMPLEMENTED();
7321}
7322
7323void APIENTRY glTexCoord1s(GLshort s)
7324{
7325 UNIMPLEMENTED();
7326}
7327
7328void APIENTRY glTexCoord1sv(const GLshort *v)
7329{
7330 UNIMPLEMENTED();
7331}
7332
7333void APIENTRY glTexCoord2d(GLdouble s, GLdouble t)
7334{
7335 UNIMPLEMENTED();
7336}
7337
7338void APIENTRY glTexCoord2dv(const GLdouble *v)
7339{
7340 UNIMPLEMENTED();
7341}
7342
7343void APIENTRY glTexCoord2f(GLfloat s, GLfloat t)
7344{
7345 TRACE("(GLfloat s = %f, GLfloat t = %f)", s, t);
7346
7347 gl::Context *context = gl::getContext();
7348
7349 if(context)
7350 {
7351 if(context->getListIndex() != 0)
7352 {
7353 UNIMPLEMENTED();
7354 }
7355
7356 //context->texCoord(s, t, 0.0f, 1.0f);
7357 unsigned int texture = context->getActiveTexture();
7358 context->setVertexAttrib(sw::TexCoord0/* + texture*/, s, t, 0.0f, 1.0f);
7359 }
7360}
7361
7362void APIENTRY glTexCoord2fv(const GLfloat *v)
7363{
7364 UNIMPLEMENTED();
7365}
7366
7367void APIENTRY glTexCoord2i(GLint s, GLint t)
7368{
7369 UNIMPLEMENTED();
7370}
7371
7372void APIENTRY glTexCoord2iv(const GLint *v)
7373{
7374 UNIMPLEMENTED();
7375}
7376
7377void APIENTRY glTexCoord2s(GLshort s, GLshort t)
7378{
7379 UNIMPLEMENTED();
7380}
7381
7382void APIENTRY glTexCoord2sv(const GLshort *v)
7383{
7384 UNIMPLEMENTED();
7385}
7386
7387void APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
7388{
7389 UNIMPLEMENTED();
7390}
7391
7392void APIENTRY glTexCoord3dv(const GLdouble *v)
7393{
7394 UNIMPLEMENTED();
7395}
7396
7397void APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
7398{
7399 UNIMPLEMENTED();
7400}
7401
7402void APIENTRY glTexCoord3fv(const GLfloat *v)
7403{
7404 UNIMPLEMENTED();
7405}
7406
7407void APIENTRY glTexCoord3i(GLint s, GLint t, GLint r)
7408{
7409 UNIMPLEMENTED();
7410}
7411
7412void APIENTRY glTexCoord3iv(const GLint *v)
7413{
7414 UNIMPLEMENTED();
7415}
7416
7417void APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r)
7418{
7419 UNIMPLEMENTED();
7420}
7421
7422void APIENTRY glTexCoord3sv(const GLshort *v)
7423{
7424 UNIMPLEMENTED();
7425}
7426
7427void APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
7428{
7429 UNIMPLEMENTED();
7430}
7431
7432void APIENTRY glTexCoord4dv(const GLdouble *v)
7433{
7434 UNIMPLEMENTED();
7435}
7436
7437void APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
7438{
7439 UNIMPLEMENTED();
7440}
7441
7442void APIENTRY glTexCoord4fv(const GLfloat *v)
7443{
7444 UNIMPLEMENTED();
7445}
7446
7447void APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q)
7448{
7449 UNIMPLEMENTED();
7450}
7451
7452void APIENTRY glTexCoord4iv(const GLint *v)
7453{
7454 UNIMPLEMENTED();
7455}
7456
7457void APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
7458{
7459 UNIMPLEMENTED();
7460}
7461
7462void APIENTRY glTexCoord4sv(const GLshort *v)
7463{
7464 UNIMPLEMENTED();
7465}
7466
7467void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
7468{
7469 TRACE("(*)");
7470
7471 gl::Context *context = gl::getContext();
7472
7473 if(context)
7474 {
7475 GLenum texture = context->getClientActiveTexture();
7476
7477 glVertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
7478 }
7479}
7480
7481void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
7482{
7483 UNIMPLEMENTED();
7484}
7485
7486void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
7487{
7488 UNIMPLEMENTED();
7489}
7490
7491void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
7492{
7493 UNIMPLEMENTED();
7494}
7495
7496void APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
7497{
7498 UNIMPLEMENTED();
7499}
7500
7501void APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param)
7502{
7503 UNIMPLEMENTED();
7504}
7505
7506void APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
7507{
7508 UNIMPLEMENTED();
7509}
7510
7511void APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param)
7512{
7513 UNIMPLEMENTED();
7514}
7515
7516void APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
7517{
7518 UNIMPLEMENTED();
7519}
7520
7521void APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param)
7522{
7523 UNIMPLEMENTED();
7524}
7525
7526void APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params)
7527{
7528 UNIMPLEMENTED();
7529}
7530
7531void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
7532{
7533 UNIMPLEMENTED();
7534}
7535
7536void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
7537{
7538 UNIMPLEMENTED();
7539}
7540
7541void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)
7542{
7543 TRACE("(*)");
7544
7545 gl::Context *context = gl::getContext();
7546
7547 if(context)
7548 {
7549 if(context->getListIndex() != 0)
7550 {
7551 return context->listCommand(gl::newCommand(glTranslated, x, y, z));
7552 }
7553
7554 context->translate(x, y, z); // FIXME
7555 }
7556}
7557
7558void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
7559{
7560 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7561
7562 gl::Context *context = gl::getContext();
7563
7564 if(context)
7565 {
7566 if(context->getListIndex() != 0)
7567 {
7568 return context->listCommand(gl::newCommand(glTranslatef, x, y, z));
7569 }
7570
7571 context->translate(x, y, z);
7572 }
7573}
7574
7575void APIENTRY glVertex2d(GLdouble x, GLdouble y)
7576{
7577 UNIMPLEMENTED();
7578}
7579
7580void APIENTRY glVertex2dv(const GLdouble *v)
7581{
7582 UNIMPLEMENTED();
7583}
7584
7585void APIENTRY glVertex2f(GLfloat x, GLfloat y)
7586{
7587 UNIMPLEMENTED();
7588}
7589
7590void APIENTRY glVertex2fv(const GLfloat *v)
7591{
7592 UNIMPLEMENTED();
7593}
7594
7595void APIENTRY glVertex2i(GLint x, GLint y)
7596{
7597 UNIMPLEMENTED();
7598}
7599
7600void APIENTRY glVertex2iv(const GLint *v)
7601{
7602 UNIMPLEMENTED();
7603}
7604
7605void APIENTRY glVertex2s(GLshort x, GLshort y)
7606{
7607 UNIMPLEMENTED();
7608}
7609
7610void APIENTRY glVertex2sv(const GLshort *v)
7611{
7612 UNIMPLEMENTED();
7613}
7614
7615void APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
7616{
7617 UNIMPLEMENTED();
7618}
7619
7620void APIENTRY glVertex3dv(const GLdouble *v)
7621{
7622 UNIMPLEMENTED();
7623}
7624
7625void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
7626{
7627 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7628
7629 gl::Context *context = gl::getContext();
7630
7631 if(context)
7632 {
7633 if(context->getListIndex() != 0)
7634 {
7635 UNIMPLEMENTED();
7636 }
7637
7638 context->position(x, y, z, 1.0f);
7639 }
7640}
7641
7642void APIENTRY glVertex3fv(const GLfloat *v)
7643{
7644 UNIMPLEMENTED();
7645}
7646
7647void APIENTRY glVertex3i(GLint x, GLint y, GLint z)
7648{
7649 UNIMPLEMENTED();
7650}
7651
7652void APIENTRY glVertex3iv(const GLint *v)
7653{
7654 UNIMPLEMENTED();
7655}
7656
7657void APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z)
7658{
7659 UNIMPLEMENTED();
7660}
7661
7662void APIENTRY glVertex3sv(const GLshort *v)
7663{
7664 UNIMPLEMENTED();
7665}
7666
7667void APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
7668{
7669 UNIMPLEMENTED();
7670}
7671
7672void APIENTRY glVertex4dv(const GLdouble *v)
7673{
7674 UNIMPLEMENTED();
7675}
7676
7677void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
7678{
7679 UNIMPLEMENTED();
7680}
7681
7682void APIENTRY glVertex4fv(const GLfloat *v)
7683{
7684 UNIMPLEMENTED();
7685}
7686
7687void APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w)
7688{
7689 UNIMPLEMENTED();
7690}
7691
7692void APIENTRY glVertex4iv(const GLint *v)
7693{
7694 UNIMPLEMENTED();
7695}
7696
7697void APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
7698{
7699 UNIMPLEMENTED();
7700}
7701
7702void APIENTRY glVertex4sv(const GLshort *v)
7703{
7704 UNIMPLEMENTED();
7705}
7706
7707void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
7708{
Nicolas Capens4be33702015-04-28 15:13:30 -07007709 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 -05007710
7711 glVertexAttribPointer(sw::Position, size, type, false, stride, pointer);
7712}
7713
7714void APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) {UNIMPLEMENTED();}
7715void APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}
7716void 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();}
7717void APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
7718
7719void APIENTRY glClientActiveTexture(GLenum texture)
7720{
7721 TRACE("(GLenum texture = 0x%X)", texture);
7722
7723 switch(texture)
7724 {
7725 case GL_TEXTURE0:
7726 case GL_TEXTURE1:
7727 break;
7728 default:
7729 UNIMPLEMENTED();
7730 UNREACHABLE();
7731 }
7732
7733 gl::Context *context = gl::getContext();
7734
7735 if(context)
7736 {
7737 context->clientActiveTexture(texture);
7738 }
7739}
7740
7741void APIENTRY glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7742void APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7743void APIENTRY glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7744void 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();}
7745void APIENTRY glGetCompressedTexImage(GLenum target, GLint level, void *img) {UNIMPLEMENTED();}
7746void APIENTRY glMultiTexCoord1f(GLenum target, GLfloat s) {UNIMPLEMENTED();}
7747void APIENTRY glMultiTexCoord1d(GLenum target, GLdouble s) {UNIMPLEMENTED();}
7748
7749void APIENTRY glMultiTexCoord2f(GLenum texture, GLfloat s, GLfloat t)
7750{
7751 TRACE("(GLenum texture = 0x%X, GLfloat s = %f, GLfloat t = %f)", texture, s, t);
7752
7753 gl::Context *context = gl::getContext();
7754
7755 if(context)
7756 {
7757 if(context->getListIndex() != 0)
7758 {
7759 UNIMPLEMENTED();
7760 }
7761
7762 //context->texCoord(s, t, 0.0f, 1.0f);
7763 context->setVertexAttrib(sw::TexCoord0 + (texture - GL_TEXTURE0), s, t, 0.0f, 1.0f);
7764 }
7765}
7766
7767void APIENTRY glMultiTexCoord2d(GLenum target, GLdouble s, GLdouble t) {UNIMPLEMENTED();}
7768void APIENTRY glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {UNIMPLEMENTED();}
7769void APIENTRY glMultiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r) {UNIMPLEMENTED();}
7770void APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {UNIMPLEMENTED();}
7771void APIENTRY glMultiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) {UNIMPLEMENTED();}
7772void APIENTRY glLoadTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
7773void APIENTRY glLoadTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
7774void APIENTRY glMultTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
7775void APIENTRY glMultTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
7776void APIENTRY glFogCoordf(GLfloat coord) {UNIMPLEMENTED();}
7777void APIENTRY glFogCoordd(GLdouble coord) {UNIMPLEMENTED();}
7778void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
7779void APIENTRY glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) {UNIMPLEMENTED();}
7780void APIENTRY glPointParameteri(GLenum pname, GLint param) {UNIMPLEMENTED();}
7781void APIENTRY glPointParameterf(GLenum pname, GLfloat param) {UNIMPLEMENTED();}
7782void APIENTRY glPointParameteriv(GLenum pname, const GLint *params) {UNIMPLEMENTED();}
7783void APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params) {UNIMPLEMENTED();}
7784void APIENTRY glSecondaryColor3b(GLbyte red, GLbyte green, GLbyte blue) {UNIMPLEMENTED();}
7785void APIENTRY glSecondaryColor3f(GLfloat red, GLfloat green, GLfloat blue) {UNIMPLEMENTED();}
7786void APIENTRY glSecondaryColor3d(GLdouble red, GLdouble green, GLdouble blue) {UNIMPLEMENTED();}
7787void APIENTRY glSecondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue) {UNIMPLEMENTED();}
7788void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
7789void APIENTRY glWindowPos2f(GLfloat x, GLfloat y) {UNIMPLEMENTED();}
7790void APIENTRY glWindowPos2d(GLdouble x, GLdouble y) {UNIMPLEMENTED();}
7791void APIENTRY glWindowPos2i(GLint x, GLint y) {UNIMPLEMENTED();}
7792void APIENTRY glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) {UNIMPLEMENTED();}
7793void APIENTRY glWindowPos3d(GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
7794void APIENTRY glWindowPos3i(GLint x, GLint y, GLint z) {UNIMPLEMENTED();}
7795void APIENTRY glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data) {UNIMPLEMENTED();}
7796void *APIENTRY glMapBuffer(GLenum target, GLenum access) {UNIMPLEMENTED(); return 0;}
7797GLboolean APIENTRY glUnmapBuffer(GLenum target) {UNIMPLEMENTED(); return GL_FALSE;}
7798void APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params) {UNIMPLEMENTED();}
7799void APIENTRY glGenQueries(GLsizei n, GLuint *ids) {UNIMPLEMENTED();}
7800void APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids) {UNIMPLEMENTED();}
7801GLboolean APIENTRY glIsQuery(GLuint id) {UNIMPLEMENTED(); return 0;}
7802void APIENTRY glBeginQuery(GLenum target, GLuint id) {UNIMPLEMENTED();}
7803void APIENTRY glEndQuery(GLenum target) {UNIMPLEMENTED();}
7804void APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params) {UNIMPLEMENTED();}
7805void APIENTRY glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) {UNIMPLEMENTED();}
7806void APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) {UNIMPLEMENTED();}
7807void APIENTRY glVertexAttrib1s(GLuint index, GLshort x) {UNIMPLEMENTED();}
7808void APIENTRY glVertexAttrib1d(GLuint index, GLdouble x) {UNIMPLEMENTED();}
7809void APIENTRY glVertexAttrib2s(GLuint index, GLshort x, GLshort y) {UNIMPLEMENTED();}
7810void APIENTRY glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y) {UNIMPLEMENTED();}
7811void APIENTRY glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z) {UNIMPLEMENTED();}
7812void APIENTRY glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
7813void APIENTRY glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) {UNIMPLEMENTED();}
7814void APIENTRY glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {UNIMPLEMENTED();}
7815void APIENTRY glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {UNIMPLEMENTED();}
7816void APIENTRY glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {UNIMPLEMENTED();}
7817void APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs) {UNIMPLEMENTED();}
7818void APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7819void APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7820void APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7821void APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7822void APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7823void APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7824
7825void APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {UNIMPLEMENTED();}
7826void APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
7827void APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {UNIMPLEMENTED();}
7828
7829BOOL WINAPI wglSwapIntervalEXT(int interval)
7830{
7831 gl::Surface *drawSurface = static_cast<gl::Surface*>(gl::getCurrentDrawSurface());
7832
7833 if(drawSurface)
7834 {
7835 drawSurface->setSwapInterval(interval);
7836 return TRUE;
7837 }
7838
7839 SetLastError(ERROR_DC_NOT_FOUND);
7840 return FALSE;
7841}
7842
7843int WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)
7844{
7845 TRACE("(*)");
7846
7847 return 1;
7848}
7849
7850BOOL WINAPI wglCopyContext(HGLRC, HGLRC, UINT)
7851{
7852 UNIMPLEMENTED();
7853 return FALSE;
7854}
7855
7856HGLRC WINAPI wglCreateContext(HDC hdc)
7857{
7858 TRACE("(*)");
7859
7860 gl::Display *display = gl::Display::getDisplay(hdc);
7861 display->initialize();
7862
7863 gl::Context *context = display->createContext(nullptr);
7864
7865 return (HGLRC)context;
7866}
7867
7868HGLRC WINAPI wglCreateLayerContext(HDC, int)
7869{
7870 UNIMPLEMENTED();
7871 return 0;
7872}
7873
7874BOOL WINAPI wglDeleteContext(HGLRC context)
7875{
7876 gl::Display *display = gl::getDisplay();
7877
7878 if(display && context)
7879 {
7880 display->destroyContext(reinterpret_cast<gl::Context*>(context));
7881
7882 return TRUE;
7883 }
7884
7885 return FALSE;
7886}
7887
7888BOOL WINAPI wglDescribeLayerPlane(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR)
7889{
7890 UNIMPLEMENTED();
7891 return FALSE;
7892}
7893
7894int WINAPI wglDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
7895{
7896 TRACE("(*)");
7897
7898 ASSERT(nBytes == sizeof(PIXELFORMATDESCRIPTOR)); // FIXME
7899
7900 ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
7901 ppfd->nVersion = 1;
7902 ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
7903 ppfd->iPixelType = PFD_TYPE_RGBA;
7904 ppfd->cColorBits = 32;
7905 ppfd->cRedBits = 8;
7906 ppfd->cRedShift = 16;
7907 ppfd->cGreenBits = 8;
7908 ppfd->cGreenShift = 8;
7909 ppfd->cBlueBits = 8;
7910 ppfd->cBlueShift = 0;
7911 ppfd->cAlphaBits = 0;
7912 ppfd->cAlphaShift = 24;
7913 ppfd->cAccumBits = 0;
7914 ppfd->cAccumRedBits = 0;
7915 ppfd->cAccumGreenBits = 0;
7916 ppfd->cAccumBlueBits = 0;
7917 ppfd->cAccumAlphaBits = 0;
7918 ppfd->cDepthBits = 24;
7919 ppfd->cStencilBits = 0;
7920 ppfd->cAuxBuffers = 0;
7921 ppfd->iLayerType = 0;
7922 ppfd->bReserved = 0;
7923 ppfd->dwLayerMask = 0;
7924 ppfd->dwVisibleMask = 0;
7925 ppfd->dwDamageMask = 0;
7926
7927 return 1;
7928}
7929
7930HGLRC WINAPI wglGetCurrentContext(VOID)
7931{
7932 TRACE("(*)");
7933 return (HGLRC)gl::getContext();
7934}
7935
7936HDC WINAPI wglGetCurrentDC(VOID)
7937{
7938 TRACE("(*)");
7939 gl::Display *display = gl::getDisplay();
7940 return display ? display->getNativeDisplay() : 0;
7941}
7942
7943void WINAPI wglGetDefaultProcAddress()
7944{
7945 UNIMPLEMENTED();
7946}
7947
7948int WINAPI wglGetLayerPaletteEntries(HDC, int, int, int, COLORREF*)
7949{
7950 UNIMPLEMENTED();
7951 return 0;
7952}
7953
7954void WINAPI wglGetPixelFormat()
7955{
7956 UNIMPLEMENTED();
7957}
7958
7959const char *WINAPI wglGetExtensionsStringARB(HDC hdc)
7960{
7961 TRACE("(*)");
7962
7963 return "GL_ARB_framebuffer_object "
7964 "WGL_EXT_extensions_string "
7965 "WGL_EXT_swap_control";
7966}
7967
7968const char *WINAPI wglGetExtensionsStringEXT()
7969{
7970 TRACE("(*)");
7971 return wglGetExtensionsStringARB(0);
7972}
7973
7974PROC WINAPI wglGetProcAddress(LPCSTR lpszProc)
7975{
7976 TRACE("(LPCSTR lpszProc = \"%s\")", lpszProc);
7977
Nicolas Capens264f1522015-01-09 17:21:17 -05007978 struct Extension
7979 {
7980 const char *name;
Nicolas Capensa9b49372015-01-30 00:33:26 -05007981 PROC address;
Nicolas Capens264f1522015-01-09 17:21:17 -05007982 };
7983
7984 static const Extension glExtensions[] =
7985 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05007986 #define EXT(function) {#function, (PROC)function}
7987
7988 // Core 2.1
7989 EXT(glDrawRangeElements),
7990 EXT(glTexImage3D),
7991 EXT(glTexSubImage3D),
7992 EXT(glCopyTexSubImage3D),
7993 EXT(glActiveTexture),
7994 EXT(glClientActiveTexture),
7995 EXT(glCompressedTexImage1D),
7996 EXT(glCompressedTexImage2D),
7997 EXT(glCompressedTexImage3D),
7998 EXT(glCompressedTexSubImage1D),
7999 EXT(glCompressedTexSubImage2D),
8000 EXT(glCompressedTexSubImage3D),
8001 EXT(glGetCompressedTexImage),
8002 EXT(glMultiTexCoord1f),
8003 EXT(glMultiTexCoord1d),
8004 EXT(glMultiTexCoord2f),
8005 EXT(glMultiTexCoord2d),
8006 EXT(glMultiTexCoord3f),
8007 EXT(glMultiTexCoord3d),
8008 EXT(glMultiTexCoord4f),
8009 EXT(glMultiTexCoord4d),
8010 EXT(glLoadTransposeMatrixf),
8011 EXT(glLoadTransposeMatrixd),
8012 EXT(glMultTransposeMatrixf),
8013 EXT(glMultTransposeMatrixd),
8014 EXT(glSampleCoverage),
8015 EXT(glBlendEquation),
8016 EXT(glBlendColor),
8017 EXT(glFogCoordf),
8018 EXT(glFogCoordd),
8019 EXT(glFogCoordPointer),
8020 EXT(glMultiDrawArrays),
8021 EXT(glPointParameteri),
8022 EXT(glPointParameterf),
8023 EXT(glPointParameteriv),
8024 EXT(glPointParameterfv),
8025 EXT(glSecondaryColor3b),
8026 EXT(glSecondaryColor3f),
8027 EXT(glSecondaryColor3d),
8028 EXT(glSecondaryColor3ub),
8029 EXT(glSecondaryColorPointer),
8030 EXT(glBlendFuncSeparate),
8031 EXT(glWindowPos2f),
8032 EXT(glWindowPos2d),
8033 EXT(glWindowPos2i),
8034 EXT(glWindowPos3f),
8035 EXT(glWindowPos3d),
8036 EXT(glWindowPos3i),
8037 EXT(glBindBuffer),
8038 EXT(glDeleteBuffers),
8039 EXT(glGenBuffers),
8040 EXT(glIsBuffer),
8041 EXT(glBufferData),
8042 EXT(glBufferSubData),
8043 EXT(glGetBufferSubData),
8044 EXT(glMapBuffer),
8045 EXT(glUnmapBuffer),
8046 EXT(glGetBufferParameteriv),
8047 EXT(glGetBufferPointerv),
8048 EXT(glGenQueries),
8049 EXT(glDeleteQueries),
8050 EXT(glIsQuery),
8051 EXT(glBeginQuery),
8052 EXT(glEndQuery),
8053 EXT(glGetQueryiv),
8054 EXT(glGetQueryObjectiv),
8055 EXT(glGetQueryObjectuiv),
8056 EXT(glShaderSource),
8057 EXT(glCreateShader),
8058 EXT(glIsShader),
8059 EXT(glCompileShader),
8060 EXT(glDeleteShader),
8061 EXT(glCreateProgram),
8062 EXT(glIsProgram),
8063 EXT(glAttachShader),
8064 EXT(glDetachShader),
8065 EXT(glLinkProgram),
8066 EXT(glUseProgram),
8067 EXT(glValidateProgram),
8068 EXT(glDeleteProgram),
8069 EXT(glUniform1f),
8070 EXT(glUniform2f),
8071 EXT(glUniform3f),
8072 EXT(glUniform4f),
8073 EXT(glUniform1i),
8074 EXT(glUniform2i),
8075 EXT(glUniform3i),
8076 EXT(glUniform4i),
8077 EXT(glUniform1fv),
8078 EXT(glUniform2fv),
8079 EXT(glUniform3fv),
8080 EXT(glUniform4fv),
8081 EXT(glUniform1iv),
8082 EXT(glUniform2iv),
8083 EXT(glUniform3iv),
8084 EXT(glUniform4iv),
8085 EXT(glUniformMatrix2fv),
8086 EXT(glUniformMatrix3fv),
8087 EXT(glUniformMatrix4fv),
8088 EXT(glGetShaderiv),
8089 EXT(glGetProgramiv),
8090 EXT(glGetShaderInfoLog),
8091 EXT(glGetProgramInfoLog),
8092 EXT(glGetAttachedShaders),
8093 EXT(glGetUniformLocation),
8094 EXT(glGetActiveUniform),
8095 EXT(glGetUniformfv),
8096 EXT(glGetUniformiv),
8097 EXT(glGetShaderSource),
8098 EXT(glVertexAttrib1s),
8099 EXT(glVertexAttrib1f),
8100 EXT(glVertexAttrib1d),
8101 EXT(glVertexAttrib2s),
8102 EXT(glVertexAttrib2f),
8103 EXT(glVertexAttrib2d),
8104 EXT(glVertexAttrib3s),
8105 EXT(glVertexAttrib3f),
8106 EXT(glVertexAttrib3d),
8107 EXT(glVertexAttrib4s),
8108 EXT(glVertexAttrib4f),
8109 EXT(glVertexAttrib4d),
8110 EXT(glVertexAttrib4Nub),
8111 EXT(glVertexAttribPointer),
8112 EXT(glEnableVertexAttribArray),
8113 EXT(glDisableVertexAttribArray),
8114 EXT(glGetVertexAttribfv),
8115 EXT(glGetVertexAttribdv),
8116 EXT(glGetVertexAttribiv),
8117 EXT(glGetVertexAttribPointerv),
8118 EXT(glBindAttribLocation),
8119 EXT(glGetActiveAttrib),
8120 EXT(glGetAttribLocation),
8121 EXT(glDrawBuffers),
8122 EXT(glStencilOpSeparate),
8123 EXT(glStencilFuncSeparate),
8124 EXT(glStencilMaskSeparate),
8125 EXT(glBlendEquationSeparate),
8126 EXT(glUniformMatrix2x3fv),
8127 EXT(glUniformMatrix3x2fv),
8128 EXT(glUniformMatrix2x4fv),
8129 EXT(glUniformMatrix4x2fv),
8130 EXT(glUniformMatrix3x4fv),
8131 EXT(glUniformMatrix4x3fv),
8132 EXT(glGenFencesNV),
8133 EXT(glDeleteFencesNV),
8134 EXT(glSetFenceNV),
8135 EXT(glTestFenceNV),
8136 EXT(glFinishFenceNV),
8137 EXT(glIsFenceNV),
8138 EXT(glGetFenceivNV),
8139
8140 EXT(glIsRenderbuffer),
8141 EXT(glBindRenderbuffer),
8142 EXT(glDeleteRenderbuffers),
8143 EXT(glGenRenderbuffers),
8144 EXT(glRenderbufferStorage),
8145 EXT(glGetRenderbufferParameteriv),
8146 EXT(glIsFramebuffer),
8147 EXT(glBindFramebuffer),
8148 EXT(glDeleteFramebuffers),
8149 EXT(glGenFramebuffers),
8150 EXT(glCheckFramebufferStatus),
8151 EXT(glFramebufferTexture1D),
8152 EXT(glFramebufferTexture2D),
8153 EXT(glFramebufferTexture3D),
8154 EXT(glFramebufferRenderbuffer),
8155 EXT(glGetFramebufferAttachmentParameteriv),
8156 EXT(glGenerateMipmap),
8157 EXT(glReleaseShaderCompiler),
8158 EXT(glShaderBinary),
8159 EXT(glGetShaderPrecisionFormat),
8160 EXT(glDepthRangef),
8161 EXT(glClearDepthf),
Nicolas Capens264f1522015-01-09 17:21:17 -05008162
Nicolas Capensa9b49372015-01-30 00:33:26 -05008163 // ARB
8164 EXT(wglGetExtensionsStringARB),
8165 EXT(glIsRenderbuffer),
8166 EXT(glBindRenderbuffer),
8167 EXT(glDeleteRenderbuffers),
8168 EXT(glGenRenderbuffers),
8169 EXT(glRenderbufferStorage),
8170 EXT(glRenderbufferStorageMultisample),
8171 EXT(glGetRenderbufferParameteriv),
8172 EXT(glIsFramebuffer),
8173 EXT(glBindFramebuffer),
8174 EXT(glDeleteFramebuffers),
8175 EXT(glGenFramebuffers),
8176 EXT(glCheckFramebufferStatus),
8177 EXT(glFramebufferTexture1D),
8178 EXT(glFramebufferTexture2D),
8179 EXT(glFramebufferTexture3D),
8180 EXT(glFramebufferTextureLayer),
8181 EXT(glFramebufferRenderbuffer),
8182 EXT(glGetFramebufferAttachmentParameteriv),
8183 EXT(glBlitFramebuffer),
8184 EXT(glGenerateMipmap),
Nicolas Capens264f1522015-01-09 17:21:17 -05008185
Nicolas Capensa9b49372015-01-30 00:33:26 -05008186 // EXT
8187 EXT(wglSwapIntervalEXT),
8188 EXT(wglGetExtensionsStringEXT),
8189 #undef EXT
Nicolas Capens264f1522015-01-09 17:21:17 -05008190 };
8191
8192 for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
8193 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05008194 if(strcmp(lpszProc, glExtensions[ext].name) == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05008195 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05008196 return (PROC)glExtensions[ext].address;
Nicolas Capens264f1522015-01-09 17:21:17 -05008197 }
8198 }
8199
Nicolas Capensa9b49372015-01-30 00:33:26 -05008200 FARPROC proc = GetProcAddress(GetModuleHandle("opengl32.dll"), lpszProc); // FIXME?
8201
8202 if(proc)
8203 {
8204 return proc;
8205 }
8206
8207 TRACE("(LPCSTR lpszProc = \"%s\") NOT FOUND!!!", lpszProc);
8208
8209 return 0;
Nicolas Capens264f1522015-01-09 17:21:17 -05008210}
8211
Nicolas Capensa9b49372015-01-30 00:33:26 -05008212BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
8213{
8214 TRACE("(*)");
8215
8216 if(hdc && hglrc)
8217 {
8218 gl::Display *display = (gl::Display*)gl::Display::getDisplay(hdc);
8219 gl::makeCurrent((gl::Context*)hglrc, display, display->getPrimarySurface());
8220 gl::setCurrentDrawSurface(display->getPrimarySurface());
8221 gl::setCurrentDisplay(display);
8222 }
8223 else
8224 {
8225 gl::makeCurrent(0, 0, 0);
8226 }
8227
8228 return TRUE;
8229}
8230
8231BOOL WINAPI wglRealizeLayerPalette(HDC, int, BOOL)
8232{
8233 UNIMPLEMENTED();
8234 return FALSE;
8235}
8236
8237int WINAPI wglSetLayerPaletteEntries(HDC, int, int, int, CONST COLORREF*)
8238{
8239 UNIMPLEMENTED();
8240 return 0;
8241}
8242
8243BOOL WINAPI wglSetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
8244{
8245 TRACE("(*)");
8246 //UNIMPLEMENTED();
8247
8248 return TRUE;
8249}
8250
8251BOOL WINAPI wglShareLists(HGLRC, HGLRC)
8252{
8253 UNIMPLEMENTED();
8254 return FALSE;
8255}
8256
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008257BOOL WINAPI wglSwapBuffers(HDC hdc)
Nicolas Capensa9b49372015-01-30 00:33:26 -05008258{
8259 TRACE("(*)");
8260
8261 gl::Display *display = gl::getDisplay();
8262
8263 if(display)
8264 {
8265 display->getPrimarySurface()->swap();
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008266 return TRUE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008267 }
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008268
8269 return FALSE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008270}
8271
8272BOOL WINAPI wglSwapLayerBuffers(HDC, UINT)
8273{
8274 UNIMPLEMENTED();
8275 return FALSE;
8276}
8277
8278DWORD WINAPI wglSwapMultipleBuffers(UINT, CONST WGLSWAP*)
8279{
8280 UNIMPLEMENTED();
8281 return 0;
8282}
8283
8284BOOL WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD)
8285{
8286 UNIMPLEMENTED();
8287 return FALSE;
8288}
8289
8290BOOL WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD)
8291{
8292 UNIMPLEMENTED();
8293 return FALSE;
8294}
8295
8296BOOL WINAPI wglUseFontOutlinesA(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
8297{
8298 UNIMPLEMENTED();
8299 return FALSE;
8300}
8301
8302BOOL WINAPI wglUseFontOutlinesW(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
8303{
8304 UNIMPLEMENTED();
8305 return FALSE;
8306}
8307
8308void APIENTRY Register(const char *licenseKey)
Nicolas Capens264f1522015-01-09 17:21:17 -05008309{
8310 RegisterLicenseKey(licenseKey);
8311}
8312
8313}