blob: fa3073d3e04aa8f2bfcaa9b506618fa3cf495fd5 [file] [log] [blame]
Nicolas Capens264f1522015-01-09 17:21:17 -05001// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2013 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
Nicolas Capens79eef882015-01-09 17:38:27 -050011// libGL.cpp: Implements the exported OpenGL functions.
Nicolas Capens264f1522015-01-09 17:21:17 -050012
13#include "main.h"
14#include "mathutil.h"
15#include "utilities.h"
16#include "Buffer.h"
17#include "Context.h"
18#include "Fence.h"
19#include "Framebuffer.h"
20#include "Program.h"
21#include "Renderbuffer.h"
22#include "Shader.h"
23#include "Texture.h"
24#include "Query.h"
25#include "common/debug.h"
26#include "Common/Version.h"
27#include "Main/Register.hpp"
28
Nicolas Capensa9b49372015-01-30 00:33:26 -050029#define _GDI32_
30#include <windows.h>
31#include <GL/GL.h>
Nicolas Capensa9b49372015-01-30 00:33:26 -050032#include <GL/glext.h>
Nicolas Capens264f1522015-01-09 17:21:17 -050033
Nicolas Capens264f1522015-01-09 17:21:17 -050034#include <limits>
35
36static bool validImageSize(GLint level, GLsizei width, GLsizei height)
37{
Nicolas Capensf4486fd2015-01-22 11:10:37 -050038 if(level < 0 || level >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
Nicolas Capens264f1522015-01-09 17:21:17 -050039 {
40 return false;
41 }
42
43 return true;
44}
45
Nicolas Capensf4486fd2015-01-22 11:10:37 -050046static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, gl::Texture *texture)
Nicolas Capens264f1522015-01-09 17:21:17 -050047{
48 if(!texture)
49 {
50 return error(GL_INVALID_OPERATION, false);
51 }
52
53 if(compressed != texture->isCompressed(target, level))
54 {
55 return error(GL_INVALID_OPERATION, false);
56 }
57
Maxime Grégoire5e582162015-07-16 12:52:57 -040058 if(format != GL_NONE && format != texture->getFormat(target, level) && target != GL_TEXTURE_1D)
Nicolas Capens264f1522015-01-09 17:21:17 -050059 {
60 return error(GL_INVALID_OPERATION, false);
61 }
62
63 if(compressed)
64 {
65 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
66 (height % 4 != 0 && height != texture->getHeight(target, 0)))
67 {
68 return error(GL_INVALID_OPERATION, false);
69 }
70 }
71
72 if(xoffset + width > texture->getWidth(target, level) ||
73 yoffset + height > texture->getHeight(target, level))
74 {
75 return error(GL_INVALID_VALUE, false);
76 }
77
78 return true;
79}
80
81// Check for combinations of format and type that are valid for ReadPixels
82static bool validReadFormatType(GLenum format, GLenum type)
83{
84 switch(format)
85 {
86 case GL_RGBA:
87 switch(type)
88 {
89 case GL_UNSIGNED_BYTE:
90 break;
91 default:
92 return false;
93 }
94 break;
95 case GL_BGRA_EXT:
96 switch(type)
97 {
98 case GL_UNSIGNED_BYTE:
Nicolas Capensa9b49372015-01-30 00:33:26 -050099 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
100 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
Nicolas Capens264f1522015-01-09 17:21:17 -0500101 break;
102 default:
103 return false;
104 }
105 break;
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500106 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500107 switch(type)
108 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500109 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
Nicolas Capens264f1522015-01-09 17:21:17 -0500110 break;
111 default:
112 return false;
113 }
114 break;
115 default:
116 return false;
117 }
118
119 return true;
120}
121
122extern "C"
123{
124
Nicolas Capensa9b49372015-01-30 00:33:26 -0500125void APIENTRY glActiveTexture(GLenum texture)
Nicolas Capens264f1522015-01-09 17:21:17 -0500126{
127 TRACE("(GLenum texture = 0x%X)", texture);
128
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500129 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500130
131 if(context)
132 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500133 if(context->getListIndex() != 0)
134 {
135 UNIMPLEMENTED();
136 }
137
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500138 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
Nicolas Capens264f1522015-01-09 17:21:17 -0500139 {
140 return error(GL_INVALID_ENUM);
141 }
142
143 context->setActiveSampler(texture - GL_TEXTURE0);
144 }
145}
146
Nicolas Capensa9b49372015-01-30 00:33:26 -0500147void APIENTRY glAttachShader(GLuint program, GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -0500148{
149 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
150
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500151 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500152
153 if(context)
154 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500155 gl::Program *programObject = context->getProgram(program);
156 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -0500157
158 if(!programObject)
159 {
160 if(context->getShader(program))
161 {
162 return error(GL_INVALID_OPERATION);
163 }
164 else
165 {
166 return error(GL_INVALID_VALUE);
167 }
168 }
169
170 if(!shaderObject)
171 {
172 if(context->getProgram(shader))
173 {
174 return error(GL_INVALID_OPERATION);
175 }
176 else
177 {
178 return error(GL_INVALID_VALUE);
179 }
180 }
181
182 if(!programObject->attachShader(shaderObject))
183 {
184 return error(GL_INVALID_OPERATION);
185 }
186 }
187}
188
Nicolas Capensa9b49372015-01-30 00:33:26 -0500189void APIENTRY glBeginQueryEXT(GLenum target, GLuint name)
Nicolas Capens264f1522015-01-09 17:21:17 -0500190{
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500191 TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
Nicolas Capens264f1522015-01-09 17:21:17 -0500192
193 switch(target)
194 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500195 case GL_ANY_SAMPLES_PASSED:
196 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
Nicolas Capens264f1522015-01-09 17:21:17 -0500197 break;
198 default:
199 return error(GL_INVALID_ENUM);
200 }
201
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500202 if(name == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -0500203 {
204 return error(GL_INVALID_OPERATION);
205 }
206
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500207 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500208
209 if(context)
210 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500211 if(context->getListIndex() != 0)
212 {
213 UNIMPLEMENTED();
214 }
215
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500216 context->beginQuery(target, name);
Nicolas Capens264f1522015-01-09 17:21:17 -0500217 }
218}
219
Nicolas Capensa9b49372015-01-30 00:33:26 -0500220void APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -0500221{
222 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
223
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500224 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -0500225 {
226 return error(GL_INVALID_VALUE);
227 }
228
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500229 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500230
231 if(context)
232 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500233 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -0500234
235 if(!programObject)
236 {
237 if(context->getShader(program))
238 {
239 return error(GL_INVALID_OPERATION);
240 }
241 else
242 {
243 return error(GL_INVALID_VALUE);
244 }
245 }
246
247 if(strncmp(name, "gl_", 3) == 0)
248 {
249 return error(GL_INVALID_OPERATION);
250 }
251
252 programObject->bindAttributeLocation(index, name);
253 }
254}
255
Nicolas Capensa9b49372015-01-30 00:33:26 -0500256void APIENTRY glBindBuffer(GLenum target, GLuint buffer)
Nicolas Capens264f1522015-01-09 17:21:17 -0500257{
258 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
259
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500260 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500261
262 if(context)
263 {
264 switch(target)
265 {
266 case GL_ARRAY_BUFFER:
267 context->bindArrayBuffer(buffer);
268 return;
269 case GL_ELEMENT_ARRAY_BUFFER:
270 context->bindElementArrayBuffer(buffer);
271 return;
272 default:
273 return error(GL_INVALID_ENUM);
274 }
275 }
276}
277
Nicolas Capensa9b49372015-01-30 00:33:26 -0500278void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -0500279{
280 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
281
Nicolas Capensa9b49372015-01-30 00:33:26 -0500282 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500283 {
284 return error(GL_INVALID_ENUM);
285 }
286
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500287 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500288
289 if(context)
290 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500291 if(context->getListIndex() != 0)
292 {
293 UNIMPLEMENTED();
294 }
295
296 if(target == GL_READ_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
Nicolas Capens264f1522015-01-09 17:21:17 -0500297 {
298 context->bindReadFramebuffer(framebuffer);
299 }
Nicolas Capensa9b49372015-01-30 00:33:26 -0500300
301 if(target == GL_DRAW_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
Nicolas Capens264f1522015-01-09 17:21:17 -0500302 {
303 context->bindDrawFramebuffer(framebuffer);
304 }
305 }
306}
307
Nicolas Capensa9b49372015-01-30 00:33:26 -0500308void APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -0500309{
310 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
311
312 if(target != GL_RENDERBUFFER)
313 {
314 return error(GL_INVALID_ENUM);
315 }
316
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500317 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500318
319 if(context)
320 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500321 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -0500322 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500323 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -0500324 }
325
326 context->bindRenderbuffer(renderbuffer);
327 }
328}
329
Nicolas Capensa9b49372015-01-30 00:33:26 -0500330void APIENTRY glBindTexture(GLenum target, GLuint texture)
Nicolas Capens264f1522015-01-09 17:21:17 -0500331{
332 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
333
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500334 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500335
336 if(context)
337 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500338 if(context->getListIndex() != 0)
339 {
340 UNIMPLEMENTED();
341 }
342
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500343 gl::Texture *textureObject = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -0500344
345 if(textureObject && textureObject->getTarget() != target && texture != 0)
346 {
347 return error(GL_INVALID_OPERATION);
348 }
349
350 switch(target)
351 {
Maxime Grégoire5e582162015-07-16 12:52:57 -0400352 case GL_TEXTURE_1D:
353 context->bindTexture1D(texture);
354 return;
Nicolas Capens264f1522015-01-09 17:21:17 -0500355 case GL_TEXTURE_2D:
356 context->bindTexture2D(texture);
357 return;
358 case GL_TEXTURE_CUBE_MAP:
359 context->bindTextureCubeMap(texture);
360 return;
Nicolas Capens264f1522015-01-09 17:21:17 -0500361 default:
362 return error(GL_INVALID_ENUM);
363 }
364 }
365}
366
Nicolas Capensa9b49372015-01-30 00:33:26 -0500367void APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500368{
369 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
Nicolas Capensa9b49372015-01-30 00:33:26 -0500370 red, green, blue, alpha);
Nicolas Capens264f1522015-01-09 17:21:17 -0500371
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500372 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500373
374 if(context)
375 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500376 if(context->getListIndex() != 0)
377 {
378 UNIMPLEMENTED();
379 }
380
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500381 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
Nicolas Capens264f1522015-01-09 17:21:17 -0500382 }
383}
384
Nicolas Capensa9b49372015-01-30 00:33:26 -0500385void APIENTRY glBlendEquation(GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -0500386{
387 glBlendEquationSeparate(mode, mode);
388}
389
Nicolas Capensa9b49372015-01-30 00:33:26 -0500390void APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500391{
392 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
393
394 switch(modeRGB)
395 {
396 case GL_FUNC_ADD:
397 case GL_FUNC_SUBTRACT:
398 case GL_FUNC_REVERSE_SUBTRACT:
399 case GL_MIN_EXT:
400 case GL_MAX_EXT:
401 break;
402 default:
403 return error(GL_INVALID_ENUM);
404 }
405
406 switch(modeAlpha)
407 {
408 case GL_FUNC_ADD:
409 case GL_FUNC_SUBTRACT:
410 case GL_FUNC_REVERSE_SUBTRACT:
411 case GL_MIN_EXT:
412 case GL_MAX_EXT:
413 break;
414 default:
415 return error(GL_INVALID_ENUM);
416 }
417
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500418 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500419
420 if(context)
421 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500422 if(context->getListIndex() != 0)
423 {
424 UNIMPLEMENTED();
425 }
426
Nicolas Capens264f1522015-01-09 17:21:17 -0500427 context->setBlendEquation(modeRGB, modeAlpha);
428 }
429}
430
Nicolas Capensa9b49372015-01-30 00:33:26 -0500431void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
Nicolas Capens264f1522015-01-09 17:21:17 -0500432{
433 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
434}
435
Nicolas Capensa9b49372015-01-30 00:33:26 -0500436void APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500437{
438 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
439 srcRGB, dstRGB, srcAlpha, dstAlpha);
440
441 switch(srcRGB)
442 {
443 case GL_ZERO:
444 case GL_ONE:
445 case GL_SRC_COLOR:
446 case GL_ONE_MINUS_SRC_COLOR:
447 case GL_DST_COLOR:
448 case GL_ONE_MINUS_DST_COLOR:
449 case GL_SRC_ALPHA:
450 case GL_ONE_MINUS_SRC_ALPHA:
451 case GL_DST_ALPHA:
452 case GL_ONE_MINUS_DST_ALPHA:
453 case GL_CONSTANT_COLOR:
454 case GL_ONE_MINUS_CONSTANT_COLOR:
455 case GL_CONSTANT_ALPHA:
456 case GL_ONE_MINUS_CONSTANT_ALPHA:
457 case GL_SRC_ALPHA_SATURATE:
458 break;
459 default:
460 return error(GL_INVALID_ENUM);
461 }
462
463 switch(dstRGB)
464 {
465 case GL_ZERO:
466 case GL_ONE:
467 case GL_SRC_COLOR:
468 case GL_ONE_MINUS_SRC_COLOR:
469 case GL_DST_COLOR:
470 case GL_ONE_MINUS_DST_COLOR:
471 case GL_SRC_ALPHA:
472 case GL_ONE_MINUS_SRC_ALPHA:
473 case GL_DST_ALPHA:
474 case GL_ONE_MINUS_DST_ALPHA:
475 case GL_CONSTANT_COLOR:
476 case GL_ONE_MINUS_CONSTANT_COLOR:
477 case GL_CONSTANT_ALPHA:
478 case GL_ONE_MINUS_CONSTANT_ALPHA:
479 break;
480 default:
481 return error(GL_INVALID_ENUM);
482 }
483
484 switch(srcAlpha)
485 {
486 case GL_ZERO:
487 case GL_ONE:
488 case GL_SRC_COLOR:
489 case GL_ONE_MINUS_SRC_COLOR:
490 case GL_DST_COLOR:
491 case GL_ONE_MINUS_DST_COLOR:
492 case GL_SRC_ALPHA:
493 case GL_ONE_MINUS_SRC_ALPHA:
494 case GL_DST_ALPHA:
495 case GL_ONE_MINUS_DST_ALPHA:
496 case GL_CONSTANT_COLOR:
497 case GL_ONE_MINUS_CONSTANT_COLOR:
498 case GL_CONSTANT_ALPHA:
499 case GL_ONE_MINUS_CONSTANT_ALPHA:
500 case GL_SRC_ALPHA_SATURATE:
501 break;
502 default:
503 return error(GL_INVALID_ENUM);
504 }
505
506 switch(dstAlpha)
507 {
508 case GL_ZERO:
509 case GL_ONE:
510 case GL_SRC_COLOR:
511 case GL_ONE_MINUS_SRC_COLOR:
512 case GL_DST_COLOR:
513 case GL_ONE_MINUS_DST_COLOR:
514 case GL_SRC_ALPHA:
515 case GL_ONE_MINUS_SRC_ALPHA:
516 case GL_DST_ALPHA:
517 case GL_ONE_MINUS_DST_ALPHA:
518 case GL_CONSTANT_COLOR:
519 case GL_ONE_MINUS_CONSTANT_COLOR:
520 case GL_CONSTANT_ALPHA:
521 case GL_ONE_MINUS_CONSTANT_ALPHA:
522 break;
523 default:
524 return error(GL_INVALID_ENUM);
525 }
526
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500527 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500528
529 if(context)
530 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500531 if(context->getListIndex() != 0)
532 {
533 UNIMPLEMENTED();
534 }
535
Nicolas Capens264f1522015-01-09 17:21:17 -0500536 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
537 }
538}
539
Nicolas Capensa9b49372015-01-30 00:33:26 -0500540void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
Nicolas Capens264f1522015-01-09 17:21:17 -0500541{
Nicolas Capens4be33702015-04-28 15:13:30 -0700542 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
Nicolas Capens264f1522015-01-09 17:21:17 -0500543 target, size, data, usage);
544
545 if(size < 0)
546 {
547 return error(GL_INVALID_VALUE);
548 }
549
550 switch(usage)
551 {
552 case GL_STREAM_DRAW:
553 case GL_STATIC_DRAW:
554 case GL_DYNAMIC_DRAW:
555 break;
556 default:
557 return error(GL_INVALID_ENUM);
558 }
559
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500560 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500561
562 if(context)
563 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500564 gl::Buffer *buffer;
Nicolas Capens264f1522015-01-09 17:21:17 -0500565
566 switch(target)
567 {
568 case GL_ARRAY_BUFFER:
569 buffer = context->getArrayBuffer();
570 break;
571 case GL_ELEMENT_ARRAY_BUFFER:
572 buffer = context->getElementArrayBuffer();
573 break;
574 default:
575 return error(GL_INVALID_ENUM);
576 }
577
578 if(!buffer)
579 {
580 return error(GL_INVALID_OPERATION);
581 }
582
583 buffer->bufferData(data, size, usage);
584 }
585}
586
Nicolas Capensa9b49372015-01-30 00:33:26 -0500587void APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
Nicolas Capens264f1522015-01-09 17:21:17 -0500588{
Nicolas Capens4be33702015-04-28 15:13:30 -0700589 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -0500590 target, offset, size, data);
591
592 if(size < 0 || offset < 0)
593 {
594 return error(GL_INVALID_VALUE);
595 }
596
597 if(data == NULL)
598 {
599 return;
600 }
601
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500602 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500603
604 if(context)
605 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500606 gl::Buffer *buffer;
Nicolas Capens264f1522015-01-09 17:21:17 -0500607
608 switch(target)
609 {
610 case GL_ARRAY_BUFFER:
611 buffer = context->getArrayBuffer();
612 break;
613 case GL_ELEMENT_ARRAY_BUFFER:
614 buffer = context->getElementArrayBuffer();
615 break;
616 default:
617 return error(GL_INVALID_ENUM);
618 }
619
620 if(!buffer)
621 {
622 return error(GL_INVALID_OPERATION);
623 }
624
625 if((size_t)size + offset > buffer->size())
626 {
627 return error(GL_INVALID_VALUE);
628 }
629
630 buffer->bufferSubData(data, size, offset);
631 }
632}
633
Nicolas Capensa9b49372015-01-30 00:33:26 -0500634GLenum APIENTRY glCheckFramebufferStatus(GLenum target)
Nicolas Capens264f1522015-01-09 17:21:17 -0500635{
636 TRACE("(GLenum target = 0x%X)", target);
637
Nicolas Capensa9b49372015-01-30 00:33:26 -0500638 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500639 {
640 return error(GL_INVALID_ENUM, 0);
641 }
642
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500643 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500644
645 if(context)
646 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500647 if(context->getListIndex() != 0)
648 {
649 UNIMPLEMENTED();
650 }
651
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500652 gl::Framebuffer *framebuffer = NULL;
Nicolas Capensa9b49372015-01-30 00:33:26 -0500653 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500654 {
655 framebuffer = context->getReadFramebuffer();
656 }
657 else
658 {
659 framebuffer = context->getDrawFramebuffer();
660 }
661
662 return framebuffer->completeness();
663 }
664
665 return 0;
666}
667
Nicolas Capensa9b49372015-01-30 00:33:26 -0500668void APIENTRY glClear(GLbitfield mask)
Nicolas Capens264f1522015-01-09 17:21:17 -0500669{
670 TRACE("(GLbitfield mask = %X)", mask);
671
672 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
673 {
674 return error(GL_INVALID_VALUE);
675 }
676
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500677 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500678
679 if(context)
680 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500681 if(context->getListIndex() != 0)
682 {
683 return context->listCommand(gl::newCommand(glClear, mask));
684 }
685
Nicolas Capens264f1522015-01-09 17:21:17 -0500686 context->clear(mask);
687 }
688}
689
Nicolas Capensa9b49372015-01-30 00:33:26 -0500690void APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500691{
692 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
693 red, green, blue, alpha);
694
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500695 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500696
697 if(context)
698 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500699 if(context->getListIndex() != 0)
700 {
701 UNIMPLEMENTED();
702 }
703
Nicolas Capens264f1522015-01-09 17:21:17 -0500704 context->setClearColor(red, green, blue, alpha);
705 }
706}
707
Nicolas Capensa9b49372015-01-30 00:33:26 -0500708void APIENTRY glClearDepthf(GLclampf depth)
Nicolas Capens264f1522015-01-09 17:21:17 -0500709{
710 TRACE("(GLclampf depth = %f)", depth);
711
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500712 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500713
714 if(context)
715 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500716 if(context->getListIndex() != 0)
717 {
718 UNIMPLEMENTED();
719 }
720
Nicolas Capens264f1522015-01-09 17:21:17 -0500721 context->setClearDepth(depth);
722 }
723}
724
Nicolas Capensa9b49372015-01-30 00:33:26 -0500725void APIENTRY glClearStencil(GLint s)
Nicolas Capens264f1522015-01-09 17:21:17 -0500726{
727 TRACE("(GLint s = %d)", s);
728
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500729 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500730
731 if(context)
732 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500733 if(context->getListIndex() != 0)
734 {
735 UNIMPLEMENTED();
736 }
737
Nicolas Capens264f1522015-01-09 17:21:17 -0500738 context->setClearStencil(s);
739 }
740}
741
Nicolas Capensa9b49372015-01-30 00:33:26 -0500742void APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500743{
744 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
745 red, green, blue, alpha);
746
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500747 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500748
749 if(context)
750 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500751 if(context->getListIndex() != 0)
752 {
753 UNIMPLEMENTED();
754 }
755
Nicolas Capens264f1522015-01-09 17:21:17 -0500756 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
757 }
758}
759
Nicolas Capensa9b49372015-01-30 00:33:26 -0500760void APIENTRY glCompileShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -0500761{
762 TRACE("(GLuint shader = %d)", shader);
763
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500764 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500765
766 if(context)
767 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500768 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -0500769
770 if(!shaderObject)
771 {
772 if(context->getProgram(shader))
773 {
774 return error(GL_INVALID_OPERATION);
775 }
776 else
777 {
778 return error(GL_INVALID_VALUE);
779 }
780 }
781
782 shaderObject->compile();
783 }
784}
785
Nicolas Capensa9b49372015-01-30 00:33:26 -0500786void APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -0500787 GLint border, GLsizei imageSize, const GLvoid* data)
788{
789 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -0700790 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -0500791 target, level, internalformat, width, height, border, imageSize, data);
792
793 if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
794 {
795 return error(GL_INVALID_VALUE);
796 }
797
798 switch(internalformat)
799 {
Nicolas Capens264f1522015-01-09 17:21:17 -0500800 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
801 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500802 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
803 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500804 if(!S3TC_SUPPORT)
805 {
806 return error(GL_INVALID_ENUM);
807 }
808 break;
809 case GL_DEPTH_COMPONENT:
810 case GL_DEPTH_COMPONENT16:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500811 case GL_DEPTH_COMPONENT32:
812 case GL_DEPTH_STENCIL_EXT:
813 case GL_DEPTH24_STENCIL8_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500814 return error(GL_INVALID_OPERATION);
815 default:
816 return error(GL_INVALID_ENUM);
817 }
818
819 if(border != 0)
820 {
821 return error(GL_INVALID_VALUE);
822 }
823
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500824 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500825
826 if(context)
827 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500828 if(context->getListIndex() != 0)
829 {
830 UNIMPLEMENTED();
831 }
832
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500833 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -0500834 {
835 return error(GL_INVALID_VALUE);
836 }
837
838 switch(target)
839 {
840 case GL_TEXTURE_2D:
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500841 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
842 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -0500843 {
844 return error(GL_INVALID_VALUE);
845 }
846 break;
847 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
848 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
849 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
850 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
851 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
852 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
853 if(width != height)
854 {
855 return error(GL_INVALID_VALUE);
856 }
857
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500858 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
859 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -0500860 {
861 return error(GL_INVALID_VALUE);
862 }
863 break;
864 default:
865 return error(GL_INVALID_ENUM);
866 }
867
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500868 if(imageSize != gl::ComputeCompressedSize(width, height, internalformat))
Nicolas Capens264f1522015-01-09 17:21:17 -0500869 {
870 return error(GL_INVALID_VALUE);
871 }
872
873 if(target == GL_TEXTURE_2D)
874 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500875 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -0500876
877 if(!texture)
878 {
879 return error(GL_INVALID_OPERATION);
880 }
881
882 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
883 }
884 else
885 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500886 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -0500887
888 if(!texture)
889 {
890 return error(GL_INVALID_OPERATION);
891 }
892
893 switch(target)
894 {
895 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
896 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
897 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
898 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
899 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
900 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
901 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
902 break;
903 default: UNREACHABLE();
904 }
905 }
906 }
907}
908
Nicolas Capensa9b49372015-01-30 00:33:26 -0500909void APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -0500910 GLenum format, GLsizei imageSize, const GLvoid* data)
911{
912 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
913 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -0700914 "GLsizei imageSize = %d, const GLvoid* data = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -0500915 target, level, xoffset, yoffset, width, height, format, imageSize, data);
916
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500917 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -0500918 {
919 return error(GL_INVALID_ENUM);
920 }
921
922 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
923 {
924 return error(GL_INVALID_VALUE);
925 }
926
927 switch(format)
928 {
Nicolas Capens264f1522015-01-09 17:21:17 -0500929 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
930 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500931 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
932 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500933 if(!S3TC_SUPPORT)
934 {
935 return error(GL_INVALID_ENUM);
936 }
937 break;
938 default:
939 return error(GL_INVALID_ENUM);
940 }
941
942 if(width == 0 || height == 0 || data == NULL)
943 {
944 return;
945 }
946
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500947 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500948
949 if(context)
950 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500951 if(context->getListIndex() != 0)
952 {
953 UNIMPLEMENTED();
954 }
955
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500956 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -0500957 {
958 return error(GL_INVALID_VALUE);
959 }
960
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500961 if(imageSize != gl::ComputeCompressedSize(width, height, format))
Nicolas Capens264f1522015-01-09 17:21:17 -0500962 {
963 return error(GL_INVALID_VALUE);
964 }
965
966 if(xoffset % 4 != 0 || yoffset % 4 != 0)
967 {
968 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
969 return error(GL_INVALID_OPERATION);
970 }
971
972 if(target == GL_TEXTURE_2D)
973 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500974 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -0500975
976 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
977 {
978 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
979 }
980 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500981 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -0500982 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500983 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -0500984
985 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
986 {
987 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
988 }
989 }
990 else
991 {
992 UNREACHABLE();
993 }
994 }
995}
996
Nicolas Capensa9b49372015-01-30 00:33:26 -0500997void 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 -0500998{
999 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
1000 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
1001 target, level, internalformat, x, y, width, height, border);
1002
1003 if(!validImageSize(level, width, height))
1004 {
1005 return error(GL_INVALID_VALUE);
1006 }
1007
1008 if(border != 0)
1009 {
1010 return error(GL_INVALID_VALUE);
1011 }
1012
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001013 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001014
1015 if(context)
1016 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001017 if(context->getListIndex() != 0)
1018 {
1019 UNIMPLEMENTED();
1020 }
1021
Nicolas Capens264f1522015-01-09 17:21:17 -05001022 switch(target)
1023 {
1024 case GL_TEXTURE_2D:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001025 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
1026 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -05001027 {
1028 return error(GL_INVALID_VALUE);
1029 }
1030 break;
1031 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1032 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1033 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1034 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1035 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1036 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1037 if(width != height)
1038 {
1039 return error(GL_INVALID_VALUE);
1040 }
1041
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001042 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1043 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -05001044 {
1045 return error(GL_INVALID_VALUE);
1046 }
1047 break;
1048 default:
1049 return error(GL_INVALID_ENUM);
1050 }
1051
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001052 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001053
1054 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1055 {
1056 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1057 }
1058
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001059 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capens264f1522015-01-09 17:21:17 -05001060 {
1061 return error(GL_INVALID_OPERATION);
1062 }
1063
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001064 gl::Renderbuffer *source = framebuffer->getColorbuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001065 GLenum colorbufferFormat = source->getFormat();
1066
Nicolas Capens264f1522015-01-09 17:21:17 -05001067 switch(internalformat)
1068 {
1069 case GL_ALPHA:
1070 if(colorbufferFormat != GL_ALPHA &&
1071 colorbufferFormat != GL_RGBA &&
1072 colorbufferFormat != GL_RGBA4 &&
1073 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001074 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001075 {
1076 return error(GL_INVALID_OPERATION);
1077 }
1078 break;
1079 case GL_LUMINANCE:
1080 case GL_RGB:
1081 if(colorbufferFormat != GL_RGB &&
1082 colorbufferFormat != GL_RGB565 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001083 colorbufferFormat != GL_RGB8_EXT &&
Nicolas Capens264f1522015-01-09 17:21:17 -05001084 colorbufferFormat != GL_RGBA &&
1085 colorbufferFormat != GL_RGBA4 &&
1086 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001087 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001088 {
1089 return error(GL_INVALID_OPERATION);
1090 }
1091 break;
1092 case GL_LUMINANCE_ALPHA:
1093 case GL_RGBA:
1094 if(colorbufferFormat != GL_RGBA &&
1095 colorbufferFormat != GL_RGBA4 &&
1096 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001097 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001098 {
1099 return error(GL_INVALID_OPERATION);
1100 }
1101 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001102 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1103 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05001104 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1105 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05001106 if(S3TC_SUPPORT)
1107 {
1108 return error(GL_INVALID_OPERATION);
1109 }
1110 else
1111 {
1112 return error(GL_INVALID_ENUM);
1113 }
1114 default:
1115 return error(GL_INVALID_ENUM);
1116 }
1117
1118 if(target == GL_TEXTURE_2D)
1119 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001120 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05001121
1122 if(!texture)
1123 {
1124 return error(GL_INVALID_OPERATION);
1125 }
1126
1127 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
1128 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001129 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05001130 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001131 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05001132
1133 if(!texture)
1134 {
1135 return error(GL_INVALID_OPERATION);
1136 }
1137
1138 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
1139 }
1140 else UNREACHABLE();
1141 }
1142}
1143
Nicolas Capensa9b49372015-01-30 00:33:26 -05001144void 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 -05001145{
1146 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1147 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
1148 target, level, xoffset, yoffset, x, y, width, height);
1149
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001150 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05001151 {
1152 return error(GL_INVALID_ENUM);
1153 }
1154
1155 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
1156 {
1157 return error(GL_INVALID_VALUE);
1158 }
1159
1160 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1161 {
1162 return error(GL_INVALID_VALUE);
1163 }
1164
1165 if(width == 0 || height == 0)
1166 {
1167 return;
1168 }
1169
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001170 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001171
1172 if(context)
1173 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001174 if(context->getListIndex() != 0)
1175 {
1176 UNIMPLEMENTED();
1177 }
1178
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001179 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -05001180 {
1181 return error(GL_INVALID_VALUE);
1182 }
1183
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001184 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001185
1186 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1187 {
1188 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1189 }
1190
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001191 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capens264f1522015-01-09 17:21:17 -05001192 {
1193 return error(GL_INVALID_OPERATION);
1194 }
1195
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001196 gl::Renderbuffer *source = framebuffer->getColorbuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001197 GLenum colorbufferFormat = source->getFormat();
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001198 gl::Texture *texture = NULL;
Nicolas Capens264f1522015-01-09 17:21:17 -05001199
1200 if(target == GL_TEXTURE_2D)
1201 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001202 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05001203 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001204 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05001205 {
1206 texture = context->getTextureCubeMap();
1207 }
1208 else UNREACHABLE();
1209
1210 if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))
1211 {
1212 return;
1213 }
1214
1215 GLenum textureFormat = texture->getFormat(target, level);
1216
Nicolas Capens264f1522015-01-09 17:21:17 -05001217 switch(textureFormat)
1218 {
1219 case GL_ALPHA:
1220 if(colorbufferFormat != GL_ALPHA &&
1221 colorbufferFormat != GL_RGBA &&
1222 colorbufferFormat != GL_RGBA4 &&
1223 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001224 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001225 {
1226 return error(GL_INVALID_OPERATION);
1227 }
1228 break;
1229 case GL_LUMINANCE:
1230 case GL_RGB:
1231 if(colorbufferFormat != GL_RGB &&
1232 colorbufferFormat != GL_RGB565 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001233 colorbufferFormat != GL_RGB8_EXT &&
Nicolas Capens264f1522015-01-09 17:21:17 -05001234 colorbufferFormat != GL_RGBA &&
1235 colorbufferFormat != GL_RGBA4 &&
1236 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001237 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001238 {
1239 return error(GL_INVALID_OPERATION);
1240 }
1241 break;
1242 case GL_LUMINANCE_ALPHA:
1243 case GL_RGBA:
1244 if(colorbufferFormat != GL_RGBA &&
1245 colorbufferFormat != GL_RGBA4 &&
1246 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001247 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001248 {
1249 return error(GL_INVALID_OPERATION);
1250 }
1251 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001252 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1253 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05001254 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1255 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1256 return error(GL_INVALID_OPERATION);
1257 case GL_DEPTH_COMPONENT:
1258 case GL_DEPTH_STENCIL_EXT:
1259 return error(GL_INVALID_OPERATION);
1260 case GL_BGRA_EXT:
1261 if(colorbufferFormat != GL_RGB8)
Nicolas Capens264f1522015-01-09 17:21:17 -05001262 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001263 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05001264 return error(GL_INVALID_OPERATION);
1265 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05001266 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001267 default:
1268 return error(GL_INVALID_ENUM);
1269 }
1270
1271 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
1272 }
1273}
1274
Nicolas Capensa9b49372015-01-30 00:33:26 -05001275GLuint APIENTRY glCreateProgram(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05001276{
1277 TRACE("()");
1278
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001279 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001280
1281 if(context)
1282 {
1283 return context->createProgram();
1284 }
1285
1286 return 0;
1287}
1288
Nicolas Capensa9b49372015-01-30 00:33:26 -05001289GLuint APIENTRY glCreateShader(GLenum type)
Nicolas Capens264f1522015-01-09 17:21:17 -05001290{
1291 TRACE("(GLenum type = 0x%X)", type);
1292
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001293 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001294
1295 if(context)
1296 {
1297 switch(type)
1298 {
1299 case GL_FRAGMENT_SHADER:
1300 case GL_VERTEX_SHADER:
1301 return context->createShader(type);
1302 default:
1303 return error(GL_INVALID_ENUM, 0);
1304 }
1305 }
1306
1307 return 0;
1308}
1309
Nicolas Capensa9b49372015-01-30 00:33:26 -05001310void APIENTRY glCullFace(GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05001311{
1312 TRACE("(GLenum mode = 0x%X)", mode);
1313
1314 switch(mode)
1315 {
1316 case GL_FRONT:
1317 case GL_BACK:
1318 case GL_FRONT_AND_BACK:
1319 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001320 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001321
1322 if(context)
1323 {
1324 context->setCullMode(mode);
1325 }
1326 }
1327 break;
1328 default:
1329 return error(GL_INVALID_ENUM);
1330 }
1331}
1332
Nicolas Capensa9b49372015-01-30 00:33:26 -05001333void APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05001334{
Nicolas Capens4be33702015-04-28 15:13:30 -07001335 TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
Nicolas Capens264f1522015-01-09 17:21:17 -05001336
1337 if(n < 0)
1338 {
1339 return error(GL_INVALID_VALUE);
1340 }
1341
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001342 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001343
1344 if(context)
1345 {
1346 for(int i = 0; i < n; i++)
1347 {
1348 context->deleteBuffer(buffers[i]);
1349 }
1350 }
1351}
1352
Nicolas Capensa9b49372015-01-30 00:33:26 -05001353void APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
Nicolas Capens264f1522015-01-09 17:21:17 -05001354{
Nicolas Capens4be33702015-04-28 15:13:30 -07001355 TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);
Nicolas Capens264f1522015-01-09 17:21:17 -05001356
1357 if(n < 0)
1358 {
1359 return error(GL_INVALID_VALUE);
1360 }
1361
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001362 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001363
1364 if(context)
1365 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001366 if(context->getListIndex() != 0)
1367 {
1368 UNIMPLEMENTED();
1369 }
1370
Nicolas Capens264f1522015-01-09 17:21:17 -05001371 for(int i = 0; i < n; i++)
1372 {
1373 context->deleteFence(fences[i]);
1374 }
1375 }
1376}
1377
Nicolas Capensa9b49372015-01-30 00:33:26 -05001378void APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05001379{
Nicolas Capens4be33702015-04-28 15:13:30 -07001380 TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
Nicolas Capens264f1522015-01-09 17:21:17 -05001381
1382 if(n < 0)
1383 {
1384 return error(GL_INVALID_VALUE);
1385 }
1386
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001387 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001388
1389 if(context)
1390 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001391 if(context->getListIndex() != 0)
1392 {
1393 UNIMPLEMENTED();
1394 }
1395
Nicolas Capens264f1522015-01-09 17:21:17 -05001396 for(int i = 0; i < n; i++)
1397 {
1398 if(framebuffers[i] != 0)
1399 {
1400 context->deleteFramebuffer(framebuffers[i]);
1401 }
1402 }
1403 }
1404}
1405
Nicolas Capensa9b49372015-01-30 00:33:26 -05001406void APIENTRY glDeleteProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05001407{
1408 TRACE("(GLuint program = %d)", program);
1409
1410 if(program == 0)
1411 {
1412 return;
1413 }
1414
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001415 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001416
1417 if(context)
1418 {
1419 if(!context->getProgram(program))
1420 {
1421 if(context->getShader(program))
1422 {
1423 return error(GL_INVALID_OPERATION);
1424 }
1425 else
1426 {
1427 return error(GL_INVALID_VALUE);
1428 }
1429 }
1430
1431 context->deleteProgram(program);
1432 }
1433}
1434
Nicolas Capensa9b49372015-01-30 00:33:26 -05001435void APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
Nicolas Capens264f1522015-01-09 17:21:17 -05001436{
Nicolas Capens4be33702015-04-28 15:13:30 -07001437 TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
Nicolas Capens264f1522015-01-09 17:21:17 -05001438
1439 if(n < 0)
1440 {
1441 return error(GL_INVALID_VALUE);
1442 }
1443
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001444 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001445
1446 if(context)
1447 {
1448 for(int i = 0; i < n; i++)
1449 {
1450 context->deleteQuery(ids[i]);
1451 }
1452 }
1453}
1454
Nicolas Capensa9b49372015-01-30 00:33:26 -05001455void APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05001456{
Nicolas Capens4be33702015-04-28 15:13:30 -07001457 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
Nicolas Capens264f1522015-01-09 17:21:17 -05001458
1459 if(n < 0)
1460 {
1461 return error(GL_INVALID_VALUE);
1462 }
1463
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001464 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001465
1466 if(context)
1467 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001468 if(context->getListIndex() != 0)
1469 {
1470 UNIMPLEMENTED();
1471 }
1472
Nicolas Capens264f1522015-01-09 17:21:17 -05001473 for(int i = 0; i < n; i++)
1474 {
1475 context->deleteRenderbuffer(renderbuffers[i]);
1476 }
1477 }
1478}
1479
Nicolas Capensa9b49372015-01-30 00:33:26 -05001480void APIENTRY glDeleteShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05001481{
1482 TRACE("(GLuint shader = %d)", shader);
1483
1484 if(shader == 0)
1485 {
1486 return;
1487 }
1488
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001489 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001490
1491 if(context)
1492 {
1493 if(!context->getShader(shader))
1494 {
1495 if(context->getProgram(shader))
1496 {
1497 return error(GL_INVALID_OPERATION);
1498 }
1499 else
1500 {
1501 return error(GL_INVALID_VALUE);
1502 }
1503 }
1504
1505 context->deleteShader(shader);
1506 }
1507}
1508
Nicolas Capensa9b49372015-01-30 00:33:26 -05001509void APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
Nicolas Capens264f1522015-01-09 17:21:17 -05001510{
Nicolas Capens4be33702015-04-28 15:13:30 -07001511 TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
Nicolas Capens264f1522015-01-09 17:21:17 -05001512
1513 if(n < 0)
1514 {
1515 return error(GL_INVALID_VALUE);
1516 }
1517
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001518 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001519
1520 if(context)
1521 {
1522 for(int i = 0; i < n; i++)
1523 {
1524 if(textures[i] != 0)
1525 {
1526 context->deleteTexture(textures[i]);
1527 }
1528 }
1529 }
1530}
1531
Nicolas Capensa9b49372015-01-30 00:33:26 -05001532void APIENTRY glDepthFunc(GLenum func)
Nicolas Capens264f1522015-01-09 17:21:17 -05001533{
1534 TRACE("(GLenum func = 0x%X)", func);
1535
1536 switch(func)
1537 {
1538 case GL_NEVER:
1539 case GL_ALWAYS:
1540 case GL_LESS:
1541 case GL_LEQUAL:
1542 case GL_EQUAL:
1543 case GL_GREATER:
1544 case GL_GEQUAL:
1545 case GL_NOTEQUAL:
1546 break;
1547 default:
1548 return error(GL_INVALID_ENUM);
1549 }
1550
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001551 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001552
1553 if(context)
1554 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001555 if(context->getListIndex() != 0)
1556 {
1557 UNIMPLEMENTED();
1558 }
1559
Nicolas Capens264f1522015-01-09 17:21:17 -05001560 context->setDepthFunc(func);
1561 }
1562}
1563
Nicolas Capensa9b49372015-01-30 00:33:26 -05001564void APIENTRY glDepthMask(GLboolean flag)
Nicolas Capens264f1522015-01-09 17:21:17 -05001565{
1566 TRACE("(GLboolean flag = %d)", flag);
1567
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001568 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001569
1570 if(context)
1571 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001572 if(context->getListIndex() != 0)
1573 {
1574 UNIMPLEMENTED();
1575 }
1576
Nicolas Capens264f1522015-01-09 17:21:17 -05001577 context->setDepthMask(flag != GL_FALSE);
1578 }
1579}
1580
Nicolas Capensa9b49372015-01-30 00:33:26 -05001581void APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
Nicolas Capens264f1522015-01-09 17:21:17 -05001582{
1583 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
1584
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001585 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001586
1587 if(context)
1588 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001589 if(context->getListIndex() != 0)
1590 {
1591 UNIMPLEMENTED();
1592 }
1593
Nicolas Capens264f1522015-01-09 17:21:17 -05001594 context->setDepthRange(zNear, zFar);
1595 }
1596}
1597
Nicolas Capensa9b49372015-01-30 00:33:26 -05001598void APIENTRY glDetachShader(GLuint program, GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05001599{
1600 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
1601
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001602 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001603
1604 if(context)
1605 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001606 gl::Program *programObject = context->getProgram(program);
1607 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05001608
1609 if(!programObject)
1610 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001611 gl::Shader *shaderByProgramHandle;
Nicolas Capens264f1522015-01-09 17:21:17 -05001612 shaderByProgramHandle = context->getShader(program);
1613 if(!shaderByProgramHandle)
1614 {
1615 return error(GL_INVALID_VALUE);
1616 }
1617 else
1618 {
1619 return error(GL_INVALID_OPERATION);
1620 }
1621 }
1622
1623 if(!shaderObject)
1624 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001625 gl::Program *programByShaderHandle = context->getProgram(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05001626 if(!programByShaderHandle)
1627 {
1628 return error(GL_INVALID_VALUE);
1629 }
1630 else
1631 {
1632 return error(GL_INVALID_OPERATION);
1633 }
1634 }
1635
1636 if(!programObject->detachShader(shaderObject))
1637 {
1638 return error(GL_INVALID_OPERATION);
1639 }
1640 }
1641}
1642
Nicolas Capensa9b49372015-01-30 00:33:26 -05001643void APIENTRY glDisable(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05001644{
1645 TRACE("(GLenum cap = 0x%X)", cap);
1646
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001647 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001648
1649 if(context)
1650 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001651 if(context->getListIndex() != 0)
1652 {
1653 UNIMPLEMENTED();
1654 }
1655
Nicolas Capens264f1522015-01-09 17:21:17 -05001656 switch(cap)
1657 {
Maxime Grégoire5e582162015-07-16 12:52:57 -04001658 case GL_TEXTURE_1D: context->set1DTextureEnable(false); break;
Maxime Grégoiredff6d002015-07-16 10:26:45 -04001659 case GL_CULL_FACE: context->setCullFace(false); break;
1660 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1661 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1662 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1663 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1664 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1665 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1666 case GL_BLEND: context->setBlend(false); break;
1667 case GL_DITHER: context->setDither(false); break;
1668 case GL_LIGHTING: context->setLighting(false); break;
1669 case GL_FOG: context->setFog(false); break;
1670 case GL_ALPHA_TEST: context->setAlphaTest(false); break;
1671 case GL_TEXTURE_2D: context->setTexture2D(false); break;
1672 case GL_LIGHT0: context->setLight(0, false); break;
1673 case GL_LIGHT1: context->setLight(1, false); break;
1674 case GL_LIGHT2: context->setLight(2, false); break;
1675 case GL_LIGHT3: context->setLight(3, false); break;
1676 case GL_LIGHT4: context->setLight(4, false); break;
1677 case GL_LIGHT5: context->setLight(5, false); break;
1678 case GL_LIGHT6: context->setLight(6, false); break;
1679 case GL_LIGHT7: context->setLight(7, false); break;
1680 case GL_COLOR_MATERIAL: context->setColorMaterial(false); break;
1681 case GL_RESCALE_NORMAL: context->setNormalizeNormals(false); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001682 default:
1683 return error(GL_INVALID_ENUM);
1684 }
1685 }
1686}
1687
Nicolas Capensa9b49372015-01-30 00:33:26 -05001688void APIENTRY glDisableVertexAttribArray(GLuint index)
Nicolas Capens264f1522015-01-09 17:21:17 -05001689{
1690 TRACE("(GLuint index = %d)", index);
1691
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001692 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05001693 {
1694 return error(GL_INVALID_VALUE);
1695 }
1696
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001697 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001698
1699 if(context)
1700 {
1701 context->setEnableVertexAttribArray(index, false);
1702 }
1703}
1704
Nicolas Capensa9b49372015-01-30 00:33:26 -05001705void APIENTRY glCaptureAttribs()
1706{
1707 TRACE("()");
1708
1709 gl::Context *context = gl::getContext();
1710
1711 if(context)
1712 {
1713 context->captureAttribs();
1714 }
1715}
1716
1717void APIENTRY glRestoreAttribs()
1718{
1719 TRACE("()");
1720
1721 gl::Context *context = gl::getContext();
1722
1723 if(context)
1724 {
1725 context->restoreAttribs();
1726 }
1727}
1728
1729void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
Nicolas Capens264f1522015-01-09 17:21:17 -05001730{
1731 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
1732
1733 if(count < 0 || first < 0)
1734 {
1735 return error(GL_INVALID_VALUE);
1736 }
1737
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001738 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001739
1740 if(context)
1741 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001742 if(context->getListIndex() != 0)
1743 {
1744 ASSERT(context->getListMode() != GL_COMPILE_AND_EXECUTE); // UNIMPLEMENTED!
1745
1746 context->listCommand(gl::newCommand(glCaptureAttribs));
1747 context->captureDrawArrays(mode, first, count);
1748 context->listCommand(gl::newCommand(glDrawArrays, mode, first, count));
1749 context->listCommand(gl::newCommand(glRestoreAttribs));
1750
1751 return;
1752 }
1753
Nicolas Capens264f1522015-01-09 17:21:17 -05001754 context->drawArrays(mode, first, count);
1755 }
1756}
1757
Nicolas Capensa9b49372015-01-30 00:33:26 -05001758void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
Nicolas Capens264f1522015-01-09 17:21:17 -05001759{
Nicolas Capens4be33702015-04-28 15:13:30 -07001760 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05001761 mode, count, type, indices);
1762
1763 if(count < 0)
1764 {
1765 return error(GL_INVALID_VALUE);
1766 }
1767
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001768 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001769
1770 if(context)
1771 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001772 if(context->getListIndex() != 0)
1773 {
1774 UNIMPLEMENTED();
1775 }
1776
Nicolas Capens264f1522015-01-09 17:21:17 -05001777 switch(type)
1778 {
1779 case GL_UNSIGNED_BYTE:
1780 case GL_UNSIGNED_SHORT:
1781 case GL_UNSIGNED_INT:
1782 break;
1783 default:
1784 return error(GL_INVALID_ENUM);
1785 }
1786
1787 context->drawElements(mode, count, type, indices);
1788 }
1789}
1790
Nicolas Capensa9b49372015-01-30 00:33:26 -05001791void APIENTRY glEnable(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05001792{
1793 TRACE("(GLenum cap = 0x%X)", cap);
1794
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001795 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001796
1797 if(context)
1798 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001799 if(context->getListIndex() != 0)
1800 {
1801 UNIMPLEMENTED();
1802 }
1803
Nicolas Capens264f1522015-01-09 17:21:17 -05001804 switch(cap)
1805 {
Maxime Grégoire5e582162015-07-16 12:52:57 -04001806 case GL_TEXTURE_1D: context->set1DTextureEnable(true); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001807 case GL_CULL_FACE: context->setCullFace(true); break;
1808 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1809 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1810 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1811 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1812 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1813 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1814 case GL_BLEND: context->setBlend(true); break;
1815 case GL_DITHER: context->setDither(true); break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05001816 case GL_TEXTURE_2D: context->setTexture2D(true); break;
1817 case GL_ALPHA_TEST: context->setAlphaTest(true); break;
1818 case GL_COLOR_MATERIAL: context->setColorMaterial(true); break;
1819 case GL_FOG: context->setFog(true); break;
1820 case GL_LIGHTING: context->setLighting(true); break;
1821 case GL_LIGHT0: context->setLight(0, true); break;
1822 case GL_LIGHT1: context->setLight(1, true); break;
1823 case GL_LIGHT2: context->setLight(2, true); break;
1824 case GL_LIGHT3: context->setLight(3, true); break;
1825 case GL_LIGHT4: context->setLight(4, true); break;
1826 case GL_LIGHT5: context->setLight(5, true); break;
1827 case GL_LIGHT6: context->setLight(6, true); break;
1828 case GL_LIGHT7: context->setLight(7, true); break;
1829 case GL_RESCALE_NORMAL: context->setNormalizeNormals(true); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001830 default:
1831 return error(GL_INVALID_ENUM);
1832 }
1833 }
1834}
1835
Nicolas Capensa9b49372015-01-30 00:33:26 -05001836void APIENTRY glEnableVertexAttribArray(GLuint index)
Nicolas Capens264f1522015-01-09 17:21:17 -05001837{
1838 TRACE("(GLuint index = %d)", index);
1839
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001840 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05001841 {
1842 return error(GL_INVALID_VALUE);
1843 }
1844
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001845 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001846
1847 if(context)
1848 {
1849 context->setEnableVertexAttribArray(index, true);
1850 }
1851}
1852
Nicolas Capensa9b49372015-01-30 00:33:26 -05001853void APIENTRY glEndQueryEXT(GLenum target)
Nicolas Capens264f1522015-01-09 17:21:17 -05001854{
1855 TRACE("GLenum target = 0x%X)", target);
1856
1857 switch(target)
1858 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001859 case GL_ANY_SAMPLES_PASSED:
1860 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
Nicolas Capens264f1522015-01-09 17:21:17 -05001861 break;
1862 default:
1863 return error(GL_INVALID_ENUM);
1864 }
1865
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001866 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001867
1868 if(context)
1869 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001870 if(context->getListIndex() != 0)
1871 {
1872 UNIMPLEMENTED();
1873 }
1874
Nicolas Capens264f1522015-01-09 17:21:17 -05001875 context->endQuery(target);
1876 }
1877}
1878
Nicolas Capensa9b49372015-01-30 00:33:26 -05001879void APIENTRY glFinishFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05001880{
1881 TRACE("(GLuint fence = %d)", fence);
1882
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001883 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001884
1885 if(context)
1886 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001887 if(context->getListIndex() != 0)
1888 {
1889 UNIMPLEMENTED();
1890 }
1891
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001892 gl::Fence* fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05001893
1894 if(fenceObject == NULL)
1895 {
1896 return error(GL_INVALID_OPERATION);
1897 }
1898
1899 fenceObject->finishFence();
1900 }
1901}
1902
Nicolas Capensa9b49372015-01-30 00:33:26 -05001903void APIENTRY glFinish(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05001904{
1905 TRACE("()");
1906
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001907 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001908
1909 if(context)
1910 {
1911 context->finish();
1912 }
1913}
1914
Nicolas Capensa9b49372015-01-30 00:33:26 -05001915void APIENTRY glFlush(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05001916{
1917 TRACE("()");
1918
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001919 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001920
1921 if(context)
1922 {
1923 context->flush();
1924 }
1925}
1926
Nicolas Capensa9b49372015-01-30 00:33:26 -05001927void APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05001928{
1929 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1930 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
1931
Nicolas Capensa9b49372015-01-30 00:33:26 -05001932 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT) ||
Nicolas Capens264f1522015-01-09 17:21:17 -05001933 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
1934 {
1935 return error(GL_INVALID_ENUM);
1936 }
1937
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001938 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001939
1940 if(context)
1941 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001942 if(context->getListIndex() != 0)
1943 {
1944 UNIMPLEMENTED();
1945 }
1946
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001947 gl::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001948 GLuint framebufferName = 0;
Nicolas Capensa9b49372015-01-30 00:33:26 -05001949 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001950 {
1951 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001952 framebufferName = context->getReadFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05001953 }
1954 else
1955 {
1956 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001957 framebufferName = context->getDrawFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05001958 }
1959
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001960 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
Nicolas Capens264f1522015-01-09 17:21:17 -05001961 {
1962 return error(GL_INVALID_OPERATION);
1963 }
1964
1965 switch(attachment)
1966 {
1967 case GL_COLOR_ATTACHMENT0:
1968 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1969 break;
1970 case GL_DEPTH_ATTACHMENT:
1971 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1972 break;
1973 case GL_STENCIL_ATTACHMENT:
1974 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1975 break;
1976 default:
1977 return error(GL_INVALID_ENUM);
1978 }
1979 }
1980}
1981
Nicolas Capensa9b49372015-01-30 00:33:26 -05001982void APIENTRY glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1983{
1984 UNIMPLEMENTED();
1985}
1986
1987void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
Nicolas Capens264f1522015-01-09 17:21:17 -05001988{
1989 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1990 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
1991
Nicolas Capensa9b49372015-01-30 00:33:26 -05001992 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001993 {
1994 return error(GL_INVALID_ENUM);
1995 }
1996
1997 switch(attachment)
1998 {
1999 case GL_COLOR_ATTACHMENT0:
2000 case GL_DEPTH_ATTACHMENT:
2001 case GL_STENCIL_ATTACHMENT:
2002 break;
2003 default:
2004 return error(GL_INVALID_ENUM);
2005 }
2006
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002007 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002008
2009 if(context)
2010 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002011 if(context->getListIndex() != 0)
2012 {
2013 UNIMPLEMENTED();
2014 }
2015
Nicolas Capens264f1522015-01-09 17:21:17 -05002016 if(texture == 0)
2017 {
2018 textarget = GL_NONE;
2019 }
2020 else
2021 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002022 gl::Texture *tex = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -05002023
2024 if(tex == NULL)
2025 {
2026 return error(GL_INVALID_OPERATION);
2027 }
2028
2029 if(tex->isCompressed(textarget, level))
2030 {
2031 return error(GL_INVALID_OPERATION);
2032 }
2033
2034 switch(textarget)
2035 {
2036 case GL_TEXTURE_2D:
2037 if(tex->getTarget() != GL_TEXTURE_2D)
2038 {
2039 return error(GL_INVALID_OPERATION);
2040 }
2041 break;
2042 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2043 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2044 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2045 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2046 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2047 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2048 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2049 {
2050 return error(GL_INVALID_OPERATION);
2051 }
2052 break;
2053 default:
2054 return error(GL_INVALID_ENUM);
2055 }
2056
2057 if(level != 0)
2058 {
2059 return error(GL_INVALID_VALUE);
2060 }
2061 }
2062
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002063 gl::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002064 GLuint framebufferName = 0;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002065 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05002066 {
2067 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002068 framebufferName = context->getReadFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002069 }
2070 else
2071 {
2072 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002073 framebufferName = context->getDrawFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002074 }
2075
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002076 if(framebufferName == 0 || !framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05002077 {
2078 return error(GL_INVALID_OPERATION);
2079 }
2080
2081 switch(attachment)
2082 {
2083 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2084 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2085 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2086 }
2087 }
2088}
2089
Nicolas Capensa9b49372015-01-30 00:33:26 -05002090void APIENTRY glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
2091{
2092 UNIMPLEMENTED();
2093}
2094
2095void APIENTRY glFrontFace(GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05002096{
2097 TRACE("(GLenum mode = 0x%X)", mode);
2098
2099 switch(mode)
2100 {
2101 case GL_CW:
2102 case GL_CCW:
2103 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002104 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002105
2106 if(context)
2107 {
2108 context->setFrontFace(mode);
2109 }
2110 }
2111 break;
2112 default:
2113 return error(GL_INVALID_ENUM);
2114 }
2115}
2116
Nicolas Capensa9b49372015-01-30 00:33:26 -05002117void APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05002118{
Nicolas Capens4be33702015-04-28 15:13:30 -07002119 TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
Nicolas Capens264f1522015-01-09 17:21:17 -05002120
2121 if(n < 0)
2122 {
2123 return error(GL_INVALID_VALUE);
2124 }
2125
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002126 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002127
2128 if(context)
2129 {
2130 for(int i = 0; i < n; i++)
2131 {
2132 buffers[i] = context->createBuffer();
2133 }
2134 }
2135}
2136
Nicolas Capensa9b49372015-01-30 00:33:26 -05002137void APIENTRY glGenerateMipmap(GLenum target)
Nicolas Capens264f1522015-01-09 17:21:17 -05002138{
2139 TRACE("(GLenum target = 0x%X)", target);
2140
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002141 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002142
2143 if(context)
2144 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002145 if(context->getListIndex() != 0)
2146 {
2147 UNIMPLEMENTED();
2148 }
2149
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002150 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05002151
2152 switch(target)
2153 {
2154 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05002155 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05002156 break;
2157 case GL_TEXTURE_CUBE_MAP:
2158 texture = context->getTextureCubeMap();
2159 break;
2160 default:
2161 return error(GL_INVALID_ENUM);
2162 }
2163
2164 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2165 {
2166 return error(GL_INVALID_OPERATION);
2167 }
2168
2169 texture->generateMipmaps();
2170 }
2171}
2172
Nicolas Capensa9b49372015-01-30 00:33:26 -05002173void APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
Nicolas Capens264f1522015-01-09 17:21:17 -05002174{
Nicolas Capens4be33702015-04-28 15:13:30 -07002175 TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);
Nicolas Capens264f1522015-01-09 17:21:17 -05002176
2177 if(n < 0)
2178 {
2179 return error(GL_INVALID_VALUE);
2180 }
2181
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002182 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002183
2184 if(context)
2185 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002186 if(context->getListIndex() != 0)
2187 {
2188 UNIMPLEMENTED();
2189 }
2190
Nicolas Capens264f1522015-01-09 17:21:17 -05002191 for(int i = 0; i < n; i++)
2192 {
2193 fences[i] = context->createFence();
2194 }
2195 }
2196}
2197
Nicolas Capensa9b49372015-01-30 00:33:26 -05002198void APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05002199{
Nicolas Capens4be33702015-04-28 15:13:30 -07002200 TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
Nicolas Capens264f1522015-01-09 17:21:17 -05002201
2202 if(n < 0)
2203 {
2204 return error(GL_INVALID_VALUE);
2205 }
2206
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002207 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002208
2209 if(context)
2210 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002211 if(context->getListIndex() != 0)
2212 {
2213 UNIMPLEMENTED();
2214 }
2215
Nicolas Capens264f1522015-01-09 17:21:17 -05002216 for(int i = 0; i < n; i++)
2217 {
2218 framebuffers[i] = context->createFramebuffer();
2219 }
2220 }
2221}
2222
Nicolas Capensa9b49372015-01-30 00:33:26 -05002223void APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
Nicolas Capens264f1522015-01-09 17:21:17 -05002224{
Nicolas Capens4be33702015-04-28 15:13:30 -07002225 TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
Nicolas Capens264f1522015-01-09 17:21:17 -05002226
2227 if(n < 0)
2228 {
2229 return error(GL_INVALID_VALUE);
2230 }
2231
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002232 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002233
2234 if(context)
2235 {
2236 for(int i = 0; i < n; i++)
2237 {
2238 ids[i] = context->createQuery();
2239 }
2240 }
2241}
2242
Nicolas Capensa9b49372015-01-30 00:33:26 -05002243void APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05002244{
Nicolas Capens4be33702015-04-28 15:13:30 -07002245 TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
Nicolas Capens264f1522015-01-09 17:21:17 -05002246
2247 if(n < 0)
2248 {
2249 return error(GL_INVALID_VALUE);
2250 }
2251
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002252 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002253
2254 if(context)
2255 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002256 if(context->getListIndex() != 0)
2257 {
2258 UNIMPLEMENTED();
2259 }
2260
Nicolas Capens264f1522015-01-09 17:21:17 -05002261 for(int i = 0; i < n; i++)
2262 {
2263 renderbuffers[i] = context->createRenderbuffer();
2264 }
2265 }
2266}
2267
Nicolas Capensa9b49372015-01-30 00:33:26 -05002268void APIENTRY glGenTextures(GLsizei n, GLuint* textures)
Nicolas Capens264f1522015-01-09 17:21:17 -05002269{
Nicolas Capens4be33702015-04-28 15:13:30 -07002270 TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
Nicolas Capens264f1522015-01-09 17:21:17 -05002271
2272 if(n < 0)
2273 {
2274 return error(GL_INVALID_VALUE);
2275 }
2276
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002277 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002278
2279 if(context)
2280 {
2281 for(int i = 0; i < n; i++)
2282 {
2283 textures[i] = context->createTexture();
2284 }
2285 }
2286}
2287
Nicolas Capensa9b49372015-01-30 00:33:26 -05002288void APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002289{
Nicolas Capens4be33702015-04-28 15:13:30 -07002290 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
2291 "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05002292 program, index, bufsize, length, size, type, name);
2293
2294 if(bufsize < 0)
2295 {
2296 return error(GL_INVALID_VALUE);
2297 }
2298
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002299 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002300
2301 if(context)
2302 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002303 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002304
2305 if(!programObject)
2306 {
2307 if(context->getShader(program))
2308 {
2309 return error(GL_INVALID_OPERATION);
2310 }
2311 else
2312 {
2313 return error(GL_INVALID_VALUE);
2314 }
2315 }
2316
2317 if(index >= (GLuint)programObject->getActiveAttributeCount())
2318 {
2319 return error(GL_INVALID_VALUE);
2320 }
2321
2322 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2323 }
2324}
2325
Nicolas Capensa9b49372015-01-30 00:33:26 -05002326void APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002327{
2328 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07002329 "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
Nicolas Capens264f1522015-01-09 17:21:17 -05002330 program, index, bufsize, length, size, type, name);
2331
2332 if(bufsize < 0)
2333 {
2334 return error(GL_INVALID_VALUE);
2335 }
2336
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002337 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002338
2339 if(context)
2340 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002341 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002342
2343 if(!programObject)
2344 {
2345 if(context->getShader(program))
2346 {
2347 return error(GL_INVALID_OPERATION);
2348 }
2349 else
2350 {
2351 return error(GL_INVALID_VALUE);
2352 }
2353 }
2354
2355 if(index >= (GLuint)programObject->getActiveUniformCount())
2356 {
2357 return error(GL_INVALID_VALUE);
2358 }
2359
2360 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2361 }
2362}
2363
Nicolas Capensa9b49372015-01-30 00:33:26 -05002364void APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
Nicolas Capens264f1522015-01-09 17:21:17 -05002365{
Nicolas Capens4be33702015-04-28 15:13:30 -07002366 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05002367 program, maxcount, count, shaders);
2368
2369 if(maxcount < 0)
2370 {
2371 return error(GL_INVALID_VALUE);
2372 }
2373
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002374 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002375
2376 if(context)
2377 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002378 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002379
2380 if(!programObject)
2381 {
2382 if(context->getShader(program))
2383 {
2384 return error(GL_INVALID_OPERATION);
2385 }
2386 else
2387 {
2388 return error(GL_INVALID_VALUE);
2389 }
2390 }
2391
2392 return programObject->getAttachedShaders(maxcount, count, shaders);
2393 }
2394}
2395
Nicolas Capensa9b49372015-01-30 00:33:26 -05002396int APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002397{
2398 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
2399
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002400 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002401
2402 if(context)
2403 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002404 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002405
2406 if(!programObject)
2407 {
2408 if(context->getShader(program))
2409 {
2410 return error(GL_INVALID_OPERATION, -1);
2411 }
2412 else
2413 {
2414 return error(GL_INVALID_VALUE, -1);
2415 }
2416 }
2417
2418 if(!programObject->isLinked())
2419 {
2420 return error(GL_INVALID_OPERATION, -1);
2421 }
2422
2423 return programObject->getAttributeLocation(name);
2424 }
2425
2426 return -1;
2427}
2428
Nicolas Capensa9b49372015-01-30 00:33:26 -05002429void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002430{
Nicolas Capens4be33702015-04-28 15:13:30 -07002431 TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)", pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002432
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002433 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002434
2435 if(context)
2436 {
2437 if(!(context->getBooleanv(pname, params)))
2438 {
2439 GLenum nativeType;
2440 unsigned int numParams = 0;
2441 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2442 return error(GL_INVALID_ENUM);
2443
2444 if(numParams == 0)
2445 return; // it is known that the pname is valid, but there are no parameters to return
2446
2447 if(nativeType == GL_FLOAT)
2448 {
2449 GLfloat *floatParams = NULL;
2450 floatParams = new GLfloat[numParams];
2451
2452 context->getFloatv(pname, floatParams);
2453
2454 for(unsigned int i = 0; i < numParams; ++i)
2455 {
2456 if(floatParams[i] == 0.0f)
2457 params[i] = GL_FALSE;
2458 else
2459 params[i] = GL_TRUE;
2460 }
2461
2462 delete [] floatParams;
2463 }
2464 else if(nativeType == GL_INT)
2465 {
2466 GLint *intParams = NULL;
2467 intParams = new GLint[numParams];
2468
2469 context->getIntegerv(pname, intParams);
2470
2471 for(unsigned int i = 0; i < numParams; ++i)
2472 {
2473 if(intParams[i] == 0)
2474 params[i] = GL_FALSE;
2475 else
2476 params[i] = GL_TRUE;
2477 }
2478
2479 delete [] intParams;
2480 }
2481 }
2482 }
2483}
2484
Nicolas Capensa9b49372015-01-30 00:33:26 -05002485void APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002486{
Nicolas Capens4be33702015-04-28 15:13:30 -07002487 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002488
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002489 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002490
2491 if(context)
2492 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002493 gl::Buffer *buffer;
Nicolas Capens264f1522015-01-09 17:21:17 -05002494
2495 switch(target)
2496 {
2497 case GL_ARRAY_BUFFER:
2498 buffer = context->getArrayBuffer();
2499 break;
2500 case GL_ELEMENT_ARRAY_BUFFER:
2501 buffer = context->getElementArrayBuffer();
2502 break;
2503 default:
2504 return error(GL_INVALID_ENUM);
2505 }
2506
2507 if(!buffer)
2508 {
2509 // A null buffer means that "0" is bound to the requested buffer target
2510 return error(GL_INVALID_OPERATION);
2511 }
2512
2513 switch(pname)
2514 {
2515 case GL_BUFFER_USAGE:
2516 *params = buffer->usage();
2517 break;
2518 case GL_BUFFER_SIZE:
2519 *params = buffer->size();
2520 break;
2521 default:
2522 return error(GL_INVALID_ENUM);
2523 }
2524 }
2525}
2526
Nicolas Capensa9b49372015-01-30 00:33:26 -05002527GLenum APIENTRY glGetError(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05002528{
2529 TRACE("()");
2530
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002531 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002532
2533 if(context)
2534 {
2535 return context->getError();
2536 }
2537
2538 return GL_NO_ERROR;
2539}
2540
Nicolas Capensa9b49372015-01-30 00:33:26 -05002541void APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002542{
Nicolas Capens4be33702015-04-28 15:13:30 -07002543 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002544
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002545 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002546
2547 if(context)
2548 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002549 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05002550
2551 if(fenceObject == NULL)
2552 {
2553 return error(GL_INVALID_OPERATION);
2554 }
2555
2556 fenceObject->getFenceiv(pname, params);
2557 }
2558}
2559
Nicolas Capensa9b49372015-01-30 00:33:26 -05002560void APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002561{
Nicolas Capens4be33702015-04-28 15:13:30 -07002562 TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002563
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002564 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002565
2566 if(context)
2567 {
2568 if(!(context->getFloatv(pname, params)))
2569 {
2570 GLenum nativeType;
2571 unsigned int numParams = 0;
2572 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2573 return error(GL_INVALID_ENUM);
2574
2575 if(numParams == 0)
2576 return; // it is known that the pname is valid, but that there are no parameters to return.
2577
2578 if(nativeType == GL_BOOL)
2579 {
2580 GLboolean *boolParams = NULL;
2581 boolParams = new GLboolean[numParams];
2582
2583 context->getBooleanv(pname, boolParams);
2584
2585 for(unsigned int i = 0; i < numParams; ++i)
2586 {
2587 if(boolParams[i] == GL_FALSE)
2588 params[i] = 0.0f;
2589 else
2590 params[i] = 1.0f;
2591 }
2592
2593 delete [] boolParams;
2594 }
2595 else if(nativeType == GL_INT)
2596 {
2597 GLint *intParams = NULL;
2598 intParams = new GLint[numParams];
2599
2600 context->getIntegerv(pname, intParams);
2601
2602 for(unsigned int i = 0; i < numParams; ++i)
2603 {
2604 params[i] = (GLfloat)intParams[i];
2605 }
2606
2607 delete [] intParams;
2608 }
2609 }
2610 }
2611}
2612
Nicolas Capensa9b49372015-01-30 00:33:26 -05002613void APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002614{
Nicolas Capens4be33702015-04-28 15:13:30 -07002615 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05002616 target, attachment, pname, params);
2617
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002618 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002619
2620 if(context)
2621 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002622 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05002623 {
2624 return error(GL_INVALID_ENUM);
2625 }
2626
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002627 gl::Framebuffer *framebuffer = NULL;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002628 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05002629 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002630 if(context->getReadFramebufferName() == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05002631 {
2632 return error(GL_INVALID_OPERATION);
2633 }
2634
2635 framebuffer = context->getReadFramebuffer();
2636 }
2637 else
2638 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002639 if(context->getDrawFramebufferName() == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05002640 {
2641 return error(GL_INVALID_OPERATION);
2642 }
2643
2644 framebuffer = context->getDrawFramebuffer();
2645 }
2646
2647 GLenum attachmentType;
2648 GLuint attachmentHandle;
2649 switch(attachment)
2650 {
2651 case GL_COLOR_ATTACHMENT0:
2652 attachmentType = framebuffer->getColorbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002653 attachmentHandle = framebuffer->getColorbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002654 break;
2655 case GL_DEPTH_ATTACHMENT:
2656 attachmentType = framebuffer->getDepthbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002657 attachmentHandle = framebuffer->getDepthbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002658 break;
2659 case GL_STENCIL_ATTACHMENT:
2660 attachmentType = framebuffer->getStencilbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002661 attachmentHandle = framebuffer->getStencilbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002662 break;
2663 default:
2664 return error(GL_INVALID_ENUM);
2665 }
2666
2667 GLenum attachmentObjectType; // Type category
2668 if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
2669 {
2670 attachmentObjectType = attachmentType;
2671 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002672 else if(gl::IsTextureTarget(attachmentType))
Nicolas Capens264f1522015-01-09 17:21:17 -05002673 {
2674 attachmentObjectType = GL_TEXTURE;
2675 }
2676 else UNREACHABLE();
2677
2678 switch(pname)
2679 {
2680 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2681 *params = attachmentObjectType;
2682 break;
2683 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2684 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2685 {
2686 *params = attachmentHandle;
2687 }
2688 else
2689 {
2690 return error(GL_INVALID_ENUM);
2691 }
2692 break;
2693 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2694 if(attachmentObjectType == GL_TEXTURE)
2695 {
2696 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2697 }
2698 else
2699 {
2700 return error(GL_INVALID_ENUM);
2701 }
2702 break;
2703 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2704 if(attachmentObjectType == GL_TEXTURE)
2705 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002706 if(gl::IsCubemapTextureTarget(attachmentType))
Nicolas Capens264f1522015-01-09 17:21:17 -05002707 {
2708 *params = attachmentType;
2709 }
2710 else
2711 {
2712 *params = 0;
2713 }
2714 }
2715 else
2716 {
2717 return error(GL_INVALID_ENUM);
2718 }
2719 break;
2720 default:
2721 return error(GL_INVALID_ENUM);
2722 }
2723 }
2724}
2725
Nicolas Capensa9b49372015-01-30 00:33:26 -05002726GLenum APIENTRY glGetGraphicsResetStatusEXT(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05002727{
2728 TRACE("()");
2729
2730 return GL_NO_ERROR;
2731}
2732
Nicolas Capensa9b49372015-01-30 00:33:26 -05002733void APIENTRY glGetIntegerv(GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002734{
Nicolas Capens4be33702015-04-28 15:13:30 -07002735 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002736
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002737 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002738
2739 if(context)
2740 {
2741 if(!(context->getIntegerv(pname, params)))
2742 {
2743 GLenum nativeType;
2744 unsigned int numParams = 0;
2745 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2746 return error(GL_INVALID_ENUM);
2747
2748 if(numParams == 0)
2749 return; // it is known that pname is valid, but there are no parameters to return
2750
2751 if(nativeType == GL_BOOL)
2752 {
2753 GLboolean *boolParams = NULL;
2754 boolParams = new GLboolean[numParams];
2755
2756 context->getBooleanv(pname, boolParams);
2757
2758 for(unsigned int i = 0; i < numParams; ++i)
2759 {
2760 if(boolParams[i] == GL_FALSE)
2761 params[i] = 0;
2762 else
2763 params[i] = 1;
2764 }
2765
2766 delete [] boolParams;
2767 }
2768 else if(nativeType == GL_FLOAT)
2769 {
2770 GLfloat *floatParams = NULL;
2771 floatParams = new GLfloat[numParams];
2772
2773 context->getFloatv(pname, floatParams);
2774
2775 for(unsigned int i = 0; i < numParams; ++i)
2776 {
2777 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
2778 {
2779 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
2780 }
2781 else
2782 {
2783 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
2784 }
2785 }
2786
2787 delete [] floatParams;
2788 }
2789 }
2790 }
2791}
2792
Nicolas Capensa9b49372015-01-30 00:33:26 -05002793void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002794{
Nicolas Capens4be33702015-04-28 15:13:30 -07002795 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002796
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002797 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002798
2799 if(context)
2800 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002801 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002802
2803 if(!programObject)
2804 {
2805 return error(GL_INVALID_VALUE);
2806 }
2807
2808 switch(pname)
2809 {
2810 case GL_DELETE_STATUS:
2811 *params = programObject->isFlaggedForDeletion();
2812 return;
2813 case GL_LINK_STATUS:
2814 *params = programObject->isLinked();
2815 return;
2816 case GL_VALIDATE_STATUS:
2817 *params = programObject->isValidated();
2818 return;
2819 case GL_INFO_LOG_LENGTH:
2820 *params = programObject->getInfoLogLength();
2821 return;
2822 case GL_ATTACHED_SHADERS:
2823 *params = programObject->getAttachedShadersCount();
2824 return;
2825 case GL_ACTIVE_ATTRIBUTES:
2826 *params = programObject->getActiveAttributeCount();
2827 return;
2828 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2829 *params = programObject->getActiveAttributeMaxLength();
2830 return;
2831 case GL_ACTIVE_UNIFORMS:
2832 *params = programObject->getActiveUniformCount();
2833 return;
2834 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2835 *params = programObject->getActiveUniformMaxLength();
2836 return;
2837 default:
2838 return error(GL_INVALID_ENUM);
2839 }
2840 }
2841}
2842
Nicolas Capensa9b49372015-01-30 00:33:26 -05002843void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
Nicolas Capens264f1522015-01-09 17:21:17 -05002844{
Nicolas Capens4be33702015-04-28 15:13:30 -07002845 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05002846 program, bufsize, length, infolog);
2847
2848 if(bufsize < 0)
2849 {
2850 return error(GL_INVALID_VALUE);
2851 }
2852
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002853 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002854
2855 if(context)
2856 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002857 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002858
2859 if(!programObject)
2860 {
2861 return error(GL_INVALID_VALUE);
2862 }
2863
2864 programObject->getInfoLog(bufsize, length, infolog);
2865 }
2866}
2867
Nicolas Capensa9b49372015-01-30 00:33:26 -05002868void APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002869{
Nicolas Capens4be33702015-04-28 15:13:30 -07002870 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002871
2872 switch(pname)
2873 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002874 case GL_CURRENT_QUERY:
Nicolas Capens264f1522015-01-09 17:21:17 -05002875 break;
2876 default:
2877 return error(GL_INVALID_ENUM);
2878 }
2879
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002880 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002881
2882 if(context)
2883 {
2884 params[0] = context->getActiveQuery(target);
2885 }
2886}
2887
Nicolas Capensa9b49372015-01-30 00:33:26 -05002888void APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002889{
Nicolas Capens4be33702015-04-28 15:13:30 -07002890 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002891
2892 switch(pname)
2893 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002894 case GL_QUERY_RESULT:
2895 case GL_QUERY_RESULT_AVAILABLE:
Nicolas Capens264f1522015-01-09 17:21:17 -05002896 break;
2897 default:
2898 return error(GL_INVALID_ENUM);
2899 }
2900
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002901 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002902
2903 if(context)
2904 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002905 gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
Nicolas Capens264f1522015-01-09 17:21:17 -05002906
2907 if(!queryObject)
2908 {
2909 return error(GL_INVALID_OPERATION);
2910 }
2911
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002912 if(context->getActiveQuery(queryObject->getType()) == name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002913 {
2914 return error(GL_INVALID_OPERATION);
2915 }
2916
2917 switch(pname)
2918 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002919 case GL_QUERY_RESULT:
Nicolas Capens264f1522015-01-09 17:21:17 -05002920 params[0] = queryObject->getResult();
2921 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002922 case GL_QUERY_RESULT_AVAILABLE:
Nicolas Capens264f1522015-01-09 17:21:17 -05002923 params[0] = queryObject->isResultAvailable();
2924 break;
2925 default:
2926 ASSERT(false);
2927 }
2928 }
2929}
2930
Nicolas Capensa9b49372015-01-30 00:33:26 -05002931void APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002932{
Nicolas Capens4be33702015-04-28 15:13:30 -07002933 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002934
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002935 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002936
2937 if(context)
2938 {
2939 if(target != GL_RENDERBUFFER)
2940 {
2941 return error(GL_INVALID_ENUM);
2942 }
2943
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002944 if(context->getRenderbufferName() == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05002945 {
2946 return error(GL_INVALID_OPERATION);
2947 }
2948
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002949 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
Nicolas Capens264f1522015-01-09 17:21:17 -05002950
2951 switch(pname)
2952 {
2953 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
2954 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
2955 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
2956 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
2957 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
2958 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
2959 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
2960 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
2961 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002962 case GL_RENDERBUFFER_SAMPLES_EXT: *params = renderbuffer->getSamples(); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05002963 default:
2964 return error(GL_INVALID_ENUM);
2965 }
2966 }
2967}
2968
Nicolas Capensa9b49372015-01-30 00:33:26 -05002969void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002970{
Nicolas Capens4be33702015-04-28 15:13:30 -07002971 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002972
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002973 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002974
2975 if(context)
2976 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002977 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05002978
2979 if(!shaderObject)
2980 {
2981 return error(GL_INVALID_VALUE);
2982 }
2983
2984 switch(pname)
2985 {
2986 case GL_SHADER_TYPE:
2987 *params = shaderObject->getType();
2988 return;
2989 case GL_DELETE_STATUS:
2990 *params = shaderObject->isFlaggedForDeletion();
2991 return;
2992 case GL_COMPILE_STATUS:
2993 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2994 return;
2995 case GL_INFO_LOG_LENGTH:
2996 *params = shaderObject->getInfoLogLength();
2997 return;
2998 case GL_SHADER_SOURCE_LENGTH:
2999 *params = shaderObject->getSourceLength();
3000 return;
3001 default:
3002 return error(GL_INVALID_ENUM);
3003 }
3004 }
3005}
3006
Nicolas Capensa9b49372015-01-30 00:33:26 -05003007void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
Nicolas Capens264f1522015-01-09 17:21:17 -05003008{
Nicolas Capens4be33702015-04-28 15:13:30 -07003009 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003010 shader, bufsize, length, infolog);
3011
3012 if(bufsize < 0)
3013 {
3014 return error(GL_INVALID_VALUE);
3015 }
3016
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003017 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003018
3019 if(context)
3020 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003021 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003022
3023 if(!shaderObject)
3024 {
3025 return error(GL_INVALID_VALUE);
3026 }
3027
3028 shaderObject->getInfoLog(bufsize, length, infolog);
3029 }
3030}
3031
Nicolas Capensa9b49372015-01-30 00:33:26 -05003032void APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
Nicolas Capens264f1522015-01-09 17:21:17 -05003033{
Nicolas Capens4be33702015-04-28 15:13:30 -07003034 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003035 shadertype, precisiontype, range, precision);
3036
3037 switch(shadertype)
3038 {
3039 case GL_VERTEX_SHADER:
3040 case GL_FRAGMENT_SHADER:
3041 break;
3042 default:
3043 return error(GL_INVALID_ENUM);
3044 }
3045
3046 switch(precisiontype)
3047 {
3048 case GL_LOW_FLOAT:
3049 case GL_MEDIUM_FLOAT:
3050 case GL_HIGH_FLOAT:
3051 // IEEE 754 single-precision
3052 range[0] = 127;
3053 range[1] = 127;
3054 *precision = 23;
3055 break;
3056 case GL_LOW_INT:
3057 case GL_MEDIUM_INT:
3058 case GL_HIGH_INT:
3059 // Single-precision floating-point numbers can accurately represent integers up to +/-16777216
3060 range[0] = 24;
3061 range[1] = 24;
3062 *precision = 0;
3063 break;
3064 default:
3065 return error(GL_INVALID_ENUM);
3066 }
3067}
3068
Nicolas Capensa9b49372015-01-30 00:33:26 -05003069void APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
Nicolas Capens264f1522015-01-09 17:21:17 -05003070{
Nicolas Capens4be33702015-04-28 15:13:30 -07003071 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003072 shader, bufsize, length, source);
3073
3074 if(bufsize < 0)
3075 {
3076 return error(GL_INVALID_VALUE);
3077 }
3078
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003079 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003080
3081 if(context)
3082 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003083 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003084
3085 if(!shaderObject)
3086 {
3087 return error(GL_INVALID_OPERATION);
3088 }
3089
3090 shaderObject->getSource(bufsize, length, source);
3091 }
3092}
3093
Nicolas Capensa9b49372015-01-30 00:33:26 -05003094const GLubyte* APIENTRY glGetString(GLenum name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003095{
3096 TRACE("(GLenum name = 0x%X)", name);
3097
Nicolas Capens264f1522015-01-09 17:21:17 -05003098 switch(name)
3099 {
3100 case GL_VENDOR:
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003101 return (GLubyte*)"TransGaming Inc.";
Nicolas Capens264f1522015-01-09 17:21:17 -05003102 case GL_RENDERER:
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003103 return (GLubyte*)"SwiftShader";
Nicolas Capens264f1522015-01-09 17:21:17 -05003104 case GL_VERSION:
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003105 return (GLubyte*)"2.1 SwiftShader "VERSION_STRING;
Nicolas Capens264f1522015-01-09 17:21:17 -05003106 case GL_SHADING_LANGUAGE_VERSION:
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003107 return (GLubyte*)"3.30 SwiftShader "VERSION_STRING;
Nicolas Capens264f1522015-01-09 17:21:17 -05003108 case GL_EXTENSIONS:
3109 // Keep list sorted in following order:
3110 // OES extensions
3111 // EXT extensions
3112 // Vendor extensions
3113 return (GLubyte*)
Maxime Grégoiredf041002015-07-15 15:19:38 -04003114 //"GL_ARB_compressed_texture_pixel_storage "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003115 "GL_ARB_framebuffer_object "
Maxime Grégoiredf041002015-07-15 15:19:38 -04003116 //"GL_ARB_half_float_pixel "
Maxime Grégoiredf041002015-07-15 15:19:38 -04003117 //"GL_ARB_pixel_buffer_object "
Nicolas Capens264f1522015-01-09 17:21:17 -05003118 "GL_EXT_blend_minmax "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003119 "GL_EXT_depth_texture "
3120 "GL_EXT_depth_texture_cube_map "
3121 "GL_EXT_element_index_uint "
3122 "GL_EXT_packed_depth_stencil "
3123 "GL_EXT_rgb8_rgba8 "
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003124 //"GL_EXT_pixel_buffer_object "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003125 "GL_EXT_standard_derivatives "
3126 "GL_EXT_texture_float "
3127 "GL_EXT_texture_float_linear "
3128 "GL_EXT_texture_half_float "
3129 "GL_EXT_texture_half_float_linear "
3130 "GL_EXT_texture_npot "
Nicolas Capens264f1522015-01-09 17:21:17 -05003131 "GL_EXT_occlusion_query_boolean "
3132 "GL_EXT_read_format_bgra "
3133 #if (S3TC_SUPPORT)
3134 "GL_EXT_texture_compression_dxt1 "
3135 #endif
Nicolas Capensa9b49372015-01-30 00:33:26 -05003136 "GL_EXT_blend_func_separate "
3137 "GL_EXT_secondary_color "
Nicolas Capens264f1522015-01-09 17:21:17 -05003138 "GL_EXT_texture_filter_anisotropic "
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003139 //"GL_NV_pixel_data_range "
3140 //"WGL_ARB_pixel_format "
3141 //"WGL_ARB_pixel_format_float "
3142 //"WGL_ATI_pixel_format_float "
3143 //"WGL_EXT_pixel_format_packed_float "
Nicolas Capens264f1522015-01-09 17:21:17 -05003144 "GL_EXT_texture_format_BGRA8888 "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003145 "GL_EXT_framebuffer_blit "
3146 "GL_EXT_framebuffer_multisample "
Nicolas Capens264f1522015-01-09 17:21:17 -05003147 #if (S3TC_SUPPORT)
Nicolas Capensa9b49372015-01-30 00:33:26 -05003148 "GL_EXT_texture_compression_dxt3 "
3149 "GL_EXT_texture_compression_dxt5 "
Nicolas Capens264f1522015-01-09 17:21:17 -05003150 #endif
Maxime Grégoiredff6d002015-07-16 10:26:45 -04003151 "GL_NV_fence";
Nicolas Capens264f1522015-01-09 17:21:17 -05003152 default:
3153 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3154 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05003155
3156 return NULL;
Nicolas Capens264f1522015-01-09 17:21:17 -05003157}
3158
Nicolas Capensa9b49372015-01-30 00:33:26 -05003159void APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003160{
Nicolas Capens4be33702015-04-28 15:13:30 -07003161 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003162
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003163 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003164
3165 if(context)
3166 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003167 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05003168
3169 switch(target)
3170 {
3171 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003172 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05003173 break;
3174 case GL_TEXTURE_CUBE_MAP:
3175 texture = context->getTextureCubeMap();
3176 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003177 default:
3178 return error(GL_INVALID_ENUM);
3179 }
3180
3181 switch(pname)
3182 {
3183 case GL_TEXTURE_MAG_FILTER:
3184 *params = (GLfloat)texture->getMagFilter();
3185 break;
3186 case GL_TEXTURE_MIN_FILTER:
3187 *params = (GLfloat)texture->getMinFilter();
3188 break;
3189 case GL_TEXTURE_WRAP_S:
3190 *params = (GLfloat)texture->getWrapS();
3191 break;
3192 case GL_TEXTURE_WRAP_T:
3193 *params = (GLfloat)texture->getWrapT();
3194 break;
3195 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3196 *params = texture->getMaxAnisotropy();
3197 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003198 default:
3199 return error(GL_INVALID_ENUM);
3200 }
3201 }
3202}
3203
Nicolas Capensa9b49372015-01-30 00:33:26 -05003204void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003205{
Nicolas Capens4be33702015-04-28 15:13:30 -07003206 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003207
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003208 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003209
3210 if(context)
3211 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003212 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05003213
3214 switch(target)
3215 {
3216 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003217 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05003218 break;
3219 case GL_TEXTURE_CUBE_MAP:
3220 texture = context->getTextureCubeMap();
3221 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003222 default:
3223 return error(GL_INVALID_ENUM);
3224 }
3225
3226 switch(pname)
3227 {
3228 case GL_TEXTURE_MAG_FILTER:
3229 *params = texture->getMagFilter();
3230 break;
3231 case GL_TEXTURE_MIN_FILTER:
3232 *params = texture->getMinFilter();
3233 break;
3234 case GL_TEXTURE_WRAP_S:
3235 *params = texture->getWrapS();
3236 break;
3237 case GL_TEXTURE_WRAP_T:
3238 *params = texture->getWrapT();
3239 break;
3240 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3241 *params = (GLint)texture->getMaxAnisotropy();
3242 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003243 default:
3244 return error(GL_INVALID_ENUM);
3245 }
3246 }
3247}
3248
Nicolas Capensa9b49372015-01-30 00:33:26 -05003249void APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003250{
Nicolas Capens4be33702015-04-28 15:13:30 -07003251 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003252 program, location, bufSize, params);
3253
3254 if(bufSize < 0)
3255 {
3256 return error(GL_INVALID_VALUE);
3257 }
3258
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003259 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003260
3261 if(context)
3262 {
3263 if(program == 0)
3264 {
3265 return error(GL_INVALID_VALUE);
3266 }
3267
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003268 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003269
3270 if(!programObject || !programObject->isLinked())
3271 {
3272 return error(GL_INVALID_OPERATION);
3273 }
3274
3275 if(!programObject->getUniformfv(location, &bufSize, params))
3276 {
3277 return error(GL_INVALID_OPERATION);
3278 }
3279 }
3280}
3281
Nicolas Capensa9b49372015-01-30 00:33:26 -05003282void APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003283{
Nicolas Capens4be33702015-04-28 15:13:30 -07003284 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003285
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003286 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003287
3288 if(context)
3289 {
3290 if(program == 0)
3291 {
3292 return error(GL_INVALID_VALUE);
3293 }
3294
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003295 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003296
3297 if(!programObject || !programObject->isLinked())
3298 {
3299 return error(GL_INVALID_OPERATION);
3300 }
3301
3302 if(!programObject->getUniformfv(location, NULL, params))
3303 {
3304 return error(GL_INVALID_OPERATION);
3305 }
3306 }
3307}
3308
Nicolas Capensa9b49372015-01-30 00:33:26 -05003309void APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003310{
Nicolas Capens4be33702015-04-28 15:13:30 -07003311 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003312 program, location, bufSize, params);
3313
3314 if(bufSize < 0)
3315 {
3316 return error(GL_INVALID_VALUE);
3317 }
3318
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003319 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003320
3321 if(context)
3322 {
3323 if(program == 0)
3324 {
3325 return error(GL_INVALID_VALUE);
3326 }
3327
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003328 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003329
3330 if(!programObject || !programObject->isLinked())
3331 {
3332 return error(GL_INVALID_OPERATION);
3333 }
3334
3335 if(!programObject)
3336 {
3337 return error(GL_INVALID_OPERATION);
3338 }
3339
3340 if(!programObject->getUniformiv(location, &bufSize, params))
3341 {
3342 return error(GL_INVALID_OPERATION);
3343 }
3344 }
3345}
3346
Nicolas Capensa9b49372015-01-30 00:33:26 -05003347void APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003348{
Nicolas Capens4be33702015-04-28 15:13:30 -07003349 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003350
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003351 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003352
3353 if(context)
3354 {
3355 if(program == 0)
3356 {
3357 return error(GL_INVALID_VALUE);
3358 }
3359
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003360 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003361
3362 if(!programObject || !programObject->isLinked())
3363 {
3364 return error(GL_INVALID_OPERATION);
3365 }
3366
3367 if(!programObject)
3368 {
3369 return error(GL_INVALID_OPERATION);
3370 }
3371
3372 if(!programObject->getUniformiv(location, NULL, params))
3373 {
3374 return error(GL_INVALID_OPERATION);
3375 }
3376 }
3377}
3378
Nicolas Capensa9b49372015-01-30 00:33:26 -05003379int APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003380{
3381 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
3382
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003383 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003384
3385 if(strstr(name, "gl_") == name)
3386 {
3387 return -1;
3388 }
3389
3390 if(context)
3391 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003392 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003393
3394 if(!programObject)
3395 {
3396 if(context->getShader(program))
3397 {
3398 return error(GL_INVALID_OPERATION, -1);
3399 }
3400 else
3401 {
3402 return error(GL_INVALID_VALUE, -1);
3403 }
3404 }
3405
3406 if(!programObject->isLinked())
3407 {
3408 return error(GL_INVALID_OPERATION, -1);
3409 }
3410
3411 return programObject->getUniformLocation(name);
3412 }
3413
3414 return -1;
3415}
3416
Nicolas Capensa9b49372015-01-30 00:33:26 -05003417void APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003418{
Nicolas Capens4be33702015-04-28 15:13:30 -07003419 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003420
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003421 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003422
3423 if(context)
3424 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003425 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003426 {
3427 return error(GL_INVALID_VALUE);
3428 }
3429
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003430 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
Nicolas Capens264f1522015-01-09 17:21:17 -05003431
3432 switch(pname)
3433 {
3434 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3435 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3436 break;
3437 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3438 *params = (GLfloat)attribState.mSize;
3439 break;
3440 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3441 *params = (GLfloat)attribState.mStride;
3442 break;
3443 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3444 *params = (GLfloat)attribState.mType;
3445 break;
3446 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3447 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
3448 break;
3449 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003450 *params = (GLfloat)attribState.mBoundBuffer.name();
Nicolas Capens264f1522015-01-09 17:21:17 -05003451 break;
3452 case GL_CURRENT_VERTEX_ATTRIB:
3453 for(int i = 0; i < 4; ++i)
3454 {
3455 params[i] = attribState.mCurrentValue[i];
3456 }
3457 break;
3458 default: return error(GL_INVALID_ENUM);
3459 }
3460 }
3461}
3462
Nicolas Capensa9b49372015-01-30 00:33:26 -05003463void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003464{
Nicolas Capens4be33702015-04-28 15:13:30 -07003465 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05003466
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003467 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003468
3469 if(context)
3470 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003471 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003472 {
3473 return error(GL_INVALID_VALUE);
3474 }
3475
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003476 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
Nicolas Capens264f1522015-01-09 17:21:17 -05003477
3478 switch(pname)
3479 {
3480 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3481 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3482 break;
3483 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3484 *params = attribState.mSize;
3485 break;
3486 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3487 *params = attribState.mStride;
3488 break;
3489 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3490 *params = attribState.mType;
3491 break;
3492 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3493 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
3494 break;
3495 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003496 *params = attribState.mBoundBuffer.name();
Nicolas Capens264f1522015-01-09 17:21:17 -05003497 break;
3498 case GL_CURRENT_VERTEX_ATTRIB:
3499 for(int i = 0; i < 4; ++i)
3500 {
3501 float currentValue = attribState.mCurrentValue[i];
3502 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3503 }
3504 break;
3505 default: return error(GL_INVALID_ENUM);
3506 }
3507 }
3508}
3509
Nicolas Capensa9b49372015-01-30 00:33:26 -05003510void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003511{
Nicolas Capens4be33702015-04-28 15:13:30 -07003512 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003513
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003514 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003515
3516 if(context)
3517 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003518 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003519 {
3520 return error(GL_INVALID_VALUE);
3521 }
3522
3523 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3524 {
3525 return error(GL_INVALID_ENUM);
3526 }
3527
3528 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
3529 }
3530}
3531
Nicolas Capensa9b49372015-01-30 00:33:26 -05003532void APIENTRY glHint(GLenum target, GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05003533{
3534 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
3535
3536 switch(mode)
3537 {
3538 case GL_FASTEST:
3539 case GL_NICEST:
3540 case GL_DONT_CARE:
3541 break;
3542 default:
3543 return error(GL_INVALID_ENUM);
3544 }
3545
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003546 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003547 switch(target)
3548 {
3549 case GL_GENERATE_MIPMAP_HINT:
3550 if(context) context->setGenerateMipmapHint(mode);
3551 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05003552 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
Nicolas Capens264f1522015-01-09 17:21:17 -05003553 if(context) context->setFragmentShaderDerivativeHint(mode);
3554 break;
3555 default:
3556 return error(GL_INVALID_ENUM);
3557 }
3558}
3559
Nicolas Capensa9b49372015-01-30 00:33:26 -05003560GLboolean APIENTRY glIsBuffer(GLuint buffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003561{
3562 TRACE("(GLuint buffer = %d)", buffer);
3563
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003564 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003565
3566 if(context && buffer)
3567 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003568 gl::Buffer *bufferObject = context->getBuffer(buffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003569
3570 if(bufferObject)
3571 {
3572 return GL_TRUE;
3573 }
3574 }
3575
3576 return GL_FALSE;
3577}
3578
Nicolas Capensa9b49372015-01-30 00:33:26 -05003579GLboolean APIENTRY glIsEnabled(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05003580{
3581 TRACE("(GLenum cap = 0x%X)", cap);
3582
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003583 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003584
3585 if(context)
3586 {
3587 switch(cap)
3588 {
3589 case GL_CULL_FACE: return context->isCullFaceEnabled();
3590 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3591 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3592 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3593 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3594 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3595 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3596 case GL_BLEND: return context->isBlendEnabled();
3597 case GL_DITHER: return context->isDitherEnabled();
3598 default:
3599 return error(GL_INVALID_ENUM, false);
3600 }
3601 }
3602
3603 return false;
3604}
3605
Nicolas Capensa9b49372015-01-30 00:33:26 -05003606GLboolean APIENTRY glIsFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05003607{
3608 TRACE("(GLuint fence = %d)", fence);
3609
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003610 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003611
3612 if(context)
3613 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003614 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05003615
3616 if(fenceObject == NULL)
3617 {
3618 return GL_FALSE;
3619 }
3620
3621 return fenceObject->isFence();
3622 }
3623
3624 return GL_FALSE;
3625}
3626
Nicolas Capensa9b49372015-01-30 00:33:26 -05003627GLboolean APIENTRY glIsFramebuffer(GLuint framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003628{
3629 TRACE("(GLuint framebuffer = %d)", framebuffer);
3630
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003631 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003632
3633 if(context && framebuffer)
3634 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003635 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003636
3637 if(framebufferObject)
3638 {
3639 return GL_TRUE;
3640 }
3641 }
3642
3643 return GL_FALSE;
3644}
3645
Nicolas Capensa9b49372015-01-30 00:33:26 -05003646GLboolean APIENTRY glIsProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05003647{
3648 TRACE("(GLuint program = %d)", program);
3649
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003650 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003651
3652 if(context && program)
3653 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003654 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003655
3656 if(programObject)
3657 {
3658 return GL_TRUE;
3659 }
3660 }
3661
3662 return GL_FALSE;
3663}
3664
Nicolas Capensa9b49372015-01-30 00:33:26 -05003665GLboolean APIENTRY glIsQueryEXT(GLuint name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003666{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003667 TRACE("(GLuint name = %d)", name);
Nicolas Capens264f1522015-01-09 17:21:17 -05003668
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003669 if(name == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05003670 {
3671 return GL_FALSE;
3672 }
3673
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003674 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003675
3676 if(context)
3677 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003678 gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
Nicolas Capens264f1522015-01-09 17:21:17 -05003679
3680 if(queryObject)
3681 {
3682 return GL_TRUE;
3683 }
3684 }
3685
3686 return GL_FALSE;
3687}
3688
Nicolas Capensa9b49372015-01-30 00:33:26 -05003689GLboolean APIENTRY glIsRenderbuffer(GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003690{
3691 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
3692
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003693 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003694
3695 if(context && renderbuffer)
3696 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003697 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003698
3699 if(renderbufferObject)
3700 {
3701 return GL_TRUE;
3702 }
3703 }
3704
3705 return GL_FALSE;
3706}
3707
Nicolas Capensa9b49372015-01-30 00:33:26 -05003708GLboolean APIENTRY glIsShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05003709{
3710 TRACE("(GLuint shader = %d)", shader);
3711
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003712 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003713
3714 if(context && shader)
3715 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003716 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003717
3718 if(shaderObject)
3719 {
3720 return GL_TRUE;
3721 }
3722 }
3723
3724 return GL_FALSE;
3725}
3726
Nicolas Capensa9b49372015-01-30 00:33:26 -05003727GLboolean APIENTRY glIsTexture(GLuint texture)
Nicolas Capens264f1522015-01-09 17:21:17 -05003728{
3729 TRACE("(GLuint texture = %d)", texture);
3730
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003731 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003732
3733 if(context && texture)
3734 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003735 gl::Texture *textureObject = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -05003736
3737 if(textureObject)
3738 {
3739 return GL_TRUE;
3740 }
3741 }
3742
3743 return GL_FALSE;
3744}
3745
Nicolas Capensa9b49372015-01-30 00:33:26 -05003746void APIENTRY glLineWidth(GLfloat width)
Nicolas Capens264f1522015-01-09 17:21:17 -05003747{
3748 TRACE("(GLfloat width = %f)", width);
3749
3750 if(width <= 0.0f)
3751 {
3752 return error(GL_INVALID_VALUE);
3753 }
3754
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003755 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003756
3757 if(context)
3758 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003759 if(context->getListIndex() != 0)
3760 {
3761 UNIMPLEMENTED();
3762 }
3763
Nicolas Capens264f1522015-01-09 17:21:17 -05003764 context->setLineWidth(width);
3765 }
3766}
3767
Nicolas Capensa9b49372015-01-30 00:33:26 -05003768void APIENTRY glLinkProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05003769{
3770 TRACE("(GLuint program = %d)", program);
3771
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003772 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003773
3774 if(context)
3775 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003776 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003777
3778 if(!programObject)
3779 {
3780 if(context->getShader(program))
3781 {
3782 return error(GL_INVALID_OPERATION);
3783 }
3784 else
3785 {
3786 return error(GL_INVALID_VALUE);
3787 }
3788 }
3789
3790 programObject->link();
3791 }
3792}
3793
Nicolas Capensa9b49372015-01-30 00:33:26 -05003794void APIENTRY glPixelStorei(GLenum pname, GLint param)
Nicolas Capens264f1522015-01-09 17:21:17 -05003795{
3796 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
3797
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003798 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003799
3800 if(context)
3801 {
3802 switch(pname)
3803 {
3804 case GL_UNPACK_ALIGNMENT:
3805 if(param != 1 && param != 2 && param != 4 && param != 8)
3806 {
3807 return error(GL_INVALID_VALUE);
3808 }
3809 context->setUnpackAlignment(param);
3810 break;
3811 case GL_PACK_ALIGNMENT:
3812 if(param != 1 && param != 2 && param != 4 && param != 8)
3813 {
3814 return error(GL_INVALID_VALUE);
3815 }
3816 context->setPackAlignment(param);
3817 break;
3818 default:
3819 return error(GL_INVALID_ENUM);
3820 }
3821 }
3822}
3823
Nicolas Capensa9b49372015-01-30 00:33:26 -05003824void APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
Nicolas Capens264f1522015-01-09 17:21:17 -05003825{
3826 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
3827
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003828 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003829
3830 if(context)
3831 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003832 if(context->getListIndex() != 0)
3833 {
3834 UNIMPLEMENTED();
3835 }
3836
Nicolas Capens264f1522015-01-09 17:21:17 -05003837 context->setPolygonOffsetParams(factor, units);
3838 }
3839}
3840
Nicolas Capensa9b49372015-01-30 00:33:26 -05003841void APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -05003842 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
3843{
3844 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07003845 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003846 x, y, width, height, format, type, bufSize, data);
3847
3848 if(width < 0 || height < 0 || bufSize < 0)
3849 {
3850 return error(GL_INVALID_VALUE);
3851 }
3852
3853 if(!validReadFormatType(format, type))
3854 {
3855 return error(GL_INVALID_OPERATION);
3856 }
3857
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003858 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003859
3860 if(context)
3861 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003862 if(context->getListIndex() != 0)
3863 {
3864 UNIMPLEMENTED();
3865 }
3866
Nicolas Capens264f1522015-01-09 17:21:17 -05003867 context->readPixels(x, y, width, height, format, type, &bufSize, data);
3868 }
3869}
3870
Nicolas Capensa9b49372015-01-30 00:33:26 -05003871void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
Nicolas Capens264f1522015-01-09 17:21:17 -05003872{
3873 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07003874 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05003875 x, y, width, height, format, type, pixels);
3876
3877 if(width < 0 || height < 0)
3878 {
3879 return error(GL_INVALID_VALUE);
3880 }
3881
3882 if(!validReadFormatType(format, type))
3883 {
3884 return error(GL_INVALID_OPERATION);
3885 }
3886
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003887 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003888
3889 if(context)
3890 {
3891 context->readPixels(x, y, width, height, format, type, NULL, pixels);
3892 }
3893}
3894
Nicolas Capensa9b49372015-01-30 00:33:26 -05003895void APIENTRY glReleaseShaderCompiler(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05003896{
3897 TRACE("()");
3898
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003899 gl::Shader::releaseCompiler();
Nicolas Capens264f1522015-01-09 17:21:17 -05003900}
3901
Nicolas Capensa9b49372015-01-30 00:33:26 -05003902void APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05003903{
3904 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3905 target, samples, internalformat, width, height);
3906
3907 switch(target)
3908 {
3909 case GL_RENDERBUFFER:
3910 break;
3911 default:
3912 return error(GL_INVALID_ENUM);
3913 }
3914
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003915 if(!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
Nicolas Capens264f1522015-01-09 17:21:17 -05003916 {
3917 return error(GL_INVALID_ENUM);
3918 }
3919
3920 if(width < 0 || height < 0 || samples < 0)
3921 {
3922 return error(GL_INVALID_VALUE);
3923 }
3924
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003925 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003926
3927 if(context)
3928 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003929 if(context->getListIndex() != 0)
3930 {
3931 UNIMPLEMENTED();
3932 }
3933
3934 if(width > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003935 height > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
3936 samples > gl::IMPLEMENTATION_MAX_SAMPLES)
Nicolas Capens264f1522015-01-09 17:21:17 -05003937 {
3938 return error(GL_INVALID_VALUE);
3939 }
3940
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003941 GLuint handle = context->getRenderbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05003942 if(handle == 0)
3943 {
3944 return error(GL_INVALID_OPERATION);
3945 }
3946
3947 switch(internalformat)
3948 {
3949 case GL_DEPTH_COMPONENT16:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003950 case GL_DEPTH_COMPONENT24:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003951 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003952 break;
3953 case GL_RGBA4:
3954 case GL_RGB5_A1:
3955 case GL_RGB565:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003956 case GL_RGB8_EXT:
3957 case GL_RGBA8_EXT:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003958 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003959 break;
3960 case GL_STENCIL_INDEX8:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003961 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003962 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05003963 case GL_DEPTH24_STENCIL8_EXT:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003964 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003965 break;
3966 default:
3967 return error(GL_INVALID_ENUM);
3968 }
3969 }
3970}
3971
Nicolas Capensa9b49372015-01-30 00:33:26 -05003972void APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05003973{
3974 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
3975}
3976
Nicolas Capensa9b49372015-01-30 00:33:26 -05003977void APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
Nicolas Capens264f1522015-01-09 17:21:17 -05003978{
3979 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
3980
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003981 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003982
3983 if(context)
3984 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003985 if(context->getListIndex() != 0)
3986 {
3987 UNIMPLEMENTED();
3988 }
3989
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003990 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
Nicolas Capens264f1522015-01-09 17:21:17 -05003991 }
3992}
3993
Nicolas Capensa9b49372015-01-30 00:33:26 -05003994void APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
Nicolas Capens264f1522015-01-09 17:21:17 -05003995{
3996 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
3997
3998 if(condition != GL_ALL_COMPLETED_NV)
3999 {
4000 return error(GL_INVALID_ENUM);
4001 }
4002
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004003 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004004
4005 if(context)
4006 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004007 if(context->getListIndex() != 0)
4008 {
4009 UNIMPLEMENTED();
4010 }
4011
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004012 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05004013
4014 if(fenceObject == NULL)
4015 {
4016 return error(GL_INVALID_OPERATION);
4017 }
4018
4019 fenceObject->setFence(condition);
4020 }
4021}
4022
Nicolas Capensa9b49372015-01-30 00:33:26 -05004023void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05004024{
4025 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4026
4027 if(width < 0 || height < 0)
4028 {
4029 return error(GL_INVALID_VALUE);
4030 }
4031
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004032 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004033
4034 if(context)
4035 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004036 if(context->getListIndex() != 0)
4037 {
4038 UNIMPLEMENTED();
4039 }
4040
Nicolas Capens264f1522015-01-09 17:21:17 -05004041 context->setScissorParams(x, y, width, height);
4042 }
4043}
4044
Nicolas Capensa9b49372015-01-30 00:33:26 -05004045void APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
Nicolas Capens264f1522015-01-09 17:21:17 -05004046{
Nicolas Capens4be33702015-04-28 15:13:30 -07004047 TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
4048 "const GLvoid* binary = %p, GLsizei length = %d)",
Nicolas Capens264f1522015-01-09 17:21:17 -05004049 n, shaders, binaryformat, binary, length);
4050
4051 // No binary shader formats are supported.
4052 return error(GL_INVALID_ENUM);
4053}
4054
Nicolas Capensa9b49372015-01-30 00:33:26 -05004055void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
Nicolas Capens264f1522015-01-09 17:21:17 -05004056{
Nicolas Capens4be33702015-04-28 15:13:30 -07004057 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05004058 shader, count, string, length);
4059
4060 if(count < 0)
4061 {
4062 return error(GL_INVALID_VALUE);
4063 }
4064
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004065 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004066
4067 if(context)
4068 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004069 if(context->getListIndex() != 0)
4070 {
4071 UNIMPLEMENTED();
4072 }
4073
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004074 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05004075
4076 if(!shaderObject)
4077 {
4078 if(context->getProgram(shader))
4079 {
4080 return error(GL_INVALID_OPERATION);
4081 }
4082 else
4083 {
4084 return error(GL_INVALID_VALUE);
4085 }
4086 }
4087
4088 shaderObject->setSource(count, string, length);
4089 }
4090}
4091
Nicolas Capensa9b49372015-01-30 00:33:26 -05004092void APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004093{
4094 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4095}
4096
Nicolas Capensa9b49372015-01-30 00:33:26 -05004097void APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004098{
4099 TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
4100
4101 switch(face)
4102 {
4103 case GL_FRONT:
4104 case GL_BACK:
4105 case GL_FRONT_AND_BACK:
4106 break;
4107 default:
4108 return error(GL_INVALID_ENUM);
4109 }
4110
4111 switch(func)
4112 {
4113 case GL_NEVER:
4114 case GL_ALWAYS:
4115 case GL_LESS:
4116 case GL_LEQUAL:
4117 case GL_EQUAL:
4118 case GL_GEQUAL:
4119 case GL_GREATER:
4120 case GL_NOTEQUAL:
4121 break;
4122 default:
4123 return error(GL_INVALID_ENUM);
4124 }
4125
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004126 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004127
4128 if(context)
4129 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004130 if(context->getListIndex() != 0)
4131 {
4132 UNIMPLEMENTED();
4133 }
4134
Nicolas Capens264f1522015-01-09 17:21:17 -05004135 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4136 {
4137 context->setStencilParams(func, ref, mask);
4138 }
4139
4140 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4141 {
4142 context->setStencilBackParams(func, ref, mask);
4143 }
4144 }
4145}
4146
Nicolas Capensa9b49372015-01-30 00:33:26 -05004147void APIENTRY glStencilMask(GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004148{
4149 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4150}
4151
Nicolas Capensa9b49372015-01-30 00:33:26 -05004152void APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004153{
4154 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
4155
4156 switch(face)
4157 {
4158 case GL_FRONT:
4159 case GL_BACK:
4160 case GL_FRONT_AND_BACK:
4161 break;
4162 default:
4163 return error(GL_INVALID_ENUM);
4164 }
4165
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004166 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004167
4168 if(context)
4169 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004170 if(context->getListIndex() != 0)
4171 {
4172 UNIMPLEMENTED();
4173 }
4174
Nicolas Capens264f1522015-01-09 17:21:17 -05004175 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4176 {
4177 context->setStencilWritemask(mask);
4178 }
4179
4180 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4181 {
4182 context->setStencilBackWritemask(mask);
4183 }
4184 }
4185}
4186
Nicolas Capensa9b49372015-01-30 00:33:26 -05004187void APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
Nicolas Capens264f1522015-01-09 17:21:17 -05004188{
4189 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4190}
4191
Nicolas Capensa9b49372015-01-30 00:33:26 -05004192void APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
Nicolas Capens264f1522015-01-09 17:21:17 -05004193{
4194 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4195 face, fail, zfail, zpass);
4196
4197 switch(face)
4198 {
4199 case GL_FRONT:
4200 case GL_BACK:
4201 case GL_FRONT_AND_BACK:
4202 break;
4203 default:
4204 return error(GL_INVALID_ENUM);
4205 }
4206
4207 switch(fail)
4208 {
4209 case GL_ZERO:
4210 case GL_KEEP:
4211 case GL_REPLACE:
4212 case GL_INCR:
4213 case GL_DECR:
4214 case GL_INVERT:
4215 case GL_INCR_WRAP:
4216 case GL_DECR_WRAP:
4217 break;
4218 default:
4219 return error(GL_INVALID_ENUM);
4220 }
4221
4222 switch(zfail)
4223 {
4224 case GL_ZERO:
4225 case GL_KEEP:
4226 case GL_REPLACE:
4227 case GL_INCR:
4228 case GL_DECR:
4229 case GL_INVERT:
4230 case GL_INCR_WRAP:
4231 case GL_DECR_WRAP:
4232 break;
4233 default:
4234 return error(GL_INVALID_ENUM);
4235 }
4236
4237 switch(zpass)
4238 {
4239 case GL_ZERO:
4240 case GL_KEEP:
4241 case GL_REPLACE:
4242 case GL_INCR:
4243 case GL_DECR:
4244 case GL_INVERT:
4245 case GL_INCR_WRAP:
4246 case GL_DECR_WRAP:
4247 break;
4248 default:
4249 return error(GL_INVALID_ENUM);
4250 }
4251
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004252 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004253
4254 if(context)
4255 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004256 if(context->getListIndex() != 0)
4257 {
4258 UNIMPLEMENTED();
4259 }
4260
Nicolas Capens264f1522015-01-09 17:21:17 -05004261 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4262 {
4263 context->setStencilOperations(fail, zfail, zpass);
4264 }
4265
4266 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4267 {
4268 context->setStencilBackOperations(fail, zfail, zpass);
4269 }
4270 }
4271}
4272
Nicolas Capensa9b49372015-01-30 00:33:26 -05004273GLboolean APIENTRY glTestFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05004274{
4275 TRACE("(GLuint fence = %d)", fence);
4276
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004277 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004278
4279 if(context)
4280 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004281 if(context->getListIndex() != 0)
4282 {
4283 UNIMPLEMENTED();
4284 }
4285
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004286 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05004287
4288 if(fenceObject == NULL)
4289 {
4290 return error(GL_INVALID_OPERATION, GL_TRUE);
4291 }
4292
4293 return fenceObject->testFence();
4294 }
4295
4296 return GL_TRUE;
4297}
4298
Nicolas Capensa9b49372015-01-30 00:33:26 -05004299void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -05004300 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4301{
4302 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004303 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05004304 target, level, internalformat, width, height, border, format, type, pixels);
4305
4306 if(!validImageSize(level, width, height))
4307 {
4308 return error(GL_INVALID_VALUE);
4309 }
4310
4311 if(internalformat != format)
4312 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004313 //TRACE("UNIMPLEMENTED!!");
4314 //return error(GL_INVALID_OPERATION);
Nicolas Capens264f1522015-01-09 17:21:17 -05004315 }
4316
4317 switch(format)
4318 {
4319 case GL_ALPHA:
4320 case GL_LUMINANCE:
4321 case GL_LUMINANCE_ALPHA:
4322 switch(type)
4323 {
4324 case GL_UNSIGNED_BYTE:
4325 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004326 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004327 break;
4328 default:
4329 return error(GL_INVALID_ENUM);
4330 }
4331 break;
4332 case GL_RGB:
4333 switch(type)
4334 {
4335 case GL_UNSIGNED_BYTE:
4336 case GL_UNSIGNED_SHORT_5_6_5:
4337 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004338 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004339 break;
4340 default:
4341 return error(GL_INVALID_ENUM);
4342 }
4343 break;
4344 case GL_RGBA:
4345 switch(type)
4346 {
4347 case GL_UNSIGNED_BYTE:
4348 case GL_UNSIGNED_SHORT_4_4_4_4:
4349 case GL_UNSIGNED_SHORT_5_5_5_1:
4350 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004351 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004352 break;
4353 default:
4354 return error(GL_INVALID_ENUM);
4355 }
4356 break;
4357 case GL_BGRA_EXT:
4358 switch(type)
4359 {
4360 case GL_UNSIGNED_BYTE:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004361 case GL_UNSIGNED_SHORT_5_6_5:
4362 case GL_UNSIGNED_INT_8_8_8_8_REV:
Nicolas Capens264f1522015-01-09 17:21:17 -05004363 break;
4364 default:
4365 return error(GL_INVALID_ENUM);
4366 }
4367 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004368 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
Nicolas Capens264f1522015-01-09 17:21:17 -05004369 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004370 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
4371 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
4372 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004373 case GL_DEPTH_COMPONENT:
4374 switch(type)
4375 {
4376 case GL_UNSIGNED_SHORT:
4377 case GL_UNSIGNED_INT:
4378 break;
4379 default:
4380 return error(GL_INVALID_ENUM);
4381 }
4382 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004383 case GL_DEPTH_STENCIL_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004384 switch(type)
4385 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004386 case GL_UNSIGNED_INT_24_8_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004387 break;
4388 default:
4389 return error(GL_INVALID_ENUM);
4390 }
4391 break;
4392 default:
4393 return error(GL_INVALID_VALUE);
4394 }
4395
4396 if(border != 0)
4397 {
4398 return error(GL_INVALID_VALUE);
4399 }
4400
Nicolas Capensa9b49372015-01-30 00:33:26 -05004401 switch(target)
4402 {
Maxime Grégoire5e582162015-07-16 12:52:57 -04004403 case GL_TEXTURE_1D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004404 case GL_TEXTURE_2D:
4405 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4406 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4407 {
4408 return error(GL_INVALID_VALUE);
4409 }
4410 break;
4411 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4412 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4413 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4414 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4415 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4416 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4417 if(width != height)
4418 {
4419 return error(GL_INVALID_VALUE);
4420 }
4421
4422 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
4423 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
4424 {
4425 return error(GL_INVALID_VALUE);
4426 }
4427 break;
4428 case GL_PROXY_TEXTURE_2D:
4429 pixels = 0;
4430
4431 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4432 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4433 {
4434 //UNIMPLEMENTED();
4435 width = 0;
4436 height = 0;
4437 internalformat = GL_NONE;
4438 format = GL_NONE;
4439 type = GL_NONE;
4440
4441 //return;// error(GL_INVALID_VALUE);
4442 }
4443 break;
4444 default:
4445 return error(GL_INVALID_ENUM);
4446 }
4447
4448 if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4449 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
4450 format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
4451 format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
4452 {
4453 if(S3TC_SUPPORT)
4454 {
4455 return error(GL_INVALID_OPERATION);
4456 }
4457 else
4458 {
4459 return error(GL_INVALID_ENUM);
4460 }
4461 }
4462
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004463 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004464
4465 if(context)
4466 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004467 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05004468 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004469 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05004470 }
4471
Maxime Grégoire5e582162015-07-16 12:52:57 -04004472 if(target == GL_TEXTURE_1D)
4473 {
4474 gl::Texture1D *texture = context->getTexture1D();
4475
4476 if(!texture)
4477 {
4478 return error(GL_INVALID_OPERATION);
4479 }
4480
4481 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
4482 }
4483 else if(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D)
Nicolas Capens264f1522015-01-09 17:21:17 -05004484 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004485 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004486
4487 if(!texture)
4488 {
4489 return error(GL_INVALID_OPERATION);
4490 }
4491
4492 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
4493 }
4494 else
4495 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004496 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05004497
4498 if(!texture)
4499 {
4500 return error(GL_INVALID_OPERATION);
4501 }
4502
4503 texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
4504 }
4505 }
4506}
4507
Nicolas Capensa9b49372015-01-30 00:33:26 -05004508void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
Nicolas Capens264f1522015-01-09 17:21:17 -05004509{
4510 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
4511
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004512 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004513
4514 if(context)
4515 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004516 if(context->getListIndex() != 0)
4517 {
4518 UNIMPLEMENTED();
4519 }
4520
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004521 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05004522
4523 switch(target)
4524 {
4525 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004526 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004527 break;
4528 case GL_TEXTURE_CUBE_MAP:
4529 texture = context->getTextureCubeMap();
4530 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004531 default:
4532 return error(GL_INVALID_ENUM);
4533 }
4534
4535 switch(pname)
4536 {
4537 case GL_TEXTURE_WRAP_S:
4538 if(!texture->setWrapS((GLenum)param))
4539 {
4540 return error(GL_INVALID_ENUM);
4541 }
4542 break;
4543 case GL_TEXTURE_WRAP_T:
4544 if(!texture->setWrapT((GLenum)param))
4545 {
4546 return error(GL_INVALID_ENUM);
4547 }
4548 break;
4549 case GL_TEXTURE_MIN_FILTER:
4550 if(!texture->setMinFilter((GLenum)param))
4551 {
4552 return error(GL_INVALID_ENUM);
4553 }
4554 break;
4555 case GL_TEXTURE_MAG_FILTER:
4556 if(!texture->setMagFilter((GLenum)param))
4557 {
4558 return error(GL_INVALID_ENUM);
4559 }
4560 break;
4561 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4562 if(!texture->setMaxAnisotropy(param))
4563 {
4564 return error(GL_INVALID_VALUE);
4565 }
4566 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004567 case GL_TEXTURE_MIN_LOD:
4568 //TRACE("() UNIMPLEMENTED!!"); // FIXME
4569 //UNIMPLEMENTED();
4570 break;
4571 case GL_TEXTURE_MAX_LOD:
4572 //TRACE("() UNIMPLEMENTED!!"); // FIXME
4573 //UNIMPLEMENTED();
4574 break;
4575 case GL_TEXTURE_LOD_BIAS:
4576 if(param != 0.0f)
4577 {
4578 UNIMPLEMENTED();
4579 }
4580 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004581 default:
4582 return error(GL_INVALID_ENUM);
4583 }
4584 }
4585}
4586
Nicolas Capensa9b49372015-01-30 00:33:26 -05004587void APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05004588{
4589 glTexParameterf(target, pname, *params);
4590}
4591
Nicolas Capensa9b49372015-01-30 00:33:26 -05004592void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
Nicolas Capens264f1522015-01-09 17:21:17 -05004593{
4594 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
4595
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004596 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004597
4598 if(context)
4599 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004600 if(context->getListIndex() != 0)
4601 {
4602 UNIMPLEMENTED();
4603 }
4604
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004605 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05004606
4607 switch(target)
4608 {
Maxime Grégoire5e582162015-07-16 12:52:57 -04004609 case GL_TEXTURE_1D:
4610 texture = context->getTexture1D();
4611 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004612 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004613 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004614 break;
4615 case GL_TEXTURE_CUBE_MAP:
4616 texture = context->getTextureCubeMap();
4617 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004618 default:
4619 return error(GL_INVALID_ENUM);
4620 }
4621
4622 switch(pname)
4623 {
4624 case GL_TEXTURE_WRAP_S:
4625 if(!texture->setWrapS((GLenum)param))
4626 {
4627 return error(GL_INVALID_ENUM);
4628 }
4629 break;
4630 case GL_TEXTURE_WRAP_T:
4631 if(!texture->setWrapT((GLenum)param))
4632 {
4633 return error(GL_INVALID_ENUM);
4634 }
4635 break;
4636 case GL_TEXTURE_MIN_FILTER:
4637 if(!texture->setMinFilter((GLenum)param))
4638 {
4639 return error(GL_INVALID_ENUM);
4640 }
4641 break;
4642 case GL_TEXTURE_MAG_FILTER:
4643 if(!texture->setMagFilter((GLenum)param))
4644 {
4645 return error(GL_INVALID_ENUM);
4646 }
4647 break;
4648 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4649 if(!texture->setMaxAnisotropy((GLfloat)param))
4650 {
4651 return error(GL_INVALID_VALUE);
4652 }
4653 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004654 case GL_TEXTURE_MAX_LEVEL:
4655 if(!texture->setMaxLevel(param))
4656 {
4657 return error(GL_INVALID_ENUM);
4658 }
4659 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004660 default:
4661 return error(GL_INVALID_ENUM);
4662 }
4663 }
4664}
4665
Nicolas Capensa9b49372015-01-30 00:33:26 -05004666void APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05004667{
4668 glTexParameteri(target, pname, *params);
4669}
4670
Nicolas Capensa9b49372015-01-30 00:33:26 -05004671void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4672 GLenum format, GLenum type, const GLvoid* pixels)
Nicolas Capens264f1522015-01-09 17:21:17 -05004673{
4674 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4675 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07004676 "const GLvoid* pixels = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05004677 target, level, xoffset, yoffset, width, height, format, type, pixels);
4678
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004679 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05004680 {
4681 return error(GL_INVALID_ENUM);
4682 }
4683
4684 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
4685 {
4686 return error(GL_INVALID_VALUE);
4687 }
4688
4689 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4690 {
4691 return error(GL_INVALID_VALUE);
4692 }
4693
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004694 if(!gl::CheckTextureFormatType(format, type))
Nicolas Capens264f1522015-01-09 17:21:17 -05004695 {
4696 return error(GL_INVALID_ENUM);
4697 }
4698
4699 if(width == 0 || height == 0 || pixels == NULL)
4700 {
4701 return;
4702 }
4703
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004704 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004705
4706 if(context)
4707 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004708 if(context->getListIndex() != 0)
4709 {
4710 UNIMPLEMENTED();
4711 }
4712
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004713 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -05004714 {
4715 return error(GL_INVALID_VALUE);
4716 }
4717
Maxime Grégoire5e582162015-07-16 12:52:57 -04004718 if(target == GL_TEXTURE_1D)
4719 {
4720 gl::Texture1D *texture = context->getTexture1D();
4721
4722 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
4723 {
4724 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4725 }
4726 }
4727 else if(target == GL_TEXTURE_2D)
Nicolas Capens264f1522015-01-09 17:21:17 -05004728 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004729 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004730
4731 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
4732 {
4733 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4734 }
4735 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004736 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05004737 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004738 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05004739
4740 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
4741 {
4742 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4743 }
4744 }
4745 else
4746 {
4747 UNREACHABLE();
4748 }
4749 }
4750}
4751
Nicolas Capensa9b49372015-01-30 00:33:26 -05004752void APIENTRY glUniform1f(GLint location, GLfloat x)
Nicolas Capens264f1522015-01-09 17:21:17 -05004753{
4754 glUniform1fv(location, 1, &x);
4755}
4756
Nicolas Capensa9b49372015-01-30 00:33:26 -05004757void APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004758{
Nicolas Capens4be33702015-04-28 15:13:30 -07004759 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004760
4761 if(count < 0)
4762 {
4763 return error(GL_INVALID_VALUE);
4764 }
4765
4766 if(location == -1)
4767 {
4768 return;
4769 }
4770
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004771 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004772
4773 if(context)
4774 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004775 if(context->getListIndex() != 0)
4776 {
4777 UNIMPLEMENTED();
4778 }
4779
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004780 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004781
4782 if(!program)
4783 {
4784 return error(GL_INVALID_OPERATION);
4785 }
4786
4787 if(!program->setUniform1fv(location, count, v))
4788 {
4789 return error(GL_INVALID_OPERATION);
4790 }
4791 }
4792}
4793
Nicolas Capensa9b49372015-01-30 00:33:26 -05004794void APIENTRY glUniform1i(GLint location, GLint x)
Nicolas Capens264f1522015-01-09 17:21:17 -05004795{
4796 glUniform1iv(location, 1, &x);
4797}
4798
Nicolas Capensa9b49372015-01-30 00:33:26 -05004799void APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004800{
Nicolas Capens4be33702015-04-28 15:13:30 -07004801 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004802
4803 if(count < 0)
4804 {
4805 return error(GL_INVALID_VALUE);
4806 }
4807
4808 if(location == -1)
4809 {
4810 return;
4811 }
4812
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004813 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004814
4815 if(context)
4816 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004817 if(context->getListIndex() != 0)
4818 {
4819 UNIMPLEMENTED();
4820 }
4821
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004822 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004823
4824 if(!program)
4825 {
4826 return error(GL_INVALID_OPERATION);
4827 }
4828
4829 if(!program->setUniform1iv(location, count, v))
4830 {
4831 return error(GL_INVALID_OPERATION);
4832 }
4833 }
4834}
4835
Nicolas Capensa9b49372015-01-30 00:33:26 -05004836void APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
Nicolas Capens264f1522015-01-09 17:21:17 -05004837{
4838 GLfloat xy[2] = {x, y};
4839
4840 glUniform2fv(location, 1, (GLfloat*)&xy);
4841}
4842
Nicolas Capensa9b49372015-01-30 00:33:26 -05004843void APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004844{
Nicolas Capens4be33702015-04-28 15:13:30 -07004845 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004846
4847 if(count < 0)
4848 {
4849 return error(GL_INVALID_VALUE);
4850 }
4851
4852 if(location == -1)
4853 {
4854 return;
4855 }
4856
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004857 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004858
4859 if(context)
4860 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004861 if(context->getListIndex() != 0)
4862 {
4863 UNIMPLEMENTED();
4864 }
4865
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004866 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004867
4868 if(!program)
4869 {
4870 return error(GL_INVALID_OPERATION);
4871 }
4872
4873 if(!program->setUniform2fv(location, count, v))
4874 {
4875 return error(GL_INVALID_OPERATION);
4876 }
4877 }
4878}
4879
Nicolas Capensa9b49372015-01-30 00:33:26 -05004880void APIENTRY glUniform2i(GLint location, GLint x, GLint y)
Nicolas Capens264f1522015-01-09 17:21:17 -05004881{
4882 GLint xy[4] = {x, y};
4883
4884 glUniform2iv(location, 1, (GLint*)&xy);
4885}
4886
Nicolas Capensa9b49372015-01-30 00:33:26 -05004887void APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004888{
Nicolas Capens4be33702015-04-28 15:13:30 -07004889 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004890
4891 if(count < 0)
4892 {
4893 return error(GL_INVALID_VALUE);
4894 }
4895
4896 if(location == -1)
4897 {
4898 return;
4899 }
4900
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004901 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004902
4903 if(context)
4904 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004905 if(context->getListIndex() != 0)
4906 {
4907 UNIMPLEMENTED();
4908 }
4909
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004910 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004911
4912 if(!program)
4913 {
4914 return error(GL_INVALID_OPERATION);
4915 }
4916
4917 if(!program->setUniform2iv(location, count, v))
4918 {
4919 return error(GL_INVALID_OPERATION);
4920 }
4921 }
4922}
4923
Nicolas Capensa9b49372015-01-30 00:33:26 -05004924void APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
Nicolas Capens264f1522015-01-09 17:21:17 -05004925{
4926 GLfloat xyz[3] = {x, y, z};
4927
4928 glUniform3fv(location, 1, (GLfloat*)&xyz);
4929}
4930
Nicolas Capensa9b49372015-01-30 00:33:26 -05004931void APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004932{
Nicolas Capens4be33702015-04-28 15:13:30 -07004933 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004934
4935 if(count < 0)
4936 {
4937 return error(GL_INVALID_VALUE);
4938 }
4939
4940 if(location == -1)
4941 {
4942 return;
4943 }
4944
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004945 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004946
4947 if(context)
4948 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004949 if(context->getListIndex() != 0)
4950 {
4951 UNIMPLEMENTED();
4952 }
4953
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004954 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004955
4956 if(!program)
4957 {
4958 return error(GL_INVALID_OPERATION);
4959 }
4960
4961 if(!program->setUniform3fv(location, count, v))
4962 {
4963 return error(GL_INVALID_OPERATION);
4964 }
4965 }
4966}
4967
Nicolas Capensa9b49372015-01-30 00:33:26 -05004968void APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
Nicolas Capens264f1522015-01-09 17:21:17 -05004969{
4970 GLint xyz[3] = {x, y, z};
4971
4972 glUniform3iv(location, 1, (GLint*)&xyz);
4973}
4974
Nicolas Capensa9b49372015-01-30 00:33:26 -05004975void APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004976{
Nicolas Capens4be33702015-04-28 15:13:30 -07004977 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05004978
4979 if(count < 0)
4980 {
4981 return error(GL_INVALID_VALUE);
4982 }
4983
4984 if(location == -1)
4985 {
4986 return;
4987 }
4988
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004989 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004990
4991 if(context)
4992 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004993 if(context->getListIndex() != 0)
4994 {
4995 UNIMPLEMENTED();
4996 }
4997
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004998 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004999
5000 if(!program)
5001 {
5002 return error(GL_INVALID_OPERATION);
5003 }
5004
5005 if(!program->setUniform3iv(location, count, v))
5006 {
5007 return error(GL_INVALID_OPERATION);
5008 }
5009 }
5010}
5011
Nicolas Capensa9b49372015-01-30 00:33:26 -05005012void APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Nicolas Capens264f1522015-01-09 17:21:17 -05005013{
5014 GLfloat xyzw[4] = {x, y, z, w};
5015
5016 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5017}
5018
Nicolas Capensa9b49372015-01-30 00:33:26 -05005019void APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05005020{
Nicolas Capens4be33702015-04-28 15:13:30 -07005021 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05005022
5023 if(count < 0)
5024 {
5025 return error(GL_INVALID_VALUE);
5026 }
5027
5028 if(location == -1)
5029 {
5030 return;
5031 }
5032
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005033 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005034
5035 if(context)
5036 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005037 if(context->getListIndex() != 0)
5038 {
5039 UNIMPLEMENTED();
5040 }
5041
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005042 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005043
5044 if(!program)
5045 {
5046 return error(GL_INVALID_OPERATION);
5047 }
5048
5049 if(!program->setUniform4fv(location, count, v))
5050 {
5051 return error(GL_INVALID_OPERATION);
5052 }
5053 }
5054}
5055
Nicolas Capensa9b49372015-01-30 00:33:26 -05005056void APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
Nicolas Capens264f1522015-01-09 17:21:17 -05005057{
5058 GLint xyzw[4] = {x, y, z, w};
5059
5060 glUniform4iv(location, 1, (GLint*)&xyzw);
5061}
5062
Nicolas Capensa9b49372015-01-30 00:33:26 -05005063void APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05005064{
Nicolas Capens4be33702015-04-28 15:13:30 -07005065 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
Nicolas Capens264f1522015-01-09 17:21:17 -05005066
5067 if(count < 0)
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->setUniform4iv(location, count, v))
5094 {
5095 return error(GL_INVALID_OPERATION);
5096 }
5097 }
5098}
5099
Nicolas Capensa9b49372015-01-30 00:33:26 -05005100void APIENTRY glUniformMatrix2fv(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->setUniformMatrix2fv(location, count, value))
5132 {
5133 return error(GL_INVALID_OPERATION);
5134 }
5135 }
5136}
5137
Nicolas Capensa9b49372015-01-30 00:33:26 -05005138void APIENTRY glUniformMatrix3fv(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->setUniformMatrix3fv(location, count, value))
5170 {
5171 return error(GL_INVALID_OPERATION);
5172 }
5173 }
5174}
5175
Nicolas Capensa9b49372015-01-30 00:33:26 -05005176void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005177{
Nicolas Capens4be33702015-04-28 15:13:30 -07005178 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005179 location, count, transpose, value);
5180
5181 if(count < 0 || transpose != GL_FALSE)
5182 {
5183 return error(GL_INVALID_VALUE);
5184 }
5185
5186 if(location == -1)
5187 {
5188 return;
5189 }
5190
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005191 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005192
5193 if(context)
5194 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005195 if(context->getListIndex() != 0)
5196 {
5197 UNIMPLEMENTED();
5198 }
5199
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005200 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005201
5202 if(!program)
5203 {
5204 return error(GL_INVALID_OPERATION);
5205 }
5206
5207 if(!program->setUniformMatrix4fv(location, count, value))
5208 {
5209 return error(GL_INVALID_OPERATION);
5210 }
5211 }
5212}
5213
Nicolas Capensa9b49372015-01-30 00:33:26 -05005214void APIENTRY glUseProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05005215{
5216 TRACE("(GLuint program = %d)", program);
5217
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005218 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005219
5220 if(context)
5221 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005222 if(context->getListIndex() != 0)
5223 {
5224 UNIMPLEMENTED();
5225 }
5226
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005227 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05005228
5229 if(!programObject && program != 0)
5230 {
5231 if(context->getShader(program))
5232 {
5233 return error(GL_INVALID_OPERATION);
5234 }
5235 else
5236 {
5237 return error(GL_INVALID_VALUE);
5238 }
5239 }
5240
5241 if(program != 0 && !programObject->isLinked())
5242 {
5243 return error(GL_INVALID_OPERATION);
5244 }
5245
5246 context->useProgram(program);
5247 }
5248}
5249
Nicolas Capensa9b49372015-01-30 00:33:26 -05005250void APIENTRY glValidateProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05005251{
5252 TRACE("(GLuint program = %d)", program);
5253
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005254 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005255
5256 if(context)
5257 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005258 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05005259
5260 if(!programObject)
5261 {
5262 if(context->getShader(program))
5263 {
5264 return error(GL_INVALID_OPERATION);
5265 }
5266 else
5267 {
5268 return error(GL_INVALID_VALUE);
5269 }
5270 }
5271
5272 programObject->validate();
5273 }
5274}
5275
Nicolas Capensa9b49372015-01-30 00:33:26 -05005276void APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
Nicolas Capens264f1522015-01-09 17:21:17 -05005277{
5278 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
5279
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005280 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005281 {
5282 return error(GL_INVALID_VALUE);
5283 }
5284
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005285 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005286
5287 if(context)
5288 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005289 if(context->getListIndex() != 0)
5290 {
5291 UNIMPLEMENTED();
5292 }
5293
5294 //GLfloat vals[4] = { x, 0, 0, 1 };
5295 context->setVertexAttrib(index, x, 0, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005296 }
5297}
5298
Nicolas Capensa9b49372015-01-30 00:33:26 -05005299void APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005300{
Nicolas Capens4be33702015-04-28 15:13:30 -07005301 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
Nicolas Capens264f1522015-01-09 17:21:17 -05005302
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005303 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005304 {
5305 return error(GL_INVALID_VALUE);
5306 }
5307
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005308 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005309
5310 if(context)
5311 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005312 if(context->getListIndex() != 0)
5313 {
5314 UNIMPLEMENTED();
5315 }
5316
5317 //GLfloat vals[4] = { values[0], 0, 0, 1 };
5318 context->setVertexAttrib(index, values[0], 0, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005319 }
5320}
5321
Nicolas Capensa9b49372015-01-30 00:33:26 -05005322void APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
Nicolas Capens264f1522015-01-09 17:21:17 -05005323{
5324 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
5325
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005326 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005327 {
5328 return error(GL_INVALID_VALUE);
5329 }
5330
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005331 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005332
5333 if(context)
5334 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005335 if(context->getListIndex() != 0)
5336 {
5337 UNIMPLEMENTED();
5338 }
5339
5340 //GLfloat vals[4] = { x, y, 0, 1 };
5341 context->setVertexAttrib(index, x, y, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005342 }
5343}
5344
Nicolas Capensa9b49372015-01-30 00:33:26 -05005345void APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005346{
Nicolas Capens4be33702015-04-28 15:13:30 -07005347 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
Nicolas Capens264f1522015-01-09 17:21:17 -05005348
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005349 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005350 {
5351 return error(GL_INVALID_VALUE);
5352 }
5353
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005354 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005355
5356 if(context)
5357 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005358 if(context->getListIndex() != 0)
5359 {
5360 UNIMPLEMENTED();
5361 }
5362
5363 //GLfloat vals[4] = { };
5364 context->setVertexAttrib(index, values[0], values[1], 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005365 }
5366}
5367
Nicolas Capensa9b49372015-01-30 00:33:26 -05005368void APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
Nicolas Capens264f1522015-01-09 17:21:17 -05005369{
5370 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
5371
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005372 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005373 {
5374 return error(GL_INVALID_VALUE);
5375 }
5376
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005377 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005378
5379 if(context)
5380 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005381 if(context->getListIndex() != 0)
5382 {
5383 UNIMPLEMENTED();
5384 }
5385
5386 //GLfloat vals[4] = { x, y, z, 1 };
5387 context->setVertexAttrib(index, x, y, z, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005388 }
5389}
5390
Nicolas Capensa9b49372015-01-30 00:33:26 -05005391void APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005392{
Nicolas Capens4be33702015-04-28 15:13:30 -07005393 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
Nicolas Capens264f1522015-01-09 17:21:17 -05005394
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005395 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005396 {
5397 return error(GL_INVALID_VALUE);
5398 }
5399
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005400 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005401
5402 if(context)
5403 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005404 if(context->getListIndex() != 0)
5405 {
5406 UNIMPLEMENTED();
5407 }
5408
5409 //GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5410 context->setVertexAttrib(index, values[0], values[1], values[2], 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005411 }
5412}
5413
Nicolas Capensa9b49372015-01-30 00:33:26 -05005414void APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Nicolas Capens264f1522015-01-09 17:21:17 -05005415{
5416 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
5417
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005418 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005419 {
5420 return error(GL_INVALID_VALUE);
5421 }
5422
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005423 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005424
5425 if(context)
5426 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005427 if(context->getListIndex() != 0)
5428 {
5429 UNIMPLEMENTED();
5430 }
5431
5432 //GLfloat vals[4] = { x, y, z, w };
5433 context->setVertexAttrib(index, x, y, z, w);
Nicolas Capens264f1522015-01-09 17:21:17 -05005434 }
5435}
5436
Nicolas Capensa9b49372015-01-30 00:33:26 -05005437void APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005438{
Nicolas Capens4be33702015-04-28 15:13:30 -07005439 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
Nicolas Capens264f1522015-01-09 17:21:17 -05005440
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005441 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005442 {
5443 return error(GL_INVALID_VALUE);
5444 }
5445
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005446 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005447
5448 if(context)
5449 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005450 if(context->getListIndex() != 0)
5451 {
5452 UNIMPLEMENTED();
5453 }
5454
5455 context->setVertexAttrib(index, values[0], values[1], values[2], values[3]);
Nicolas Capens264f1522015-01-09 17:21:17 -05005456 }
5457}
5458
Nicolas Capensa9b49372015-01-30 00:33:26 -05005459void APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
Nicolas Capens264f1522015-01-09 17:21:17 -05005460{
5461 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
Nicolas Capens4be33702015-04-28 15:13:30 -07005462 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005463 index, size, type, normalized, stride, ptr);
5464
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005465 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005466 {
5467 return error(GL_INVALID_VALUE);
5468 }
5469
5470 if(size < 1 || size > 4)
5471 {
5472 return error(GL_INVALID_VALUE);
5473 }
5474
5475 switch(type)
5476 {
5477 case GL_BYTE:
5478 case GL_UNSIGNED_BYTE:
5479 case GL_SHORT:
5480 case GL_UNSIGNED_SHORT:
5481 case GL_FIXED:
5482 case GL_FLOAT:
5483 break;
5484 default:
5485 return error(GL_INVALID_ENUM);
5486 }
5487
5488 if(stride < 0)
5489 {
5490 return error(GL_INVALID_VALUE);
5491 }
5492
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005493 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005494
5495 if(context)
5496 {
5497 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
5498 }
5499}
5500
Nicolas Capensa9b49372015-01-30 00:33:26 -05005501void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05005502{
5503 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
5504
5505 if(width < 0 || height < 0)
5506 {
5507 return error(GL_INVALID_VALUE);
5508 }
5509
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005510 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005511
5512 if(context)
5513 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005514 if(context->getListIndex() != 0)
5515 {
5516 UNIMPLEMENTED();
5517 }
5518
Nicolas Capens264f1522015-01-09 17:21:17 -05005519 context->setViewportParams(x, y, width, height);
5520 }
5521}
5522
Nicolas Capensa9b49372015-01-30 00:33:26 -05005523void 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 -05005524 GLbitfield mask, GLenum filter)
5525{
5526 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5527 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5528 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5529 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5530
5531 switch(filter)
5532 {
5533 case GL_NEAREST:
5534 break;
5535 default:
5536 return error(GL_INVALID_ENUM);
5537 }
5538
5539 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5540 {
5541 return error(GL_INVALID_VALUE);
5542 }
5543
5544 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5545 {
5546 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5547 return error(GL_INVALID_OPERATION);
5548 }
5549
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005550 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005551
5552 if(context)
5553 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005554 if(context->getListIndex() != 0)
5555 {
5556 UNIMPLEMENTED();
5557 }
5558
Nicolas Capens7cc75e12015-01-29 14:44:24 -05005559 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
Nicolas Capens264f1522015-01-09 17:21:17 -05005560 {
5561 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5562 return error(GL_INVALID_OPERATION);
5563 }
5564
5565 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5566 }
5567}
5568
Nicolas Capensa9b49372015-01-30 00:33:26 -05005569void APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
Nicolas Capens264f1522015-01-09 17:21:17 -05005570 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
5571{
5572 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5573 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
Nicolas Capens4be33702015-04-28 15:13:30 -07005574 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
Nicolas Capens264f1522015-01-09 17:21:17 -05005575 target, level, internalformat, width, height, depth, border, format, type, pixels);
5576
5577 UNIMPLEMENTED(); // FIXME
5578}
5579
Nicolas Capensa9b49372015-01-30 00:33:26 -05005580void WINAPI GlmfBeginGlsBlock()
Nicolas Capens264f1522015-01-09 17:21:17 -05005581{
Nicolas Capensa9b49372015-01-30 00:33:26 -05005582 UNIMPLEMENTED();
5583}
5584
5585void WINAPI GlmfCloseMetaFile()
5586{
5587 UNIMPLEMENTED();
5588}
5589
5590void WINAPI GlmfEndGlsBlock()
5591{
5592 UNIMPLEMENTED();
5593}
5594
5595void WINAPI GlmfEndPlayback()
5596{
5597 UNIMPLEMENTED();
5598}
5599
5600void WINAPI GlmfInitPlayback()
5601{
5602 UNIMPLEMENTED();
5603}
5604
5605void WINAPI GlmfPlayGlsRecord()
5606{
5607 UNIMPLEMENTED();
5608}
5609
5610void APIENTRY glAccum(GLenum op, GLfloat value)
5611{
5612 UNIMPLEMENTED();
5613}
5614
5615void APIENTRY glAlphaFunc(GLenum func, GLclampf ref)
5616{
5617 TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);
5618
5619 gl::Context *context = gl::getContext();
5620
5621 if(context)
Nicolas Capens264f1522015-01-09 17:21:17 -05005622 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005623 if(context->getListIndex() != 0)
5624 {
5625 UNIMPLEMENTED();
5626 }
5627
5628 context->alphaFunc(func, ref);
Nicolas Capens264f1522015-01-09 17:21:17 -05005629 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05005630}
Nicolas Capens264f1522015-01-09 17:21:17 -05005631
Nicolas Capensa9b49372015-01-30 00:33:26 -05005632GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
5633{
5634 UNIMPLEMENTED();
5635 return GL_FALSE;
5636}
Nicolas Capens264f1522015-01-09 17:21:17 -05005637
Nicolas Capensa9b49372015-01-30 00:33:26 -05005638void APIENTRY glArrayElement(GLint i)
5639{
5640 UNIMPLEMENTED();
5641}
5642
5643void APIENTRY glBegin(GLenum mode)
5644{
5645 TRACE("(GLenum mode = 0x%X)", mode);
5646
5647 switch(mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05005648 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005649 case GL_POINTS:
5650 case GL_LINES:
5651 case GL_LINE_STRIP:
5652 case GL_LINE_LOOP:
5653 case GL_TRIANGLES:
5654 case GL_TRIANGLE_STRIP:
5655 case GL_TRIANGLE_FAN:
5656 case GL_QUADS:
5657 case GL_QUAD_STRIP:
5658 case GL_POLYGON:
Nicolas Capens264f1522015-01-09 17:21:17 -05005659 break;
5660 default:
5661 return error(GL_INVALID_ENUM);
5662 }
5663
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005664 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005665
5666 if(context)
5667 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005668 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05005669 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005670 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05005671 }
5672
Nicolas Capensa9b49372015-01-30 00:33:26 -05005673 context->begin(mode);
Nicolas Capens264f1522015-01-09 17:21:17 -05005674 }
5675}
5676
Nicolas Capensa9b49372015-01-30 00:33:26 -05005677void APIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
Nicolas Capens264f1522015-01-09 17:21:17 -05005678{
Nicolas Capens264f1522015-01-09 17:21:17 -05005679 UNIMPLEMENTED();
5680}
5681
Nicolas Capensa9b49372015-01-30 00:33:26 -05005682void APIENTRY glCallList(GLuint list)
Nicolas Capens264f1522015-01-09 17:21:17 -05005683{
Nicolas Capensa9b49372015-01-30 00:33:26 -05005684 TRACE("(GLuint list = %d)", list);
5685
5686 if(list == 0)
5687 {
5688 return error(GL_INVALID_VALUE);
5689 }
5690
5691 gl::Context *context = gl::getContext();
5692
5693 if(context)
5694 {
5695 if(context->getListIndex() != 0)
5696 {
5697 UNIMPLEMENTED();
5698 }
5699
5700 context->callList(list);
5701 }
5702}
5703
5704void APIENTRY glCallLists(GLsizei n, GLenum type, const GLvoid *lists)
5705{
5706 TRACE("(GLsizei n = %d, GLenum type = 0x%X, const GLvoid *lists)", n, type);
5707
5708 gl::Context *context = gl::getContext();
5709
5710 if(context)
5711 {
5712 if(context->getListIndex() != 0)
5713 {
5714 UNIMPLEMENTED();
5715 }
5716
5717 for(int i = 0; i < n; i++)
5718 {
5719 switch(type)
5720 {
5721 case GL_UNSIGNED_INT: context->callList(((unsigned int*)lists)[i]); break;
5722 default:
5723 UNIMPLEMENTED();
5724 UNREACHABLE();
5725 }
5726 }
5727 }
5728}
5729
5730void APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
5731{
5732 UNIMPLEMENTED();
5733}
5734
5735void APIENTRY glClearDepth(GLclampd depth)
5736{
5737 TRACE("(GLclampd depth = %d)", depth);
5738
5739 glClearDepthf((float)depth); // FIXME
5740}
5741
5742void APIENTRY glClearIndex(GLfloat c)
5743{
5744 UNIMPLEMENTED();
5745}
5746
5747void APIENTRY glClipPlane(GLenum plane, const GLdouble *equation)
5748{
5749 UNIMPLEMENTED();
5750}
5751
5752void APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue)
5753{
5754 UNIMPLEMENTED();
5755}
5756
5757void APIENTRY glColor3bv(const GLbyte *v)
5758{
5759 UNIMPLEMENTED();
5760}
5761
5762void APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue)
5763{
5764 UNIMPLEMENTED();
5765}
5766
5767void APIENTRY glColor3dv(const GLdouble *v)
5768{
5769 UNIMPLEMENTED();
5770}
5771
5772void APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue)
5773{
5774 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f)", red, green, blue);
5775
5776 gl::Context *context = gl::getContext();
5777
5778 if(context)
5779 {
5780 if(context->getListIndex() != 0)
5781 {
5782 UNIMPLEMENTED();
5783 }
5784
5785 //context->color(red, green, blue, 1.0f);
5786 //GLfloat vals[4] = {};
5787 context->setVertexAttrib(sw::Color0, red, green, blue, 1);
5788 }
5789}
5790
5791void APIENTRY glColor3fv(const GLfloat *v)
5792{
5793 UNIMPLEMENTED();
5794}
5795
5796void APIENTRY glColor3i(GLint red, GLint green, GLint blue)
5797{
5798 UNIMPLEMENTED();
5799}
5800
5801void APIENTRY glColor3iv(const GLint *v)
5802{
5803 UNIMPLEMENTED();
5804}
5805
5806void APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue)
5807{
5808 UNIMPLEMENTED();
5809}
5810
5811void APIENTRY glColor3sv(const GLshort *v)
5812{
5813 UNIMPLEMENTED();
5814}
5815
5816void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue)
5817{
5818 UNIMPLEMENTED();
5819}
5820
5821void APIENTRY glColor3ubv(const GLubyte *v)
5822{
5823 UNIMPLEMENTED();
5824}
5825
5826void APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue)
5827{
5828 UNIMPLEMENTED();
5829}
5830
5831void APIENTRY glColor3uiv(const GLuint *v)
5832{
5833 UNIMPLEMENTED();
5834}
5835
5836void APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue)
5837{
5838 UNIMPLEMENTED();
5839}
5840
5841void APIENTRY glColor3usv(const GLushort *v)
5842{
5843 UNIMPLEMENTED();
5844}
5845
5846void APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
5847{
5848 UNIMPLEMENTED();
5849}
5850
5851void APIENTRY glColor4bv(const GLbyte *v)
5852{
5853 UNIMPLEMENTED();
5854}
5855
5856void APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
5857{
5858 UNIMPLEMENTED();
5859}
5860
5861void APIENTRY glColor4dv(const GLdouble *v)
5862{
5863 UNIMPLEMENTED();
5864}
5865
5866void APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
5867{
5868 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);
5869
5870 gl::Context *context = gl::getContext();
5871
5872 if(context)
5873 {
5874 if(context->getListIndex() != 0)
5875 {
5876 UNIMPLEMENTED();
5877 }
5878
5879 //context->color(red, green, blue, alpha);
5880 //GLfloat vals[4] = {red, green, blue, alpha};
5881 context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
5882 }
5883}
5884
5885void APIENTRY glColor4fv(const GLfloat *v)
5886{
5887 UNIMPLEMENTED();
5888}
5889
5890void APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha)
5891{
5892 UNIMPLEMENTED();
5893}
5894
5895void APIENTRY glColor4iv(const GLint *v)
5896{
5897 UNIMPLEMENTED();
5898}
5899
5900void APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
5901{
5902 UNIMPLEMENTED();
5903}
5904
5905void APIENTRY glColor4sv(const GLshort *v)
5906{
5907 UNIMPLEMENTED();
5908}
5909
5910void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
5911{
5912 UNIMPLEMENTED();
5913}
5914
5915void APIENTRY glColor4ubv(const GLubyte *v)
5916{
5917 UNIMPLEMENTED();
5918}
5919
5920void APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
5921{
5922 UNIMPLEMENTED();
5923}
5924
5925void APIENTRY glColor4uiv(const GLuint *v)
5926{
5927 UNIMPLEMENTED();
5928}
5929
5930void APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
5931{
5932 UNIMPLEMENTED();
5933}
5934
5935void APIENTRY glColor4usv(const GLushort *v)
5936{
5937 UNIMPLEMENTED();
5938}
5939
5940void APIENTRY glColorMaterial(GLenum face, GLenum mode)
5941{
5942 TRACE("(GLenum face = 0x%X, GLenum mode = 0x%X)", face, mode);
5943
5944 // FIXME: Validate enums
5945
5946 gl::Context *context = gl::getContext();
5947
5948 if(context)
5949 {
5950 if(context->getListIndex() != 0)
5951 {
5952 UNIMPLEMENTED();
5953 }
5954
5955 switch(face)
5956 {
5957 case GL_FRONT:
5958 context->setColorMaterialMode(mode); // FIXME: Front only
5959 break;
5960 case GL_FRONT_AND_BACK:
5961 context->setColorMaterialMode(mode);
5962 break;
5963 default:
5964 UNIMPLEMENTED();
5965 return error(GL_INVALID_ENUM);
5966 }
5967 }
5968}
5969
5970void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
5971{
5972 TRACE("(*)");
5973
5974 glVertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
5975}
5976
5977void APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
5978{
5979 UNIMPLEMENTED();
5980}
5981
5982void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)
5983{
5984 UNIMPLEMENTED();
5985}
5986
5987void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
5988{
5989 UNIMPLEMENTED();
5990}
5991
5992void APIENTRY glDebugEntry()
5993{
5994 UNIMPLEMENTED();
5995}
5996
5997void APIENTRY glDeleteLists(GLuint list, GLsizei range)
5998{
5999 TRACE("(GLuint list = %d, GLsizei range = %d)", list, range);
6000
6001 if(range < 0)
6002 {
6003 return error(GL_INVALID_VALUE);
6004 }
6005
6006 gl::Context *context = gl::getContext();
6007
6008 if(context)
6009 {
Alexis Hetuf7be67f2015-02-11 16:11:07 -05006010 for(GLuint i = list; i < list + range; i++)
Nicolas Capensa9b49372015-01-30 00:33:26 -05006011 {
6012 context->deleteList(i);
6013 }
6014 }
6015}
6016
6017void APIENTRY glDepthRange(GLclampd zNear, GLclampd zFar)
6018{
6019 UNIMPLEMENTED();
6020}
6021
6022void APIENTRY glDisableClientState(GLenum array)
6023{
6024 TRACE("(GLenum array = 0x%X)", array);
6025
6026 gl::Context *context = gl::getContext();
6027
6028 if(context)
6029 {
6030 GLenum texture = context->getClientActiveTexture();
6031
6032 switch(array)
6033 {
6034 case GL_VERTEX_ARRAY: context->setEnableVertexAttribArray(sw::Position, false); break;
6035 case GL_COLOR_ARRAY: context->setEnableVertexAttribArray(sw::Color0, false); break;
6036 case GL_TEXTURE_COORD_ARRAY: context->setEnableVertexAttribArray(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
6037 case GL_NORMAL_ARRAY: context->setEnableVertexAttribArray(sw::Normal, false); break;
6038 default: UNIMPLEMENTED();
6039 }
6040 }
6041}
6042
6043void APIENTRY glDrawBuffer(GLenum mode)
6044{
6045 UNIMPLEMENTED();
6046}
6047
6048void APIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
6049{
6050 UNIMPLEMENTED();
6051}
6052
6053void APIENTRY glEdgeFlag(GLboolean flag)
6054{
6055 UNIMPLEMENTED();
6056}
6057
6058void APIENTRY glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)
6059{
6060 UNIMPLEMENTED();
6061}
6062
6063void APIENTRY glEdgeFlagv(const GLboolean *flag)
6064{
6065 UNIMPLEMENTED();
6066}
6067
6068void APIENTRY glEnableClientState(GLenum array)
6069{
6070 TRACE("(GLenum array = 0x%X)", array);
6071
6072 gl::Context *context = gl::getContext();
6073
6074 if(context)
6075 {
6076 GLenum texture = context->getClientActiveTexture();
6077
6078 switch(array)
6079 {
6080 case GL_VERTEX_ARRAY: context->setEnableVertexAttribArray(sw::Position, true); break;
6081 case GL_COLOR_ARRAY: context->setEnableVertexAttribArray(sw::Color0, true); break;
6082 case GL_TEXTURE_COORD_ARRAY: context->setEnableVertexAttribArray(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
6083 case GL_NORMAL_ARRAY: context->setEnableVertexAttribArray(sw::Normal, true); break;
6084 default: UNIMPLEMENTED();
6085 }
6086 }
6087}
6088
6089void APIENTRY glEnd()
6090{
6091 TRACE("()");
6092
6093 gl::Context *context = gl::getContext();
6094
6095 if(context)
6096 {
6097 if(context->getListIndex() != 0)
6098 {
6099 UNIMPLEMENTED();
6100 }
6101
6102 context->end();
6103 }
6104}
6105
6106void APIENTRY glEndList()
6107{
6108 TRACE("()");
6109
6110 gl::Context *context = gl::getContext();
6111
6112 if(context)
6113 {
6114 context->endList();
6115 }
6116}
6117
6118void APIENTRY glEvalCoord1d(GLdouble u)
6119{
6120 UNIMPLEMENTED();
6121}
6122
6123void APIENTRY glEvalCoord1dv(const GLdouble *u)
6124{
6125 UNIMPLEMENTED();
6126}
6127
6128void APIENTRY glEvalCoord1f(GLfloat u)
6129{
6130 UNIMPLEMENTED();
6131}
6132
6133void APIENTRY glEvalCoord1fv(const GLfloat *u)
6134{
6135 UNIMPLEMENTED();
6136}
6137
6138void APIENTRY glEvalCoord2d(GLdouble u, GLdouble v)
6139{
6140 UNIMPLEMENTED();
6141}
6142
6143void APIENTRY glEvalCoord2dv(const GLdouble *u)
6144{
6145 UNIMPLEMENTED();
6146}
6147
6148void APIENTRY glEvalCoord2f(GLfloat u, GLfloat v)
6149{
6150 UNIMPLEMENTED();
6151}
6152
6153void APIENTRY glEvalCoord2fv(const GLfloat *u)
6154{
6155 UNIMPLEMENTED();
6156}
6157
6158void APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2)
6159{
6160 UNIMPLEMENTED();
6161}
6162
6163void APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
6164{
6165 UNIMPLEMENTED();
6166}
6167
6168void APIENTRY glEvalPoint1(GLint i)
6169{
6170 UNIMPLEMENTED();
6171}
6172
6173void APIENTRY glEvalPoint2(GLint i, GLint j)
6174{
6175 UNIMPLEMENTED();
6176}
6177
6178void APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
6179{
6180 UNIMPLEMENTED();
6181}
6182
6183void APIENTRY glFogf(GLenum pname, GLfloat param)
6184{
6185 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
6186
6187 gl::Context *context = gl::getContext();
6188
6189 if(context)
6190 {
6191 if(context->getListIndex() != 0)
6192 {
6193 UNIMPLEMENTED();
6194 }
6195
6196 gl::Device *device = gl::getDevice(); // FIXME
6197
6198 switch(pname)
6199 {
6200 case GL_FOG_START: device->setFogStart(param); break;
6201 case GL_FOG_END: device->setFogEnd(param); break;
6202 default:
6203 UNIMPLEMENTED();
6204 return error(GL_INVALID_ENUM);
6205 }
6206 }
6207}
6208
6209void APIENTRY glFogfv(GLenum pname, const GLfloat *params)
6210{
6211 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
6212
6213 gl::Context *context = gl::getContext();
6214
6215 if(context)
6216 {
6217 if(context->getListIndex() != 0)
6218 {
6219 UNIMPLEMENTED();
6220 }
6221
6222 switch(pname)
6223 {
6224 case GL_FOG_COLOR:
6225 {
6226 gl::Device *device = gl::getDevice(); // FIXME
6227 device->setFogColor(sw::Color<float>(params[0], params[1], params[2], params[3]));
6228 }
6229 break;
6230 default:
6231 UNIMPLEMENTED();
6232 return error(GL_INVALID_ENUM);
6233 }
6234 }
6235}
6236
6237void APIENTRY glFogi(GLenum pname, GLint param)
6238{
6239 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
6240
6241 gl::Context *context = gl::getContext();
6242
6243 if(context)
6244 {
6245 if(context->getListIndex() != 0)
6246 {
6247 UNIMPLEMENTED();
6248 }
6249
6250 switch(pname)
6251 {
6252 case GL_FOG_MODE:
6253 {
6254 gl::Device *device = gl::getDevice(); // FIXME
6255 switch(param)
6256 {
6257 case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
6258 default:
6259 UNIMPLEMENTED();
6260 return error(GL_INVALID_ENUM);
6261 }
6262 }
6263 break;
6264 default:
6265 UNIMPLEMENTED();
6266 return error(GL_INVALID_ENUM);
6267 }
6268 }
6269}
6270
6271void APIENTRY glFogiv(GLenum pname, const GLint *params)
6272{
6273 UNIMPLEMENTED();
6274}
6275
6276void APIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
6277{
Nicolas Capens74626012015-03-11 21:49:44 -04006278 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 -05006279
6280 gl::Context *context = gl::getContext();
6281
6282 if(context)
6283 {
6284 if(context->getListIndex() != 0)
6285 {
6286 UNIMPLEMENTED();
6287 }
6288
6289 context->frustum(left, right, bottom, top, zNear, zFar);
6290 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05006291}
6292
6293GLuint APIENTRY glGenLists(GLsizei range)
6294{
6295 TRACE("(GLsizei range = %d)", range);
6296
6297 if(range < 0)
6298 {
6299 return error(GL_INVALID_VALUE, 0);
6300 }
6301
6302 gl::Context *context = gl::getContext();
6303
6304 if(context)
6305 {
6306 return context->genLists(range);
6307 }
6308
6309 return 0;
6310}
6311
6312void APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation)
6313{
6314 UNIMPLEMENTED();
6315}
6316
6317void APIENTRY glGetDoublev(GLenum pname, GLdouble *params)
6318{
6319 UNIMPLEMENTED();
6320}
6321
6322void APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
6323{
6324 UNIMPLEMENTED();
6325}
6326
6327void APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params)
6328{
6329 UNIMPLEMENTED();
6330}
6331
6332void APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v)
6333{
6334 UNIMPLEMENTED();
6335}
6336
6337void APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v)
6338{
6339 UNIMPLEMENTED();
6340}
6341
6342void APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v)
6343{
6344 UNIMPLEMENTED();
6345}
6346
6347void APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
6348{
6349 UNIMPLEMENTED();
6350}
6351
6352void APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params)
6353{
6354 UNIMPLEMENTED();
6355}
6356
6357void APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values)
6358{
6359 UNIMPLEMENTED();
6360}
6361
6362void APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values)
6363{
6364 UNIMPLEMENTED();
6365}
6366
6367void APIENTRY glGetPixelMapusv(GLenum map, GLushort *values)
6368{
6369 UNIMPLEMENTED();
6370}
6371
6372void APIENTRY glGetPointerv(GLenum pname, GLvoid* *params)
6373{
6374 UNIMPLEMENTED();
6375}
6376
6377void APIENTRY glGetPolygonStipple(GLubyte *mask)
6378{
6379 UNIMPLEMENTED();
6380}
6381
6382void APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
6383{
6384 UNIMPLEMENTED();
6385}
6386
6387void APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params)
6388{
6389 UNIMPLEMENTED();
6390}
6391
6392void APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
6393{
6394 UNIMPLEMENTED();
6395}
6396
6397void APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
6398{
6399 UNIMPLEMENTED();
6400}
6401
6402void APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
6403{
6404 UNIMPLEMENTED();
6405}
6406
6407void APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
6408{
Nicolas Capens4be33702015-04-28 15:13:30 -07006409 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 -05006410
6411 gl::Context *context = gl::getContext();
6412
6413 if(context)
6414 {
6415 gl::Texture *texture;
6416
6417 switch(target)
6418 {
6419 case GL_TEXTURE_2D:
6420 texture = context->getTexture2D(target);
6421 break;
6422 case GL_TEXTURE_CUBE_MAP:
6423 texture = context->getTextureCubeMap();
6424 break;
6425 default:
6426 UNIMPLEMENTED();
6427 return error(GL_INVALID_ENUM);
6428 }
6429
6430 if(format == texture->getFormat(target, level) && type == texture->getType(target, level))
6431 {
6432 gl::Image *image = texture->getRenderTarget(target, level);
6433 void *source = image->lock(0, 0, sw::LOCK_READONLY);
6434 memcpy(pixels, source, image->getPitch() * image->getHeight());
6435 image->unlock();
6436 }
6437 else
6438 {
6439 UNIMPLEMENTED();
6440 }
6441 }
6442}
6443
6444void APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
6445{
6446 UNIMPLEMENTED();
6447}
6448
6449void APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
6450{
Nicolas Capens4be33702015-04-28 15:13:30 -07006451 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 -05006452
6453 gl::Context *context = gl::getContext();
6454
6455 if(context)
6456 {
6457 gl::Texture *texture;
6458
6459 switch(target)
6460 {
6461 case GL_TEXTURE_2D:
6462 case GL_PROXY_TEXTURE_2D:
6463 texture = context->getTexture2D(target);
6464 break;
6465 case GL_TEXTURE_CUBE_MAP:
6466 texture = context->getTextureCubeMap();
6467 break;
6468 default:
6469 UNIMPLEMENTED();
6470 return error(GL_INVALID_ENUM);
6471 }
6472
6473 switch(pname)
6474 {
6475 case GL_TEXTURE_MAG_FILTER:
6476 *params = texture->getMagFilter();
6477 break;
6478 case GL_TEXTURE_MIN_FILTER:
6479 *params = texture->getMinFilter();
6480 break;
6481 case GL_TEXTURE_WRAP_S:
6482 *params = texture->getWrapS();
6483 break;
6484 case GL_TEXTURE_WRAP_T:
6485 *params = texture->getWrapT();
6486 break;
6487 case GL_TEXTURE_WIDTH:
6488 *params = texture->getWidth(target, level);
6489 break;
6490 case GL_TEXTURE_HEIGHT:
6491 *params = texture->getHeight(target, level);
6492 break;
6493 case GL_TEXTURE_INTERNAL_FORMAT:
6494 *params = texture->getInternalFormat(target, level);
6495 break;
6496 case GL_TEXTURE_BORDER_COLOR:
6497 UNIMPLEMENTED();
6498 break;
6499 case GL_TEXTURE_BORDER:
6500 UNIMPLEMENTED();
6501 break;
6502 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6503 *params = (GLint)texture->getMaxAnisotropy();
6504 break;
6505 default:
6506 return error(GL_INVALID_ENUM);
6507 }
6508 }
6509}
6510
6511void APIENTRY glIndexMask(GLuint mask)
6512{
6513 UNIMPLEMENTED();
6514}
6515
6516void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
6517{
6518 UNIMPLEMENTED();
6519}
6520
6521void APIENTRY glIndexd(GLdouble c)
6522{
6523 UNIMPLEMENTED();
6524}
6525
6526void APIENTRY glIndexdv(const GLdouble *c)
6527{
6528 UNIMPLEMENTED();
6529}
6530
6531void APIENTRY glIndexf(GLfloat c)
6532{
6533 UNIMPLEMENTED();
6534}
6535
6536void APIENTRY glIndexfv(const GLfloat *c)
6537{
6538 UNIMPLEMENTED();
6539}
6540
6541void APIENTRY glIndexi(GLint c)
6542{
6543 UNIMPLEMENTED();
6544}
6545
6546void APIENTRY glIndexiv(const GLint *c)
6547{
6548 UNIMPLEMENTED();
6549}
6550
6551void APIENTRY glIndexs(GLshort c)
6552{
6553 UNIMPLEMENTED();
6554}
6555
6556void APIENTRY glIndexsv(const GLshort *c)
6557{
6558 UNIMPLEMENTED();
6559}
6560
6561void APIENTRY glIndexub(GLubyte c)
6562{
6563 UNIMPLEMENTED();
6564}
6565
6566void APIENTRY glIndexubv(const GLubyte *c)
6567{
6568 UNIMPLEMENTED();
6569}
6570
6571void APIENTRY glInitNames(void)
6572{
6573 UNIMPLEMENTED();
6574}
6575
6576void APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
6577{
6578 UNIMPLEMENTED();
6579}
6580
6581GLboolean APIENTRY glIsList(GLuint list)
6582{
6583 UNIMPLEMENTED();
6584 return GL_FALSE;
6585}
6586
6587void APIENTRY glLightModelf(GLenum pname, GLfloat param)
6588{
6589 UNIMPLEMENTED();
6590}
6591
6592void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
6593{
6594 TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
6595
6596 gl::Context *context = gl::getContext();
6597
6598 if(context)
6599 {
6600 if(context->getListIndex() != 0)
6601 {
6602 UNIMPLEMENTED();
6603 }
6604
6605 gl::Device *device = gl::getDevice(); // FIXME
6606
6607 switch(pname)
6608 {
6609 case GL_LIGHT_MODEL_AMBIENT:
6610 device->setGlobalAmbient(sw::Color<float>(params[0], params[1], params[2], params[3]));
6611 break;
6612 default:
6613 UNIMPLEMENTED();
6614 return error(GL_INVALID_ENUM);
6615 }
6616 }
6617}
6618
6619void APIENTRY glLightModeli(GLenum pname, GLint param)
6620{
6621 UNIMPLEMENTED();
6622}
6623
6624void APIENTRY glLightModeliv(GLenum pname, const GLint *params)
6625{
6626 TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
6627 UNIMPLEMENTED();
6628}
6629
6630void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
6631{
6632 UNIMPLEMENTED();
6633}
6634
6635void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
6636{
6637 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
6638
6639 gl::Context *context = gl::getContext();
6640
6641 if(context)
6642 {
6643 if(context->getListIndex() != 0)
6644 {
6645 UNIMPLEMENTED();
6646 }
6647
6648 gl::Device *device = gl::getDevice(); // FIXME
6649
6650 switch(pname)
6651 {
6652 case GL_AMBIENT: device->setLightAmbient(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6653 case GL_DIFFUSE: device->setLightDiffuse(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6654 case GL_SPECULAR: device->setLightSpecular(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6655 case GL_POSITION:
6656 if(params[3] == 0.0f) // Directional light
6657 {
6658 // Create a very far out point light
6659 float max = std::max(std::max(abs(params[0]), abs(params[1])), abs(params[2]));
6660 device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / max * 1e10f, params[1] / max * 1e10f, params[2] / max * 1e10f));
6661 }
6662 else
6663 {
6664 device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / params[3], params[1] / params[3], params[2] / params[3]));
6665 }
6666 break;
6667 default:
6668 UNIMPLEMENTED();
6669 return error(GL_INVALID_ENUM);
6670 }
6671 }
6672}
6673
6674void APIENTRY glLighti(GLenum light, GLenum pname, GLint param)
6675{
6676 UNIMPLEMENTED();
6677}
6678
6679void APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params)
6680{
6681 UNIMPLEMENTED();
6682}
6683
6684void APIENTRY glLineStipple(GLint factor, GLushort pattern)
6685{
6686 UNIMPLEMENTED();
6687}
6688
6689void APIENTRY glListBase(GLuint base)
6690{
6691 UNIMPLEMENTED();
6692}
6693
6694void APIENTRY glLoadIdentity()
6695{
6696 TRACE("()");
6697
6698 gl::Context *context = gl::getContext();
6699
6700 if(context)
6701 {
6702 if(context->getListIndex() != 0)
6703 {
6704 UNIMPLEMENTED();
6705 }
6706
6707 context->loadIdentity();
6708 }
6709}
6710
6711void APIENTRY glLoadMatrixd(const GLdouble *m)
6712{
6713 UNIMPLEMENTED();
6714}
6715
6716void APIENTRY glLoadMatrixf(const GLfloat *m)
6717{
6718 UNIMPLEMENTED();
6719}
6720
6721void APIENTRY glLoadName(GLuint name)
6722{
6723 UNIMPLEMENTED();
6724}
6725
6726void APIENTRY glLogicOp(GLenum opcode)
6727{
6728 UNIMPLEMENTED();
6729}
6730
6731void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
6732{
6733 UNIMPLEMENTED();
6734}
6735
6736void APIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
6737{
6738 UNIMPLEMENTED();
6739}
6740
6741void APIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)
6742{
6743 UNIMPLEMENTED();
6744}
6745
6746void APIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)
6747{
6748 UNIMPLEMENTED();
6749}
6750
6751void APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
6752{
6753 UNIMPLEMENTED();
6754}
6755
6756void APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
6757{
6758 UNIMPLEMENTED();
6759}
6760
6761void APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
6762{
6763 UNIMPLEMENTED();
6764}
6765
6766void APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
6767{
6768 UNIMPLEMENTED();
6769}
6770
6771void APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
6772{
6773 UNIMPLEMENTED();
6774}
6775
6776void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
6777{
6778 UNIMPLEMENTED();
6779}
6780
6781void APIENTRY glMateriali(GLenum face, GLenum pname, GLint param)
6782{
6783 UNIMPLEMENTED();
6784}
6785
6786void APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params)
6787{
6788 UNIMPLEMENTED();
6789}
6790
6791void APIENTRY glMatrixMode(GLenum mode)
6792{
6793 TRACE("(*)");
6794
6795 gl::Context *context = gl::getContext();
6796
6797 if(context)
6798 {
6799 if(context->getListIndex() != 0)
6800 {
6801 UNIMPLEMENTED();
6802 }
6803
6804 context->setMatrixMode(mode);
6805 }
6806}
6807
6808void APIENTRY glMultMatrixd(const GLdouble *m)
6809{
Maxime Gregoire53ff8d82015-03-04 14:51:58 -05006810 TRACE("(*)");
6811
6812 gl::Context *context = gl::getContext();
6813
6814 if(context)
6815 {
6816 if(context->getListIndex() != 0)
6817 {
6818 UNIMPLEMENTED();
6819 }
6820
6821 context->multiply(m);
6822 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05006823}
6824
6825void APIENTRY glMultMatrixm(sw::Matrix m)
6826{
6827 gl::Context *context = gl::getContext();
6828
6829 if(context)
6830 {
6831 context->multiply((GLfloat*)m.m);
6832 }
6833}
6834
6835void APIENTRY glMultMatrixf(const GLfloat *m)
6836{
6837 TRACE("(*)");
6838
6839 gl::Context *context = gl::getContext();
6840
6841 if(context)
6842 {
6843 if(context->getListIndex() != 0)
6844 {
6845 return context->listCommand(gl::newCommand(glMultMatrixm, sw::Matrix(m)));
6846 }
6847
6848 context->multiply(m);
6849 }
6850}
6851
6852void APIENTRY glNewList(GLuint list, GLenum mode)
6853{
6854 TRACE("(GLuint list = %d, GLenum mode = 0x%X)", list, mode);
6855
6856 if(list == 0)
6857 {
6858 return error(GL_INVALID_VALUE);
6859 }
6860
6861 switch(mode)
6862 {
6863 case GL_COMPILE:
6864 case GL_COMPILE_AND_EXECUTE:
6865 break;
6866 default:
6867 return error(GL_INVALID_ENUM);
6868 }
6869
6870 gl::Context *context = gl::getContext();
6871
6872 if(context)
6873 {
6874 if(context->getListIndex() != 0)
6875 {
6876 UNIMPLEMENTED();
6877 }
6878
6879 context->newList(list, mode);
6880 }
6881}
6882
6883void APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
6884{
6885 UNIMPLEMENTED();
6886}
6887
6888void APIENTRY glNormal3bv(const GLbyte *v)
6889{
6890 UNIMPLEMENTED();
6891}
6892
6893void APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
6894{
6895 UNIMPLEMENTED();
6896}
6897
6898void APIENTRY glNormal3dv(const GLdouble *v)
6899{
6900 UNIMPLEMENTED();
6901}
6902
6903void APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
6904{
6905 TRACE("(GLfloat nx = %f, GLfloat ny = %f, GLfloat nz = %f)", nx, ny, nz);
6906
6907 gl::Context *context = gl::getContext();
6908
6909 if(context)
6910 {
6911 if(context->getListIndex() != 0)
6912 {
6913 UNIMPLEMENTED();
6914 }
6915
6916 //context->normal(nx, ny, nz);
6917 context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
6918 }
6919}
6920
6921void APIENTRY glNormal3fv(const GLfloat *v)
6922{
6923 UNIMPLEMENTED();
6924}
6925
6926void APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz)
6927{
6928 UNIMPLEMENTED();
6929}
6930
6931void APIENTRY glNormal3iv(const GLint *v)
6932{
6933 UNIMPLEMENTED();
6934}
6935
6936void APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz)
6937{
6938 UNIMPLEMENTED();
6939}
6940
6941void APIENTRY glNormal3sv(const GLshort *v)
6942{
6943 UNIMPLEMENTED();
6944}
6945
6946void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
6947{
6948 TRACE("(*)");
6949
Nicolas Capensa3fac8b2015-05-25 15:57:03 -04006950 glVertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);
Nicolas Capensa9b49372015-01-30 00:33:26 -05006951}
6952
6953void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
6954{
6955 TRACE("(*)");
6956
6957 gl::Context *context = gl::getContext();
6958
6959 if(context)
6960 {
6961 if(context->getListIndex() != 0)
6962 {
6963 UNIMPLEMENTED();
6964 }
6965
6966 context->ortho(left, right, bottom, top, zNear, zFar);
6967 }
6968}
6969
6970void APIENTRY glPassThrough(GLfloat token)
6971{
6972 UNIMPLEMENTED();
6973}
6974
6975void APIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)
6976{
6977 UNIMPLEMENTED();
6978}
6979
6980void APIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)
6981{
6982 UNIMPLEMENTED();
6983}
6984
6985void APIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)
6986{
6987 UNIMPLEMENTED();
6988}
6989
6990void APIENTRY glPixelStoref(GLenum pname, GLfloat param)
6991{
6992 UNIMPLEMENTED();
6993}
6994
6995void APIENTRY glPixelTransferf(GLenum pname, GLfloat param)
6996{
6997 UNIMPLEMENTED();
6998}
6999
7000void APIENTRY glPixelTransferi(GLenum pname, GLint param)
7001{
7002 UNIMPLEMENTED();
7003}
7004
7005void APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
7006{
7007 UNIMPLEMENTED();
7008}
7009
7010void APIENTRY glPointSize(GLfloat size)
7011{
7012 UNIMPLEMENTED();
7013}
7014
7015void APIENTRY glPolygonMode(GLenum face, GLenum mode)
7016{
7017 UNIMPLEMENTED();
7018}
7019
7020void APIENTRY glPolygonStipple(const GLubyte *mask)
7021{
7022 UNIMPLEMENTED();
7023}
7024
7025void APIENTRY glPopAttrib(void)
7026{
7027 UNIMPLEMENTED();
7028}
7029
7030void APIENTRY glPopClientAttrib(void)
7031{
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007032 UNIMPLEMENTED();
Nicolas Capensa9b49372015-01-30 00:33:26 -05007033}
7034
7035void APIENTRY glPopMatrix(void)
7036{
7037 TRACE("()");
7038
7039 gl::Context *context = gl::getContext();
7040
7041 if(context)
7042 {
7043 if(context->getListIndex() != 0)
7044 {
7045 return context->listCommand(gl::newCommand(glPopMatrix));
7046 }
7047
7048 context->popMatrix();
7049 }
7050}
7051
7052void APIENTRY glPopName(void)
7053{
7054 UNIMPLEMENTED();
7055}
7056
7057void APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities)
7058{
7059 UNIMPLEMENTED();
7060}
7061
7062void APIENTRY glPushAttrib(GLbitfield mask)
7063{
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007064 UNIMPLEMENTED();
Nicolas Capensa9b49372015-01-30 00:33:26 -05007065}
7066
7067void APIENTRY glPushClientAttrib(GLbitfield mask)
7068{
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007069 UNIMPLEMENTED();
Nicolas Capensa9b49372015-01-30 00:33:26 -05007070}
7071
7072void APIENTRY glPushMatrix(void)
7073{
7074 TRACE("()");
7075
7076 gl::Context *context = gl::getContext();
7077
7078 if(context)
7079 {
7080 if(context->getListIndex() != 0)
7081 {
7082 return context->listCommand(gl::newCommand(glPushMatrix));
7083 }
7084
7085 context->pushMatrix();
7086 }
7087}
7088
7089void APIENTRY glPushName(GLuint name)
7090{
7091 UNIMPLEMENTED();
7092}
7093
7094void APIENTRY glRasterPos2d(GLdouble x, GLdouble y)
7095{
7096 UNIMPLEMENTED();
7097}
7098
7099void APIENTRY glRasterPos2dv(const GLdouble *v)
7100{
7101 UNIMPLEMENTED();
7102}
7103
7104void APIENTRY glRasterPos2f(GLfloat x, GLfloat y)
7105{
7106 UNIMPLEMENTED();
7107}
7108
7109void APIENTRY glRasterPos2fv(const GLfloat *v)
7110{
7111 UNIMPLEMENTED();
7112}
7113
7114void APIENTRY glRasterPos2i(GLint x, GLint y)
7115{
7116 UNIMPLEMENTED();
7117}
7118
7119void APIENTRY glRasterPos2iv(const GLint *v)
7120{
7121 UNIMPLEMENTED();
7122}
7123
7124void APIENTRY glRasterPos2s(GLshort x, GLshort y)
7125{
7126 UNIMPLEMENTED();
7127}
7128
7129void APIENTRY glRasterPos2sv(const GLshort *v)
7130{
7131 UNIMPLEMENTED();
7132}
7133
7134void APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
7135{
7136 UNIMPLEMENTED();
7137}
7138
7139void APIENTRY glRasterPos3dv(const GLdouble *v)
7140{
7141 UNIMPLEMENTED();
7142}
7143
7144void APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
7145{
7146 UNIMPLEMENTED();
7147}
7148
7149void APIENTRY glRasterPos3fv(const GLfloat *v)
7150{
7151 UNIMPLEMENTED();
7152}
7153
7154void APIENTRY glRasterPos3i(GLint x, GLint y, GLint z)
7155{
7156 UNIMPLEMENTED();
7157}
7158
7159void APIENTRY glRasterPos3iv(const GLint *v)
7160{
7161 UNIMPLEMENTED();
7162}
7163
7164void APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z)
7165{
7166 UNIMPLEMENTED();
7167}
7168
7169void APIENTRY glRasterPos3sv(const GLshort *v)
7170{
7171 UNIMPLEMENTED();
7172}
7173
7174void APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
7175{
7176 UNIMPLEMENTED();
7177}
7178
7179void APIENTRY glRasterPos4dv(const GLdouble *v)
7180{
7181 UNIMPLEMENTED();
7182}
7183
7184void APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
7185{
7186 UNIMPLEMENTED();
7187}
7188
7189void APIENTRY glRasterPos4fv(const GLfloat *v)
7190{
7191 UNIMPLEMENTED();
7192}
7193
7194void APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w)
7195{
7196 UNIMPLEMENTED();
7197}
7198
7199void APIENTRY glRasterPos4iv(const GLint *v)
7200{
7201 UNIMPLEMENTED();
7202}
7203
7204void APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
7205{
7206 UNIMPLEMENTED();
7207}
7208
7209void APIENTRY glRasterPos4sv(const GLshort *v)
7210{
7211 UNIMPLEMENTED();
7212}
7213
7214void APIENTRY glReadBuffer(GLenum mode)
7215{
7216 UNIMPLEMENTED();
7217}
7218
7219void APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
7220{
7221 UNIMPLEMENTED();
7222}
7223
7224void APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2)
7225{
7226 UNIMPLEMENTED();
7227}
7228
7229void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
7230{
7231 UNIMPLEMENTED();
7232}
7233
7234void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2)
7235{
7236 UNIMPLEMENTED();
7237}
7238
7239void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2)
7240{
7241 UNIMPLEMENTED();
7242}
7243
7244void APIENTRY glRectiv(const GLint *v1, const GLint *v2)
7245{
7246 UNIMPLEMENTED();
7247}
7248
7249void APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
7250{
7251 UNIMPLEMENTED();
7252}
7253
7254void APIENTRY glRectsv(const GLshort *v1, const GLshort *v2)
7255{
7256 UNIMPLEMENTED();
7257}
7258
7259GLint APIENTRY glRenderMode(GLenum mode)
7260{
7261 UNIMPLEMENTED();
7262 return 0;
7263}
7264
7265void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
7266{
7267 UNIMPLEMENTED();
7268}
7269
7270void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
7271{
7272 TRACE("(*)");
7273
7274 gl::Context *context = gl::getContext();
7275
7276 if(context)
7277 {
7278 if(context->getListIndex() != 0)
7279 {
7280 UNIMPLEMENTED();
7281 }
7282
7283 context->rotate(angle, x, y, z);
7284 }
7285}
7286
7287void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)
7288{
7289 UNIMPLEMENTED();
7290}
7291
7292void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
7293{
7294 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7295
7296 gl::Context *context = gl::getContext();
7297
7298 if(context)
7299 {
7300 if(context->getListIndex() != 0)
7301 {
7302 return context->listCommand(gl::newCommand(glScalef, x, y, z));
7303 }
7304
7305 context->scale(x, y, z);
7306 }
7307}
7308
7309void APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer)
7310{
7311 UNIMPLEMENTED();
7312}
7313
7314void APIENTRY glShadeModel(GLenum mode)
7315{
7316 TRACE("(*)");
7317
7318 gl::Context *context = gl::getContext();
7319
7320 if(context)
7321 {
7322 if(context->getListIndex() != 0)
7323 {
7324 UNIMPLEMENTED();
7325 }
7326
7327 context->setShadeModel(mode);
7328 }
7329}
7330
7331void APIENTRY glTexCoord1d(GLdouble s)
7332{
7333 UNIMPLEMENTED();
7334}
7335
7336void APIENTRY glTexCoord1dv(const GLdouble *v)
7337{
7338 UNIMPLEMENTED();
7339}
7340
7341void APIENTRY glTexCoord1f(GLfloat s)
7342{
7343 UNIMPLEMENTED();
7344}
7345
7346void APIENTRY glTexCoord1fv(const GLfloat *v)
7347{
7348 UNIMPLEMENTED();
7349}
7350
7351void APIENTRY glTexCoord1i(GLint s)
7352{
7353 UNIMPLEMENTED();
7354}
7355
7356void APIENTRY glTexCoord1iv(const GLint *v)
7357{
7358 UNIMPLEMENTED();
7359}
7360
7361void APIENTRY glTexCoord1s(GLshort s)
7362{
7363 UNIMPLEMENTED();
7364}
7365
7366void APIENTRY glTexCoord1sv(const GLshort *v)
7367{
7368 UNIMPLEMENTED();
7369}
7370
7371void APIENTRY glTexCoord2d(GLdouble s, GLdouble t)
7372{
7373 UNIMPLEMENTED();
7374}
7375
7376void APIENTRY glTexCoord2dv(const GLdouble *v)
7377{
7378 UNIMPLEMENTED();
7379}
7380
7381void APIENTRY glTexCoord2f(GLfloat s, GLfloat t)
7382{
7383 TRACE("(GLfloat s = %f, GLfloat t = %f)", s, t);
7384
7385 gl::Context *context = gl::getContext();
7386
7387 if(context)
7388 {
7389 if(context->getListIndex() != 0)
7390 {
7391 UNIMPLEMENTED();
7392 }
7393
7394 //context->texCoord(s, t, 0.0f, 1.0f);
7395 unsigned int texture = context->getActiveTexture();
7396 context->setVertexAttrib(sw::TexCoord0/* + texture*/, s, t, 0.0f, 1.0f);
7397 }
7398}
7399
7400void APIENTRY glTexCoord2fv(const GLfloat *v)
7401{
7402 UNIMPLEMENTED();
7403}
7404
7405void APIENTRY glTexCoord2i(GLint s, GLint t)
7406{
7407 UNIMPLEMENTED();
7408}
7409
7410void APIENTRY glTexCoord2iv(const GLint *v)
7411{
7412 UNIMPLEMENTED();
7413}
7414
7415void APIENTRY glTexCoord2s(GLshort s, GLshort t)
7416{
7417 UNIMPLEMENTED();
7418}
7419
7420void APIENTRY glTexCoord2sv(const GLshort *v)
7421{
7422 UNIMPLEMENTED();
7423}
7424
7425void APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
7426{
7427 UNIMPLEMENTED();
7428}
7429
7430void APIENTRY glTexCoord3dv(const GLdouble *v)
7431{
7432 UNIMPLEMENTED();
7433}
7434
7435void APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
7436{
7437 UNIMPLEMENTED();
7438}
7439
7440void APIENTRY glTexCoord3fv(const GLfloat *v)
7441{
7442 UNIMPLEMENTED();
7443}
7444
7445void APIENTRY glTexCoord3i(GLint s, GLint t, GLint r)
7446{
7447 UNIMPLEMENTED();
7448}
7449
7450void APIENTRY glTexCoord3iv(const GLint *v)
7451{
7452 UNIMPLEMENTED();
7453}
7454
7455void APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r)
7456{
7457 UNIMPLEMENTED();
7458}
7459
7460void APIENTRY glTexCoord3sv(const GLshort *v)
7461{
7462 UNIMPLEMENTED();
7463}
7464
7465void APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
7466{
7467 UNIMPLEMENTED();
7468}
7469
7470void APIENTRY glTexCoord4dv(const GLdouble *v)
7471{
7472 UNIMPLEMENTED();
7473}
7474
7475void APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
7476{
7477 UNIMPLEMENTED();
7478}
7479
7480void APIENTRY glTexCoord4fv(const GLfloat *v)
7481{
7482 UNIMPLEMENTED();
7483}
7484
7485void APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q)
7486{
7487 UNIMPLEMENTED();
7488}
7489
7490void APIENTRY glTexCoord4iv(const GLint *v)
7491{
7492 UNIMPLEMENTED();
7493}
7494
7495void APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
7496{
7497 UNIMPLEMENTED();
7498}
7499
7500void APIENTRY glTexCoord4sv(const GLshort *v)
7501{
7502 UNIMPLEMENTED();
7503}
7504
7505void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
7506{
7507 TRACE("(*)");
7508
7509 gl::Context *context = gl::getContext();
7510
7511 if(context)
7512 {
7513 GLenum texture = context->getClientActiveTexture();
7514
7515 glVertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
7516 }
7517}
7518
7519void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
7520{
7521 UNIMPLEMENTED();
7522}
7523
7524void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
7525{
7526 UNIMPLEMENTED();
7527}
7528
7529void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
7530{
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007531 UNIMPLEMENTED();
Nicolas Capensa9b49372015-01-30 00:33:26 -05007532}
7533
7534void APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
7535{
7536 UNIMPLEMENTED();
7537}
7538
7539void APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param)
7540{
7541 UNIMPLEMENTED();
7542}
7543
7544void APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
7545{
7546 UNIMPLEMENTED();
7547}
7548
7549void APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param)
7550{
7551 UNIMPLEMENTED();
7552}
7553
7554void APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
7555{
7556 UNIMPLEMENTED();
7557}
7558
7559void APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param)
7560{
7561 UNIMPLEMENTED();
7562}
7563
7564void APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params)
7565{
7566 UNIMPLEMENTED();
7567}
7568
7569void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
7570{
Maxime Grégoire5e582162015-07-16 12:52:57 -04007571 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "
7572 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)",
7573 target, level, internalformat, width, border, format, type, pixels);
7574
7575 glTexImage2D(target, level, internalformat, width, 1, border, format, type, pixels);
Nicolas Capensa9b49372015-01-30 00:33:26 -05007576}
7577
7578void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
7579{
Maxime Grégoire5e582162015-07-16 12:52:57 -04007580 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLsizei width = %d, "
7581 "GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)",
7582 target, level, xoffset, width, format, type, pixels);
7583
7584 glTexSubImage2D(target, level, xoffset, 0, width, 1, format, type, pixels);
Nicolas Capensa9b49372015-01-30 00:33:26 -05007585}
7586
7587void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)
7588{
7589 TRACE("(*)");
7590
7591 gl::Context *context = gl::getContext();
7592
7593 if(context)
7594 {
7595 if(context->getListIndex() != 0)
7596 {
7597 return context->listCommand(gl::newCommand(glTranslated, x, y, z));
7598 }
7599
7600 context->translate(x, y, z); // FIXME
7601 }
7602}
7603
7604void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
7605{
7606 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7607
7608 gl::Context *context = gl::getContext();
7609
7610 if(context)
7611 {
7612 if(context->getListIndex() != 0)
7613 {
7614 return context->listCommand(gl::newCommand(glTranslatef, x, y, z));
7615 }
7616
7617 context->translate(x, y, z);
7618 }
7619}
7620
7621void APIENTRY glVertex2d(GLdouble x, GLdouble y)
7622{
7623 UNIMPLEMENTED();
7624}
7625
7626void APIENTRY glVertex2dv(const GLdouble *v)
7627{
7628 UNIMPLEMENTED();
7629}
7630
7631void APIENTRY glVertex2f(GLfloat x, GLfloat y)
7632{
7633 UNIMPLEMENTED();
7634}
7635
7636void APIENTRY glVertex2fv(const GLfloat *v)
7637{
7638 UNIMPLEMENTED();
7639}
7640
7641void APIENTRY glVertex2i(GLint x, GLint y)
7642{
7643 UNIMPLEMENTED();
7644}
7645
7646void APIENTRY glVertex2iv(const GLint *v)
7647{
7648 UNIMPLEMENTED();
7649}
7650
7651void APIENTRY glVertex2s(GLshort x, GLshort y)
7652{
7653 UNIMPLEMENTED();
7654}
7655
7656void APIENTRY glVertex2sv(const GLshort *v)
7657{
7658 UNIMPLEMENTED();
7659}
7660
7661void APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
7662{
7663 UNIMPLEMENTED();
7664}
7665
7666void APIENTRY glVertex3dv(const GLdouble *v)
7667{
7668 UNIMPLEMENTED();
7669}
7670
7671void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
7672{
7673 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7674
7675 gl::Context *context = gl::getContext();
7676
7677 if(context)
7678 {
7679 if(context->getListIndex() != 0)
7680 {
7681 UNIMPLEMENTED();
7682 }
7683
7684 context->position(x, y, z, 1.0f);
7685 }
7686}
7687
7688void APIENTRY glVertex3fv(const GLfloat *v)
7689{
7690 UNIMPLEMENTED();
7691}
7692
7693void APIENTRY glVertex3i(GLint x, GLint y, GLint z)
7694{
7695 UNIMPLEMENTED();
7696}
7697
7698void APIENTRY glVertex3iv(const GLint *v)
7699{
7700 UNIMPLEMENTED();
7701}
7702
7703void APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z)
7704{
7705 UNIMPLEMENTED();
7706}
7707
7708void APIENTRY glVertex3sv(const GLshort *v)
7709{
7710 UNIMPLEMENTED();
7711}
7712
7713void APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
7714{
7715 UNIMPLEMENTED();
7716}
7717
7718void APIENTRY glVertex4dv(const GLdouble *v)
7719{
7720 UNIMPLEMENTED();
7721}
7722
7723void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
7724{
7725 UNIMPLEMENTED();
7726}
7727
7728void APIENTRY glVertex4fv(const GLfloat *v)
7729{
7730 UNIMPLEMENTED();
7731}
7732
7733void APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w)
7734{
7735 UNIMPLEMENTED();
7736}
7737
7738void APIENTRY glVertex4iv(const GLint *v)
7739{
7740 UNIMPLEMENTED();
7741}
7742
7743void APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
7744{
7745 UNIMPLEMENTED();
7746}
7747
7748void APIENTRY glVertex4sv(const GLshort *v)
7749{
7750 UNIMPLEMENTED();
7751}
7752
7753void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
7754{
Nicolas Capens4be33702015-04-28 15:13:30 -07007755 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 -05007756
7757 glVertexAttribPointer(sw::Position, size, type, false, stride, pointer);
7758}
7759
7760void APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) {UNIMPLEMENTED();}
7761void APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}
7762void 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();}
7763void APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
7764
7765void APIENTRY glClientActiveTexture(GLenum texture)
7766{
7767 TRACE("(GLenum texture = 0x%X)", texture);
7768
7769 switch(texture)
7770 {
7771 case GL_TEXTURE0:
7772 case GL_TEXTURE1:
7773 break;
7774 default:
7775 UNIMPLEMENTED();
7776 UNREACHABLE();
7777 }
7778
7779 gl::Context *context = gl::getContext();
7780
7781 if(context)
7782 {
7783 context->clientActiveTexture(texture);
7784 }
7785}
7786
7787void APIENTRY glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7788void APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7789void APIENTRY glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7790void 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();}
7791void APIENTRY glGetCompressedTexImage(GLenum target, GLint level, void *img) {UNIMPLEMENTED();}
7792void APIENTRY glMultiTexCoord1f(GLenum target, GLfloat s) {UNIMPLEMENTED();}
7793void APIENTRY glMultiTexCoord1d(GLenum target, GLdouble s) {UNIMPLEMENTED();}
7794
7795void APIENTRY glMultiTexCoord2f(GLenum texture, GLfloat s, GLfloat t)
7796{
7797 TRACE("(GLenum texture = 0x%X, GLfloat s = %f, GLfloat t = %f)", texture, s, t);
7798
7799 gl::Context *context = gl::getContext();
7800
7801 if(context)
7802 {
7803 if(context->getListIndex() != 0)
7804 {
7805 UNIMPLEMENTED();
7806 }
7807
7808 //context->texCoord(s, t, 0.0f, 1.0f);
7809 context->setVertexAttrib(sw::TexCoord0 + (texture - GL_TEXTURE0), s, t, 0.0f, 1.0f);
7810 }
7811}
7812
7813void APIENTRY glMultiTexCoord2d(GLenum target, GLdouble s, GLdouble t) {UNIMPLEMENTED();}
7814void APIENTRY glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {UNIMPLEMENTED();}
7815void APIENTRY glMultiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r) {UNIMPLEMENTED();}
7816void APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {UNIMPLEMENTED();}
7817void APIENTRY glMultiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) {UNIMPLEMENTED();}
7818void APIENTRY glLoadTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
7819void APIENTRY glLoadTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
7820void APIENTRY glMultTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
7821void APIENTRY glMultTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
7822void APIENTRY glFogCoordf(GLfloat coord) {UNIMPLEMENTED();}
7823void APIENTRY glFogCoordd(GLdouble coord) {UNIMPLEMENTED();}
7824void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
7825void APIENTRY glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) {UNIMPLEMENTED();}
7826void APIENTRY glPointParameteri(GLenum pname, GLint param) {UNIMPLEMENTED();}
7827void APIENTRY glPointParameterf(GLenum pname, GLfloat param) {UNIMPLEMENTED();}
7828void APIENTRY glPointParameteriv(GLenum pname, const GLint *params) {UNIMPLEMENTED();}
7829void APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params) {UNIMPLEMENTED();}
7830void APIENTRY glSecondaryColor3b(GLbyte red, GLbyte green, GLbyte blue) {UNIMPLEMENTED();}
7831void APIENTRY glSecondaryColor3f(GLfloat red, GLfloat green, GLfloat blue) {UNIMPLEMENTED();}
7832void APIENTRY glSecondaryColor3d(GLdouble red, GLdouble green, GLdouble blue) {UNIMPLEMENTED();}
7833void APIENTRY glSecondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue) {UNIMPLEMENTED();}
7834void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
7835void APIENTRY glWindowPos2f(GLfloat x, GLfloat y) {UNIMPLEMENTED();}
7836void APIENTRY glWindowPos2d(GLdouble x, GLdouble y) {UNIMPLEMENTED();}
7837void APIENTRY glWindowPos2i(GLint x, GLint y) {UNIMPLEMENTED();}
7838void APIENTRY glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) {UNIMPLEMENTED();}
7839void APIENTRY glWindowPos3d(GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
7840void APIENTRY glWindowPos3i(GLint x, GLint y, GLint z) {UNIMPLEMENTED();}
7841void APIENTRY glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data) {UNIMPLEMENTED();}
7842void *APIENTRY glMapBuffer(GLenum target, GLenum access) {UNIMPLEMENTED(); return 0;}
7843GLboolean APIENTRY glUnmapBuffer(GLenum target) {UNIMPLEMENTED(); return GL_FALSE;}
7844void APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params) {UNIMPLEMENTED();}
7845void APIENTRY glGenQueries(GLsizei n, GLuint *ids) {UNIMPLEMENTED();}
7846void APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids) {UNIMPLEMENTED();}
7847GLboolean APIENTRY glIsQuery(GLuint id) {UNIMPLEMENTED(); return 0;}
7848void APIENTRY glBeginQuery(GLenum target, GLuint id) {UNIMPLEMENTED();}
7849void APIENTRY glEndQuery(GLenum target) {UNIMPLEMENTED();}
7850void APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params) {UNIMPLEMENTED();}
7851void APIENTRY glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) {UNIMPLEMENTED();}
7852void APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) {UNIMPLEMENTED();}
7853void APIENTRY glVertexAttrib1s(GLuint index, GLshort x) {UNIMPLEMENTED();}
7854void APIENTRY glVertexAttrib1d(GLuint index, GLdouble x) {UNIMPLEMENTED();}
7855void APIENTRY glVertexAttrib2s(GLuint index, GLshort x, GLshort y) {UNIMPLEMENTED();}
7856void APIENTRY glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y) {UNIMPLEMENTED();}
7857void APIENTRY glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z) {UNIMPLEMENTED();}
7858void APIENTRY glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
7859void APIENTRY glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) {UNIMPLEMENTED();}
7860void APIENTRY glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {UNIMPLEMENTED();}
7861void APIENTRY glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {UNIMPLEMENTED();}
7862void APIENTRY glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {UNIMPLEMENTED();}
7863void APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs) {UNIMPLEMENTED();}
7864void APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7865void APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7866void APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7867void APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7868void APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7869void APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7870
7871void APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {UNIMPLEMENTED();}
7872void APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
7873void APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {UNIMPLEMENTED();}
7874
7875BOOL WINAPI wglSwapIntervalEXT(int interval)
7876{
7877 gl::Surface *drawSurface = static_cast<gl::Surface*>(gl::getCurrentDrawSurface());
7878
7879 if(drawSurface)
7880 {
7881 drawSurface->setSwapInterval(interval);
7882 return TRUE;
7883 }
7884
7885 SetLastError(ERROR_DC_NOT_FOUND);
7886 return FALSE;
7887}
7888
7889int WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)
7890{
7891 TRACE("(*)");
7892
7893 return 1;
7894}
7895
7896BOOL WINAPI wglCopyContext(HGLRC, HGLRC, UINT)
7897{
7898 UNIMPLEMENTED();
7899 return FALSE;
7900}
7901
7902HGLRC WINAPI wglCreateContext(HDC hdc)
7903{
7904 TRACE("(*)");
7905
7906 gl::Display *display = gl::Display::getDisplay(hdc);
7907 display->initialize();
7908
7909 gl::Context *context = display->createContext(nullptr);
7910
7911 return (HGLRC)context;
7912}
7913
7914HGLRC WINAPI wglCreateLayerContext(HDC, int)
7915{
7916 UNIMPLEMENTED();
7917 return 0;
7918}
7919
7920BOOL WINAPI wglDeleteContext(HGLRC context)
7921{
7922 gl::Display *display = gl::getDisplay();
7923
7924 if(display && context)
7925 {
7926 display->destroyContext(reinterpret_cast<gl::Context*>(context));
7927
7928 return TRUE;
7929 }
7930
Maxime Grégoiredff6d002015-07-16 10:26:45 -04007931 return FALSE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05007932}
7933
7934BOOL WINAPI wglDescribeLayerPlane(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR)
7935{
7936 UNIMPLEMENTED();
7937 return FALSE;
7938}
7939
7940int WINAPI wglDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
7941{
7942 TRACE("(*)");
7943
7944 ASSERT(nBytes == sizeof(PIXELFORMATDESCRIPTOR)); // FIXME
7945
7946 ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
7947 ppfd->nVersion = 1;
7948 ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
7949 ppfd->iPixelType = PFD_TYPE_RGBA;
7950 ppfd->cColorBits = 32;
7951 ppfd->cRedBits = 8;
7952 ppfd->cRedShift = 16;
7953 ppfd->cGreenBits = 8;
7954 ppfd->cGreenShift = 8;
7955 ppfd->cBlueBits = 8;
7956 ppfd->cBlueShift = 0;
7957 ppfd->cAlphaBits = 0;
7958 ppfd->cAlphaShift = 24;
7959 ppfd->cAccumBits = 0;
7960 ppfd->cAccumRedBits = 0;
7961 ppfd->cAccumGreenBits = 0;
7962 ppfd->cAccumBlueBits = 0;
7963 ppfd->cAccumAlphaBits = 0;
7964 ppfd->cDepthBits = 24;
7965 ppfd->cStencilBits = 0;
7966 ppfd->cAuxBuffers = 0;
7967 ppfd->iLayerType = 0;
7968 ppfd->bReserved = 0;
7969 ppfd->dwLayerMask = 0;
7970 ppfd->dwVisibleMask = 0;
7971 ppfd->dwDamageMask = 0;
7972
7973 return 1;
7974}
7975
7976HGLRC WINAPI wglGetCurrentContext(VOID)
7977{
7978 TRACE("(*)");
7979 return (HGLRC)gl::getContext();
7980}
7981
7982HDC WINAPI wglGetCurrentDC(VOID)
7983{
7984 TRACE("(*)");
7985 gl::Display *display = gl::getDisplay();
7986 return display ? display->getNativeDisplay() : 0;
7987}
7988
7989void WINAPI wglGetDefaultProcAddress()
7990{
7991 UNIMPLEMENTED();
7992}
7993
7994int WINAPI wglGetLayerPaletteEntries(HDC, int, int, int, COLORREF*)
7995{
7996 UNIMPLEMENTED();
7997 return 0;
7998}
7999
8000void WINAPI wglGetPixelFormat()
8001{
8002 UNIMPLEMENTED();
8003}
8004
8005const char *WINAPI wglGetExtensionsStringARB(HDC hdc)
8006{
8007 TRACE("(*)");
8008
Maxime Grégoiredff6d002015-07-16 10:26:45 -04008009 return "GL_ARB_framebuffer_object "
8010 "WGL_EXT_extensions_string "
8011 "WGL_EXT_swap_control";
Nicolas Capensa9b49372015-01-30 00:33:26 -05008012}
8013
8014const char *WINAPI wglGetExtensionsStringEXT()
8015{
8016 TRACE("(*)");
8017 return wglGetExtensionsStringARB(0);
8018}
8019
8020PROC WINAPI wglGetProcAddress(LPCSTR lpszProc)
8021{
8022 TRACE("(LPCSTR lpszProc = \"%s\")", lpszProc);
8023
Nicolas Capens264f1522015-01-09 17:21:17 -05008024 struct Extension
8025 {
8026 const char *name;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008027 PROC address;
Nicolas Capens264f1522015-01-09 17:21:17 -05008028 };
8029
8030 static const Extension glExtensions[] =
8031 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05008032 #define EXT(function) {#function, (PROC)function}
8033
8034 // Core 2.1
8035 EXT(glDrawRangeElements),
8036 EXT(glTexImage3D),
8037 EXT(glTexSubImage3D),
8038 EXT(glCopyTexSubImage3D),
8039 EXT(glActiveTexture),
8040 EXT(glClientActiveTexture),
8041 EXT(glCompressedTexImage1D),
8042 EXT(glCompressedTexImage2D),
8043 EXT(glCompressedTexImage3D),
8044 EXT(glCompressedTexSubImage1D),
8045 EXT(glCompressedTexSubImage2D),
8046 EXT(glCompressedTexSubImage3D),
8047 EXT(glGetCompressedTexImage),
8048 EXT(glMultiTexCoord1f),
8049 EXT(glMultiTexCoord1d),
8050 EXT(glMultiTexCoord2f),
8051 EXT(glMultiTexCoord2d),
8052 EXT(glMultiTexCoord3f),
8053 EXT(glMultiTexCoord3d),
8054 EXT(glMultiTexCoord4f),
8055 EXT(glMultiTexCoord4d),
8056 EXT(glLoadTransposeMatrixf),
8057 EXT(glLoadTransposeMatrixd),
8058 EXT(glMultTransposeMatrixf),
8059 EXT(glMultTransposeMatrixd),
8060 EXT(glSampleCoverage),
8061 EXT(glBlendEquation),
8062 EXT(glBlendColor),
8063 EXT(glFogCoordf),
8064 EXT(glFogCoordd),
8065 EXT(glFogCoordPointer),
8066 EXT(glMultiDrawArrays),
8067 EXT(glPointParameteri),
8068 EXT(glPointParameterf),
8069 EXT(glPointParameteriv),
8070 EXT(glPointParameterfv),
8071 EXT(glSecondaryColor3b),
8072 EXT(glSecondaryColor3f),
8073 EXT(glSecondaryColor3d),
8074 EXT(glSecondaryColor3ub),
8075 EXT(glSecondaryColorPointer),
8076 EXT(glBlendFuncSeparate),
8077 EXT(glWindowPos2f),
8078 EXT(glWindowPos2d),
8079 EXT(glWindowPos2i),
8080 EXT(glWindowPos3f),
8081 EXT(glWindowPos3d),
8082 EXT(glWindowPos3i),
8083 EXT(glBindBuffer),
8084 EXT(glDeleteBuffers),
8085 EXT(glGenBuffers),
8086 EXT(glIsBuffer),
8087 EXT(glBufferData),
8088 EXT(glBufferSubData),
8089 EXT(glGetBufferSubData),
8090 EXT(glMapBuffer),
8091 EXT(glUnmapBuffer),
8092 EXT(glGetBufferParameteriv),
8093 EXT(glGetBufferPointerv),
8094 EXT(glGenQueries),
8095 EXT(glDeleteQueries),
8096 EXT(glIsQuery),
8097 EXT(glBeginQuery),
8098 EXT(glEndQuery),
8099 EXT(glGetQueryiv),
8100 EXT(glGetQueryObjectiv),
8101 EXT(glGetQueryObjectuiv),
8102 EXT(glShaderSource),
8103 EXT(glCreateShader),
8104 EXT(glIsShader),
8105 EXT(glCompileShader),
8106 EXT(glDeleteShader),
8107 EXT(glCreateProgram),
8108 EXT(glIsProgram),
8109 EXT(glAttachShader),
8110 EXT(glDetachShader),
8111 EXT(glLinkProgram),
8112 EXT(glUseProgram),
8113 EXT(glValidateProgram),
8114 EXT(glDeleteProgram),
8115 EXT(glUniform1f),
8116 EXT(glUniform2f),
8117 EXT(glUniform3f),
8118 EXT(glUniform4f),
8119 EXT(glUniform1i),
8120 EXT(glUniform2i),
8121 EXT(glUniform3i),
8122 EXT(glUniform4i),
8123 EXT(glUniform1fv),
8124 EXT(glUniform2fv),
8125 EXT(glUniform3fv),
8126 EXT(glUniform4fv),
8127 EXT(glUniform1iv),
8128 EXT(glUniform2iv),
8129 EXT(glUniform3iv),
8130 EXT(glUniform4iv),
8131 EXT(glUniformMatrix2fv),
8132 EXT(glUniformMatrix3fv),
8133 EXT(glUniformMatrix4fv),
8134 EXT(glGetShaderiv),
8135 EXT(glGetProgramiv),
8136 EXT(glGetShaderInfoLog),
8137 EXT(glGetProgramInfoLog),
8138 EXT(glGetAttachedShaders),
8139 EXT(glGetUniformLocation),
8140 EXT(glGetActiveUniform),
8141 EXT(glGetUniformfv),
8142 EXT(glGetUniformiv),
8143 EXT(glGetShaderSource),
8144 EXT(glVertexAttrib1s),
8145 EXT(glVertexAttrib1f),
8146 EXT(glVertexAttrib1d),
8147 EXT(glVertexAttrib2s),
8148 EXT(glVertexAttrib2f),
8149 EXT(glVertexAttrib2d),
8150 EXT(glVertexAttrib3s),
8151 EXT(glVertexAttrib3f),
8152 EXT(glVertexAttrib3d),
8153 EXT(glVertexAttrib4s),
8154 EXT(glVertexAttrib4f),
8155 EXT(glVertexAttrib4d),
8156 EXT(glVertexAttrib4Nub),
8157 EXT(glVertexAttribPointer),
8158 EXT(glEnableVertexAttribArray),
8159 EXT(glDisableVertexAttribArray),
8160 EXT(glGetVertexAttribfv),
8161 EXT(glGetVertexAttribdv),
8162 EXT(glGetVertexAttribiv),
8163 EXT(glGetVertexAttribPointerv),
8164 EXT(glBindAttribLocation),
8165 EXT(glGetActiveAttrib),
8166 EXT(glGetAttribLocation),
8167 EXT(glDrawBuffers),
8168 EXT(glStencilOpSeparate),
8169 EXT(glStencilFuncSeparate),
8170 EXT(glStencilMaskSeparate),
8171 EXT(glBlendEquationSeparate),
8172 EXT(glUniformMatrix2x3fv),
8173 EXT(glUniformMatrix3x2fv),
8174 EXT(glUniformMatrix2x4fv),
8175 EXT(glUniformMatrix4x2fv),
8176 EXT(glUniformMatrix3x4fv),
8177 EXT(glUniformMatrix4x3fv),
8178 EXT(glGenFencesNV),
8179 EXT(glDeleteFencesNV),
8180 EXT(glSetFenceNV),
8181 EXT(glTestFenceNV),
8182 EXT(glFinishFenceNV),
8183 EXT(glIsFenceNV),
8184 EXT(glGetFenceivNV),
8185
8186 EXT(glIsRenderbuffer),
8187 EXT(glBindRenderbuffer),
8188 EXT(glDeleteRenderbuffers),
8189 EXT(glGenRenderbuffers),
8190 EXT(glRenderbufferStorage),
8191 EXT(glGetRenderbufferParameteriv),
8192 EXT(glIsFramebuffer),
8193 EXT(glBindFramebuffer),
8194 EXT(glDeleteFramebuffers),
8195 EXT(glGenFramebuffers),
8196 EXT(glCheckFramebufferStatus),
8197 EXT(glFramebufferTexture1D),
8198 EXT(glFramebufferTexture2D),
8199 EXT(glFramebufferTexture3D),
8200 EXT(glFramebufferRenderbuffer),
8201 EXT(glGetFramebufferAttachmentParameteriv),
8202 EXT(glGenerateMipmap),
8203 EXT(glReleaseShaderCompiler),
8204 EXT(glShaderBinary),
8205 EXT(glGetShaderPrecisionFormat),
8206 EXT(glDepthRangef),
8207 EXT(glClearDepthf),
Nicolas Capens264f1522015-01-09 17:21:17 -05008208
Nicolas Capensa9b49372015-01-30 00:33:26 -05008209 // ARB
8210 EXT(wglGetExtensionsStringARB),
8211 EXT(glIsRenderbuffer),
8212 EXT(glBindRenderbuffer),
8213 EXT(glDeleteRenderbuffers),
8214 EXT(glGenRenderbuffers),
8215 EXT(glRenderbufferStorage),
8216 EXT(glRenderbufferStorageMultisample),
8217 EXT(glGetRenderbufferParameteriv),
8218 EXT(glIsFramebuffer),
8219 EXT(glBindFramebuffer),
8220 EXT(glDeleteFramebuffers),
8221 EXT(glGenFramebuffers),
8222 EXT(glCheckFramebufferStatus),
8223 EXT(glFramebufferTexture1D),
8224 EXT(glFramebufferTexture2D),
8225 EXT(glFramebufferTexture3D),
8226 EXT(glFramebufferTextureLayer),
8227 EXT(glFramebufferRenderbuffer),
8228 EXT(glGetFramebufferAttachmentParameteriv),
8229 EXT(glBlitFramebuffer),
8230 EXT(glGenerateMipmap),
Nicolas Capens264f1522015-01-09 17:21:17 -05008231
Nicolas Capensa9b49372015-01-30 00:33:26 -05008232 // EXT
8233 EXT(wglSwapIntervalEXT),
8234 EXT(wglGetExtensionsStringEXT),
8235 #undef EXT
Nicolas Capens264f1522015-01-09 17:21:17 -05008236 };
8237
8238 for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
8239 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05008240 if(strcmp(lpszProc, glExtensions[ext].name) == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05008241 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05008242 return (PROC)glExtensions[ext].address;
Nicolas Capens264f1522015-01-09 17:21:17 -05008243 }
8244 }
8245
Nicolas Capensa9b49372015-01-30 00:33:26 -05008246 FARPROC proc = GetProcAddress(GetModuleHandle("opengl32.dll"), lpszProc); // FIXME?
8247
8248 if(proc)
8249 {
8250 return proc;
8251 }
8252
8253 TRACE("(LPCSTR lpszProc = \"%s\") NOT FOUND!!!", lpszProc);
8254
Maxime Grégoiredff6d002015-07-16 10:26:45 -04008255 return 0;
Nicolas Capens264f1522015-01-09 17:21:17 -05008256}
8257
Nicolas Capensa9b49372015-01-30 00:33:26 -05008258BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
8259{
8260 TRACE("(*)");
8261
8262 if(hdc && hglrc)
8263 {
8264 gl::Display *display = (gl::Display*)gl::Display::getDisplay(hdc);
8265 gl::makeCurrent((gl::Context*)hglrc, display, display->getPrimarySurface());
8266 gl::setCurrentDrawSurface(display->getPrimarySurface());
8267 gl::setCurrentDisplay(display);
8268 }
8269 else
8270 {
8271 gl::makeCurrent(0, 0, 0);
8272 }
8273
8274 return TRUE;
8275}
8276
8277BOOL WINAPI wglRealizeLayerPalette(HDC, int, BOOL)
8278{
8279 UNIMPLEMENTED();
8280 return FALSE;
8281}
8282
8283int WINAPI wglSetLayerPaletteEntries(HDC, int, int, int, CONST COLORREF*)
8284{
8285 UNIMPLEMENTED();
8286 return 0;
8287}
8288
8289BOOL WINAPI wglSetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
8290{
8291 TRACE("(*)");
8292 //UNIMPLEMENTED();
8293
8294 return TRUE;
8295}
8296
Maxime Grégoiredff6d002015-07-16 10:26:45 -04008297BOOL WINAPI wglShareLists(HGLRC, HGLRC)
Nicolas Capensa9b49372015-01-30 00:33:26 -05008298{
Maxime Grégoiredff6d002015-07-16 10:26:45 -04008299 UNIMPLEMENTED();
8300 return FALSE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008301}
8302
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008303BOOL WINAPI wglSwapBuffers(HDC hdc)
Nicolas Capensa9b49372015-01-30 00:33:26 -05008304{
8305 TRACE("(*)");
8306
8307 gl::Display *display = gl::getDisplay();
8308
8309 if(display)
8310 {
8311 display->getPrimarySurface()->swap();
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008312 return TRUE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008313 }
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008314
8315 return FALSE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008316}
8317
8318BOOL WINAPI wglSwapLayerBuffers(HDC, UINT)
8319{
8320 UNIMPLEMENTED();
8321 return FALSE;
8322}
8323
8324DWORD WINAPI wglSwapMultipleBuffers(UINT, CONST WGLSWAP*)
8325{
8326 UNIMPLEMENTED();
8327 return 0;
8328}
8329
8330BOOL WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD)
8331{
8332 UNIMPLEMENTED();
8333 return FALSE;
8334}
8335
8336BOOL WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD)
8337{
8338 UNIMPLEMENTED();
8339 return FALSE;
8340}
8341
8342BOOL WINAPI wglUseFontOutlinesA(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
8343{
8344 UNIMPLEMENTED();
8345 return FALSE;
8346}
8347
8348BOOL WINAPI wglUseFontOutlinesW(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
8349{
8350 UNIMPLEMENTED();
8351 return FALSE;
8352}
8353
8354void APIENTRY Register(const char *licenseKey)
Nicolas Capens264f1522015-01-09 17:21:17 -05008355{
8356 RegisterLicenseKey(licenseKey);
8357}
8358
8359}