blob: 8458b78b8b90b671027bfc70c955946928288aac [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>
32#define GL_GLEXT_PROTOTYPES
33#include <GL/glext.h>
Nicolas Capens264f1522015-01-09 17:21:17 -050034
35#include <exception>
36#include <limits>
37
38static bool validImageSize(GLint level, GLsizei width, GLsizei height)
39{
Nicolas Capensf4486fd2015-01-22 11:10:37 -050040 if(level < 0 || level >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
Nicolas Capens264f1522015-01-09 17:21:17 -050041 {
42 return false;
43 }
44
45 return true;
46}
47
Nicolas Capensf4486fd2015-01-22 11:10:37 -050048static 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 -050049{
50 if(!texture)
51 {
52 return error(GL_INVALID_OPERATION, false);
53 }
54
55 if(compressed != texture->isCompressed(target, level))
56 {
57 return error(GL_INVALID_OPERATION, false);
58 }
59
60 if(format != GL_NONE && format != texture->getFormat(target, level))
61 {
62 return error(GL_INVALID_OPERATION, false);
63 }
64
65 if(compressed)
66 {
67 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
68 (height % 4 != 0 && height != texture->getHeight(target, 0)))
69 {
70 return error(GL_INVALID_OPERATION, false);
71 }
72 }
73
74 if(xoffset + width > texture->getWidth(target, level) ||
75 yoffset + height > texture->getHeight(target, level))
76 {
77 return error(GL_INVALID_VALUE, false);
78 }
79
80 return true;
81}
82
83// Check for combinations of format and type that are valid for ReadPixels
84static bool validReadFormatType(GLenum format, GLenum type)
85{
86 switch(format)
87 {
88 case GL_RGBA:
89 switch(type)
90 {
91 case GL_UNSIGNED_BYTE:
92 break;
93 default:
94 return false;
95 }
96 break;
97 case GL_BGRA_EXT:
98 switch(type)
99 {
100 case GL_UNSIGNED_BYTE:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500101 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
102 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
Nicolas Capens264f1522015-01-09 17:21:17 -0500103 break;
104 default:
105 return false;
106 }
107 break;
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500108 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500109 switch(type)
110 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500111 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
Nicolas Capens264f1522015-01-09 17:21:17 -0500112 break;
113 default:
114 return false;
115 }
116 break;
117 default:
118 return false;
119 }
120
121 return true;
122}
123
124extern "C"
125{
126
Nicolas Capensa9b49372015-01-30 00:33:26 -0500127void APIENTRY glActiveTexture(GLenum texture)
Nicolas Capens264f1522015-01-09 17:21:17 -0500128{
129 TRACE("(GLenum texture = 0x%X)", texture);
130
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500131 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500132
133 if(context)
134 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500135 if(context->getListIndex() != 0)
136 {
137 UNIMPLEMENTED();
138 }
139
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500140 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
Nicolas Capens264f1522015-01-09 17:21:17 -0500141 {
142 return error(GL_INVALID_ENUM);
143 }
144
145 context->setActiveSampler(texture - GL_TEXTURE0);
146 }
147}
148
Nicolas Capensa9b49372015-01-30 00:33:26 -0500149void APIENTRY glAttachShader(GLuint program, GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -0500150{
151 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
152
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500153 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500154
155 if(context)
156 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500157 gl::Program *programObject = context->getProgram(program);
158 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -0500159
160 if(!programObject)
161 {
162 if(context->getShader(program))
163 {
164 return error(GL_INVALID_OPERATION);
165 }
166 else
167 {
168 return error(GL_INVALID_VALUE);
169 }
170 }
171
172 if(!shaderObject)
173 {
174 if(context->getProgram(shader))
175 {
176 return error(GL_INVALID_OPERATION);
177 }
178 else
179 {
180 return error(GL_INVALID_VALUE);
181 }
182 }
183
184 if(!programObject->attachShader(shaderObject))
185 {
186 return error(GL_INVALID_OPERATION);
187 }
188 }
189}
190
Nicolas Capensa9b49372015-01-30 00:33:26 -0500191void APIENTRY glBeginQueryEXT(GLenum target, GLuint name)
Nicolas Capens264f1522015-01-09 17:21:17 -0500192{
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500193 TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
Nicolas Capens264f1522015-01-09 17:21:17 -0500194
195 switch(target)
196 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500197 case GL_ANY_SAMPLES_PASSED:
198 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
Nicolas Capens264f1522015-01-09 17:21:17 -0500199 break;
200 default:
201 return error(GL_INVALID_ENUM);
202 }
203
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500204 if(name == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -0500205 {
206 return error(GL_INVALID_OPERATION);
207 }
208
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500209 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500210
211 if(context)
212 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500213 if(context->getListIndex() != 0)
214 {
215 UNIMPLEMENTED();
216 }
217
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500218 context->beginQuery(target, name);
Nicolas Capens264f1522015-01-09 17:21:17 -0500219 }
220}
221
Nicolas Capensa9b49372015-01-30 00:33:26 -0500222void APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -0500223{
224 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
225
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500226 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -0500227 {
228 return error(GL_INVALID_VALUE);
229 }
230
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500231 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500232
233 if(context)
234 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500235 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -0500236
237 if(!programObject)
238 {
239 if(context->getShader(program))
240 {
241 return error(GL_INVALID_OPERATION);
242 }
243 else
244 {
245 return error(GL_INVALID_VALUE);
246 }
247 }
248
249 if(strncmp(name, "gl_", 3) == 0)
250 {
251 return error(GL_INVALID_OPERATION);
252 }
253
254 programObject->bindAttributeLocation(index, name);
255 }
256}
257
Nicolas Capensa9b49372015-01-30 00:33:26 -0500258void APIENTRY glBindBuffer(GLenum target, GLuint buffer)
Nicolas Capens264f1522015-01-09 17:21:17 -0500259{
260 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
261
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500262 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500263
264 if(context)
265 {
266 switch(target)
267 {
268 case GL_ARRAY_BUFFER:
269 context->bindArrayBuffer(buffer);
270 return;
271 case GL_ELEMENT_ARRAY_BUFFER:
272 context->bindElementArrayBuffer(buffer);
273 return;
274 default:
275 return error(GL_INVALID_ENUM);
276 }
277 }
278}
279
Nicolas Capensa9b49372015-01-30 00:33:26 -0500280void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -0500281{
282 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
283
Nicolas Capensa9b49372015-01-30 00:33:26 -0500284 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500285 {
286 return error(GL_INVALID_ENUM);
287 }
288
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500289 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500290
291 if(context)
292 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500293 if(context->getListIndex() != 0)
294 {
295 UNIMPLEMENTED();
296 }
297
298 if(target == GL_READ_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
Nicolas Capens264f1522015-01-09 17:21:17 -0500299 {
300 context->bindReadFramebuffer(framebuffer);
301 }
Nicolas Capensa9b49372015-01-30 00:33:26 -0500302
303 if(target == GL_DRAW_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
Nicolas Capens264f1522015-01-09 17:21:17 -0500304 {
305 context->bindDrawFramebuffer(framebuffer);
306 }
307 }
308}
309
Nicolas Capensa9b49372015-01-30 00:33:26 -0500310void APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -0500311{
312 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
313
314 if(target != GL_RENDERBUFFER)
315 {
316 return error(GL_INVALID_ENUM);
317 }
318
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500319 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500320
321 if(context)
322 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500323 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -0500324 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500325 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -0500326 }
327
328 context->bindRenderbuffer(renderbuffer);
329 }
330}
331
Nicolas Capensa9b49372015-01-30 00:33:26 -0500332void APIENTRY glBindTexture(GLenum target, GLuint texture)
Nicolas Capens264f1522015-01-09 17:21:17 -0500333{
334 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
335
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500336 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500337
338 if(context)
339 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500340 if(context->getListIndex() != 0)
341 {
342 UNIMPLEMENTED();
343 }
344
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500345 gl::Texture *textureObject = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -0500346
347 if(textureObject && textureObject->getTarget() != target && texture != 0)
348 {
349 return error(GL_INVALID_OPERATION);
350 }
351
352 switch(target)
353 {
354 case GL_TEXTURE_2D:
355 context->bindTexture2D(texture);
356 return;
357 case GL_TEXTURE_CUBE_MAP:
358 context->bindTextureCubeMap(texture);
359 return;
Nicolas Capens264f1522015-01-09 17:21:17 -0500360 default:
361 return error(GL_INVALID_ENUM);
362 }
363 }
364}
365
Nicolas Capensa9b49372015-01-30 00:33:26 -0500366void APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500367{
368 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
Nicolas Capensa9b49372015-01-30 00:33:26 -0500369 red, green, blue, alpha);
Nicolas Capens264f1522015-01-09 17:21:17 -0500370
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500371 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500372
373 if(context)
374 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500375 if(context->getListIndex() != 0)
376 {
377 UNIMPLEMENTED();
378 }
379
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500380 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
Nicolas Capens264f1522015-01-09 17:21:17 -0500381 }
382}
383
Nicolas Capensa9b49372015-01-30 00:33:26 -0500384void APIENTRY glBlendEquation(GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -0500385{
386 glBlendEquationSeparate(mode, mode);
387}
388
Nicolas Capensa9b49372015-01-30 00:33:26 -0500389void APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500390{
391 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
392
393 switch(modeRGB)
394 {
395 case GL_FUNC_ADD:
396 case GL_FUNC_SUBTRACT:
397 case GL_FUNC_REVERSE_SUBTRACT:
398 case GL_MIN_EXT:
399 case GL_MAX_EXT:
400 break;
401 default:
402 return error(GL_INVALID_ENUM);
403 }
404
405 switch(modeAlpha)
406 {
407 case GL_FUNC_ADD:
408 case GL_FUNC_SUBTRACT:
409 case GL_FUNC_REVERSE_SUBTRACT:
410 case GL_MIN_EXT:
411 case GL_MAX_EXT:
412 break;
413 default:
414 return error(GL_INVALID_ENUM);
415 }
416
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500417 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500418
419 if(context)
420 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500421 if(context->getListIndex() != 0)
422 {
423 UNIMPLEMENTED();
424 }
425
Nicolas Capens264f1522015-01-09 17:21:17 -0500426 context->setBlendEquation(modeRGB, modeAlpha);
427 }
428}
429
Nicolas Capensa9b49372015-01-30 00:33:26 -0500430void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
Nicolas Capens264f1522015-01-09 17:21:17 -0500431{
432 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
433}
434
Nicolas Capensa9b49372015-01-30 00:33:26 -0500435void APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500436{
437 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
438 srcRGB, dstRGB, srcAlpha, dstAlpha);
439
440 switch(srcRGB)
441 {
442 case GL_ZERO:
443 case GL_ONE:
444 case GL_SRC_COLOR:
445 case GL_ONE_MINUS_SRC_COLOR:
446 case GL_DST_COLOR:
447 case GL_ONE_MINUS_DST_COLOR:
448 case GL_SRC_ALPHA:
449 case GL_ONE_MINUS_SRC_ALPHA:
450 case GL_DST_ALPHA:
451 case GL_ONE_MINUS_DST_ALPHA:
452 case GL_CONSTANT_COLOR:
453 case GL_ONE_MINUS_CONSTANT_COLOR:
454 case GL_CONSTANT_ALPHA:
455 case GL_ONE_MINUS_CONSTANT_ALPHA:
456 case GL_SRC_ALPHA_SATURATE:
457 break;
458 default:
459 return error(GL_INVALID_ENUM);
460 }
461
462 switch(dstRGB)
463 {
464 case GL_ZERO:
465 case GL_ONE:
466 case GL_SRC_COLOR:
467 case GL_ONE_MINUS_SRC_COLOR:
468 case GL_DST_COLOR:
469 case GL_ONE_MINUS_DST_COLOR:
470 case GL_SRC_ALPHA:
471 case GL_ONE_MINUS_SRC_ALPHA:
472 case GL_DST_ALPHA:
473 case GL_ONE_MINUS_DST_ALPHA:
474 case GL_CONSTANT_COLOR:
475 case GL_ONE_MINUS_CONSTANT_COLOR:
476 case GL_CONSTANT_ALPHA:
477 case GL_ONE_MINUS_CONSTANT_ALPHA:
478 break;
479 default:
480 return error(GL_INVALID_ENUM);
481 }
482
483 switch(srcAlpha)
484 {
485 case GL_ZERO:
486 case GL_ONE:
487 case GL_SRC_COLOR:
488 case GL_ONE_MINUS_SRC_COLOR:
489 case GL_DST_COLOR:
490 case GL_ONE_MINUS_DST_COLOR:
491 case GL_SRC_ALPHA:
492 case GL_ONE_MINUS_SRC_ALPHA:
493 case GL_DST_ALPHA:
494 case GL_ONE_MINUS_DST_ALPHA:
495 case GL_CONSTANT_COLOR:
496 case GL_ONE_MINUS_CONSTANT_COLOR:
497 case GL_CONSTANT_ALPHA:
498 case GL_ONE_MINUS_CONSTANT_ALPHA:
499 case GL_SRC_ALPHA_SATURATE:
500 break;
501 default:
502 return error(GL_INVALID_ENUM);
503 }
504
505 switch(dstAlpha)
506 {
507 case GL_ZERO:
508 case GL_ONE:
509 case GL_SRC_COLOR:
510 case GL_ONE_MINUS_SRC_COLOR:
511 case GL_DST_COLOR:
512 case GL_ONE_MINUS_DST_COLOR:
513 case GL_SRC_ALPHA:
514 case GL_ONE_MINUS_SRC_ALPHA:
515 case GL_DST_ALPHA:
516 case GL_ONE_MINUS_DST_ALPHA:
517 case GL_CONSTANT_COLOR:
518 case GL_ONE_MINUS_CONSTANT_COLOR:
519 case GL_CONSTANT_ALPHA:
520 case GL_ONE_MINUS_CONSTANT_ALPHA:
521 break;
522 default:
523 return error(GL_INVALID_ENUM);
524 }
525
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500526 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500527
528 if(context)
529 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500530 if(context->getListIndex() != 0)
531 {
532 UNIMPLEMENTED();
533 }
534
Nicolas Capens264f1522015-01-09 17:21:17 -0500535 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
536 }
537}
538
Nicolas Capensa9b49372015-01-30 00:33:26 -0500539void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
Nicolas Capens264f1522015-01-09 17:21:17 -0500540{
Nicolas Capens264f1522015-01-09 17:21:17 -0500541 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
542 target, size, data, usage);
543
544 if(size < 0)
545 {
546 return error(GL_INVALID_VALUE);
547 }
548
549 switch(usage)
550 {
551 case GL_STREAM_DRAW:
552 case GL_STATIC_DRAW:
553 case GL_DYNAMIC_DRAW:
554 break;
555 default:
556 return error(GL_INVALID_ENUM);
557 }
558
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500559 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500560
561 if(context)
562 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500563 gl::Buffer *buffer;
Nicolas Capens264f1522015-01-09 17:21:17 -0500564
565 switch(target)
566 {
567 case GL_ARRAY_BUFFER:
568 buffer = context->getArrayBuffer();
569 break;
570 case GL_ELEMENT_ARRAY_BUFFER:
571 buffer = context->getElementArrayBuffer();
572 break;
573 default:
574 return error(GL_INVALID_ENUM);
575 }
576
577 if(!buffer)
578 {
579 return error(GL_INVALID_OPERATION);
580 }
581
582 buffer->bufferData(data, size, usage);
583 }
584}
585
Nicolas Capensa9b49372015-01-30 00:33:26 -0500586void APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
Nicolas Capens264f1522015-01-09 17:21:17 -0500587{
Nicolas Capens264f1522015-01-09 17:21:17 -0500588 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
589 target, offset, size, data);
590
591 if(size < 0 || offset < 0)
592 {
593 return error(GL_INVALID_VALUE);
594 }
595
596 if(data == NULL)
597 {
598 return;
599 }
600
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500601 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500602
603 if(context)
604 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500605 gl::Buffer *buffer;
Nicolas Capens264f1522015-01-09 17:21:17 -0500606
607 switch(target)
608 {
609 case GL_ARRAY_BUFFER:
610 buffer = context->getArrayBuffer();
611 break;
612 case GL_ELEMENT_ARRAY_BUFFER:
613 buffer = context->getElementArrayBuffer();
614 break;
615 default:
616 return error(GL_INVALID_ENUM);
617 }
618
619 if(!buffer)
620 {
621 return error(GL_INVALID_OPERATION);
622 }
623
624 if((size_t)size + offset > buffer->size())
625 {
626 return error(GL_INVALID_VALUE);
627 }
628
629 buffer->bufferSubData(data, size, offset);
630 }
631}
632
Nicolas Capensa9b49372015-01-30 00:33:26 -0500633GLenum APIENTRY glCheckFramebufferStatus(GLenum target)
Nicolas Capens264f1522015-01-09 17:21:17 -0500634{
635 TRACE("(GLenum target = 0x%X)", target);
636
Nicolas Capensa9b49372015-01-30 00:33:26 -0500637 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500638 {
639 return error(GL_INVALID_ENUM, 0);
640 }
641
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500642 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500643
644 if(context)
645 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500646 if(context->getListIndex() != 0)
647 {
648 UNIMPLEMENTED();
649 }
650
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500651 gl::Framebuffer *framebuffer = NULL;
Nicolas Capensa9b49372015-01-30 00:33:26 -0500652 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500653 {
654 framebuffer = context->getReadFramebuffer();
655 }
656 else
657 {
658 framebuffer = context->getDrawFramebuffer();
659 }
660
661 return framebuffer->completeness();
662 }
663
664 return 0;
665}
666
Nicolas Capensa9b49372015-01-30 00:33:26 -0500667void APIENTRY glClear(GLbitfield mask)
Nicolas Capens264f1522015-01-09 17:21:17 -0500668{
669 TRACE("(GLbitfield mask = %X)", mask);
670
671 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
672 {
673 return error(GL_INVALID_VALUE);
674 }
675
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500676 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500677
678 if(context)
679 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500680 if(context->getListIndex() != 0)
681 {
682 return context->listCommand(gl::newCommand(glClear, mask));
683 }
684
Nicolas Capens264f1522015-01-09 17:21:17 -0500685 context->clear(mask);
686 }
687}
688
Nicolas Capensa9b49372015-01-30 00:33:26 -0500689void APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500690{
691 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
692 red, green, blue, alpha);
693
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500694 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500695
696 if(context)
697 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500698 if(context->getListIndex() != 0)
699 {
700 UNIMPLEMENTED();
701 }
702
Nicolas Capens264f1522015-01-09 17:21:17 -0500703 context->setClearColor(red, green, blue, alpha);
704 }
705}
706
Nicolas Capensa9b49372015-01-30 00:33:26 -0500707void APIENTRY glClearDepthf(GLclampf depth)
Nicolas Capens264f1522015-01-09 17:21:17 -0500708{
709 TRACE("(GLclampf depth = %f)", depth);
710
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500711 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500712
713 if(context)
714 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500715 if(context->getListIndex() != 0)
716 {
717 UNIMPLEMENTED();
718 }
719
Nicolas Capens264f1522015-01-09 17:21:17 -0500720 context->setClearDepth(depth);
721 }
722}
723
Nicolas Capensa9b49372015-01-30 00:33:26 -0500724void APIENTRY glClearStencil(GLint s)
Nicolas Capens264f1522015-01-09 17:21:17 -0500725{
726 TRACE("(GLint s = %d)", s);
727
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500728 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500729
730 if(context)
731 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500732 if(context->getListIndex() != 0)
733 {
734 UNIMPLEMENTED();
735 }
736
Nicolas Capens264f1522015-01-09 17:21:17 -0500737 context->setClearStencil(s);
738 }
739}
740
Nicolas Capensa9b49372015-01-30 00:33:26 -0500741void APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500742{
743 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
744 red, green, blue, alpha);
745
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500746 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500747
748 if(context)
749 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500750 if(context->getListIndex() != 0)
751 {
752 UNIMPLEMENTED();
753 }
754
Nicolas Capens264f1522015-01-09 17:21:17 -0500755 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
756 }
757}
758
Nicolas Capensa9b49372015-01-30 00:33:26 -0500759void APIENTRY glCompileShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -0500760{
761 TRACE("(GLuint shader = %d)", shader);
762
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500763 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500764
765 if(context)
766 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500767 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -0500768
769 if(!shaderObject)
770 {
771 if(context->getProgram(shader))
772 {
773 return error(GL_INVALID_OPERATION);
774 }
775 else
776 {
777 return error(GL_INVALID_VALUE);
778 }
779 }
780
781 shaderObject->compile();
782 }
783}
784
Nicolas Capensa9b49372015-01-30 00:33:26 -0500785void APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -0500786 GLint border, GLsizei imageSize, const GLvoid* data)
787{
788 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
789 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
790 target, level, internalformat, width, height, border, imageSize, data);
791
792 if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
793 {
794 return error(GL_INVALID_VALUE);
795 }
796
797 switch(internalformat)
798 {
Nicolas Capens264f1522015-01-09 17:21:17 -0500799 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
800 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500801 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
802 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500803 if(!S3TC_SUPPORT)
804 {
805 return error(GL_INVALID_ENUM);
806 }
807 break;
808 case GL_DEPTH_COMPONENT:
809 case GL_DEPTH_COMPONENT16:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500810 case GL_DEPTH_COMPONENT32:
811 case GL_DEPTH_STENCIL_EXT:
812 case GL_DEPTH24_STENCIL8_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500813 return error(GL_INVALID_OPERATION);
814 default:
815 return error(GL_INVALID_ENUM);
816 }
817
818 if(border != 0)
819 {
820 return error(GL_INVALID_VALUE);
821 }
822
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500823 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500824
825 if(context)
826 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500827 if(context->getListIndex() != 0)
828 {
829 UNIMPLEMENTED();
830 }
831
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500832 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -0500833 {
834 return error(GL_INVALID_VALUE);
835 }
836
837 switch(target)
838 {
839 case GL_TEXTURE_2D:
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500840 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
841 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -0500842 {
843 return error(GL_INVALID_VALUE);
844 }
845 break;
846 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
847 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
848 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
849 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
850 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
851 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
852 if(width != height)
853 {
854 return error(GL_INVALID_VALUE);
855 }
856
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500857 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
858 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -0500859 {
860 return error(GL_INVALID_VALUE);
861 }
862 break;
863 default:
864 return error(GL_INVALID_ENUM);
865 }
866
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500867 if(imageSize != gl::ComputeCompressedSize(width, height, internalformat))
Nicolas Capens264f1522015-01-09 17:21:17 -0500868 {
869 return error(GL_INVALID_VALUE);
870 }
871
872 if(target == GL_TEXTURE_2D)
873 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500874 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -0500875
876 if(!texture)
877 {
878 return error(GL_INVALID_OPERATION);
879 }
880
881 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
882 }
883 else
884 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500885 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -0500886
887 if(!texture)
888 {
889 return error(GL_INVALID_OPERATION);
890 }
891
892 switch(target)
893 {
894 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
895 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
896 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
897 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
898 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
899 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
900 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
901 break;
902 default: UNREACHABLE();
903 }
904 }
905 }
906}
907
Nicolas Capensa9b49372015-01-30 00:33:26 -0500908void APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -0500909 GLenum format, GLsizei imageSize, const GLvoid* data)
910{
911 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
912 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
913 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
914 target, level, xoffset, yoffset, width, height, format, imageSize, data);
915
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500916 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -0500917 {
918 return error(GL_INVALID_ENUM);
919 }
920
921 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
922 {
923 return error(GL_INVALID_VALUE);
924 }
925
926 switch(format)
927 {
Nicolas Capens264f1522015-01-09 17:21:17 -0500928 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
929 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500930 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
931 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500932 if(!S3TC_SUPPORT)
933 {
934 return error(GL_INVALID_ENUM);
935 }
936 break;
937 default:
938 return error(GL_INVALID_ENUM);
939 }
940
941 if(width == 0 || height == 0 || data == NULL)
942 {
943 return;
944 }
945
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500946 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500947
948 if(context)
949 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500950 if(context->getListIndex() != 0)
951 {
952 UNIMPLEMENTED();
953 }
954
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500955 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -0500956 {
957 return error(GL_INVALID_VALUE);
958 }
959
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500960 if(imageSize != gl::ComputeCompressedSize(width, height, format))
Nicolas Capens264f1522015-01-09 17:21:17 -0500961 {
962 return error(GL_INVALID_VALUE);
963 }
964
965 if(xoffset % 4 != 0 || yoffset % 4 != 0)
966 {
967 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
968 return error(GL_INVALID_OPERATION);
969 }
970
971 if(target == GL_TEXTURE_2D)
972 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500973 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -0500974
975 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
976 {
977 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
978 }
979 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500980 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -0500981 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500982 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -0500983
984 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
985 {
986 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
987 }
988 }
989 else
990 {
991 UNREACHABLE();
992 }
993 }
994}
995
Nicolas Capensa9b49372015-01-30 00:33:26 -0500996void 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 -0500997{
998 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
999 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
1000 target, level, internalformat, x, y, width, height, border);
1001
1002 if(!validImageSize(level, width, height))
1003 {
1004 return error(GL_INVALID_VALUE);
1005 }
1006
1007 if(border != 0)
1008 {
1009 return error(GL_INVALID_VALUE);
1010 }
1011
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001012 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001013
1014 if(context)
1015 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001016 if(context->getListIndex() != 0)
1017 {
1018 UNIMPLEMENTED();
1019 }
1020
Nicolas Capens264f1522015-01-09 17:21:17 -05001021 switch(target)
1022 {
1023 case GL_TEXTURE_2D:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001024 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
1025 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -05001026 {
1027 return error(GL_INVALID_VALUE);
1028 }
1029 break;
1030 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1031 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1032 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1033 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1034 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1035 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1036 if(width != height)
1037 {
1038 return error(GL_INVALID_VALUE);
1039 }
1040
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001041 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1042 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -05001043 {
1044 return error(GL_INVALID_VALUE);
1045 }
1046 break;
1047 default:
1048 return error(GL_INVALID_ENUM);
1049 }
1050
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001051 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001052
1053 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1054 {
1055 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1056 }
1057
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001058 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capens264f1522015-01-09 17:21:17 -05001059 {
1060 return error(GL_INVALID_OPERATION);
1061 }
1062
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001063 gl::Renderbuffer *source = framebuffer->getColorbuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001064 GLenum colorbufferFormat = source->getFormat();
1065
Nicolas Capens264f1522015-01-09 17:21:17 -05001066 switch(internalformat)
1067 {
1068 case GL_ALPHA:
1069 if(colorbufferFormat != GL_ALPHA &&
1070 colorbufferFormat != GL_RGBA &&
1071 colorbufferFormat != GL_RGBA4 &&
1072 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001073 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001074 {
1075 return error(GL_INVALID_OPERATION);
1076 }
1077 break;
1078 case GL_LUMINANCE:
1079 case GL_RGB:
1080 if(colorbufferFormat != GL_RGB &&
1081 colorbufferFormat != GL_RGB565 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001082 colorbufferFormat != GL_RGB8_EXT &&
Nicolas Capens264f1522015-01-09 17:21:17 -05001083 colorbufferFormat != GL_RGBA &&
1084 colorbufferFormat != GL_RGBA4 &&
1085 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001086 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001087 {
1088 return error(GL_INVALID_OPERATION);
1089 }
1090 break;
1091 case GL_LUMINANCE_ALPHA:
1092 case GL_RGBA:
1093 if(colorbufferFormat != GL_RGBA &&
1094 colorbufferFormat != GL_RGBA4 &&
1095 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001096 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001097 {
1098 return error(GL_INVALID_OPERATION);
1099 }
1100 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001101 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1102 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05001103 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1104 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05001105 if(S3TC_SUPPORT)
1106 {
1107 return error(GL_INVALID_OPERATION);
1108 }
1109 else
1110 {
1111 return error(GL_INVALID_ENUM);
1112 }
1113 default:
1114 return error(GL_INVALID_ENUM);
1115 }
1116
1117 if(target == GL_TEXTURE_2D)
1118 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001119 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05001120
1121 if(!texture)
1122 {
1123 return error(GL_INVALID_OPERATION);
1124 }
1125
1126 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
1127 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001128 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05001129 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001130 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05001131
1132 if(!texture)
1133 {
1134 return error(GL_INVALID_OPERATION);
1135 }
1136
1137 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
1138 }
1139 else UNREACHABLE();
1140 }
1141}
1142
Nicolas Capensa9b49372015-01-30 00:33:26 -05001143void 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 -05001144{
1145 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1146 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
1147 target, level, xoffset, yoffset, x, y, width, height);
1148
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001149 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05001150 {
1151 return error(GL_INVALID_ENUM);
1152 }
1153
1154 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
1155 {
1156 return error(GL_INVALID_VALUE);
1157 }
1158
1159 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1160 {
1161 return error(GL_INVALID_VALUE);
1162 }
1163
1164 if(width == 0 || height == 0)
1165 {
1166 return;
1167 }
1168
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001169 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001170
1171 if(context)
1172 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001173 if(context->getListIndex() != 0)
1174 {
1175 UNIMPLEMENTED();
1176 }
1177
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001178 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -05001179 {
1180 return error(GL_INVALID_VALUE);
1181 }
1182
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001183 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001184
1185 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1186 {
1187 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1188 }
1189
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001190 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capens264f1522015-01-09 17:21:17 -05001191 {
1192 return error(GL_INVALID_OPERATION);
1193 }
1194
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001195 gl::Renderbuffer *source = framebuffer->getColorbuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001196 GLenum colorbufferFormat = source->getFormat();
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001197 gl::Texture *texture = NULL;
Nicolas Capens264f1522015-01-09 17:21:17 -05001198
1199 if(target == GL_TEXTURE_2D)
1200 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001201 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05001202 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001203 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05001204 {
1205 texture = context->getTextureCubeMap();
1206 }
1207 else UNREACHABLE();
1208
1209 if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))
1210 {
1211 return;
1212 }
1213
1214 GLenum textureFormat = texture->getFormat(target, level);
1215
Nicolas Capens264f1522015-01-09 17:21:17 -05001216 switch(textureFormat)
1217 {
1218 case GL_ALPHA:
1219 if(colorbufferFormat != GL_ALPHA &&
1220 colorbufferFormat != GL_RGBA &&
1221 colorbufferFormat != GL_RGBA4 &&
1222 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001223 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001224 {
1225 return error(GL_INVALID_OPERATION);
1226 }
1227 break;
1228 case GL_LUMINANCE:
1229 case GL_RGB:
1230 if(colorbufferFormat != GL_RGB &&
1231 colorbufferFormat != GL_RGB565 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001232 colorbufferFormat != GL_RGB8_EXT &&
Nicolas Capens264f1522015-01-09 17:21:17 -05001233 colorbufferFormat != GL_RGBA &&
1234 colorbufferFormat != GL_RGBA4 &&
1235 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001236 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001237 {
1238 return error(GL_INVALID_OPERATION);
1239 }
1240 break;
1241 case GL_LUMINANCE_ALPHA:
1242 case GL_RGBA:
1243 if(colorbufferFormat != GL_RGBA &&
1244 colorbufferFormat != GL_RGBA4 &&
1245 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001246 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001247 {
1248 return error(GL_INVALID_OPERATION);
1249 }
1250 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001251 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1252 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05001253 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1254 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1255 return error(GL_INVALID_OPERATION);
1256 case GL_DEPTH_COMPONENT:
1257 case GL_DEPTH_STENCIL_EXT:
1258 return error(GL_INVALID_OPERATION);
1259 case GL_BGRA_EXT:
1260 if(colorbufferFormat != GL_RGB8)
Nicolas Capens264f1522015-01-09 17:21:17 -05001261 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001262 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05001263 return error(GL_INVALID_OPERATION);
1264 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05001265 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001266 default:
1267 return error(GL_INVALID_ENUM);
1268 }
1269
1270 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
1271 }
1272}
1273
Nicolas Capensa9b49372015-01-30 00:33:26 -05001274GLuint APIENTRY glCreateProgram(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05001275{
1276 TRACE("()");
1277
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001278 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001279
1280 if(context)
1281 {
1282 return context->createProgram();
1283 }
1284
1285 return 0;
1286}
1287
Nicolas Capensa9b49372015-01-30 00:33:26 -05001288GLuint APIENTRY glCreateShader(GLenum type)
Nicolas Capens264f1522015-01-09 17:21:17 -05001289{
1290 TRACE("(GLenum type = 0x%X)", type);
1291
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001292 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001293
1294 if(context)
1295 {
1296 switch(type)
1297 {
1298 case GL_FRAGMENT_SHADER:
1299 case GL_VERTEX_SHADER:
1300 return context->createShader(type);
1301 default:
1302 return error(GL_INVALID_ENUM, 0);
1303 }
1304 }
1305
1306 return 0;
1307}
1308
Nicolas Capensa9b49372015-01-30 00:33:26 -05001309void APIENTRY glCullFace(GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05001310{
1311 TRACE("(GLenum mode = 0x%X)", mode);
1312
1313 switch(mode)
1314 {
1315 case GL_FRONT:
1316 case GL_BACK:
1317 case GL_FRONT_AND_BACK:
1318 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001319 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001320
1321 if(context)
1322 {
1323 context->setCullMode(mode);
1324 }
1325 }
1326 break;
1327 default:
1328 return error(GL_INVALID_ENUM);
1329 }
1330}
1331
Nicolas Capensa9b49372015-01-30 00:33:26 -05001332void APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05001333{
1334 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
1335
1336 if(n < 0)
1337 {
1338 return error(GL_INVALID_VALUE);
1339 }
1340
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001341 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001342
1343 if(context)
1344 {
1345 for(int i = 0; i < n; i++)
1346 {
1347 context->deleteBuffer(buffers[i]);
1348 }
1349 }
1350}
1351
Nicolas Capensa9b49372015-01-30 00:33:26 -05001352void APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
Nicolas Capens264f1522015-01-09 17:21:17 -05001353{
1354 TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
1355
1356 if(n < 0)
1357 {
1358 return error(GL_INVALID_VALUE);
1359 }
1360
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001361 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001362
1363 if(context)
1364 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001365 if(context->getListIndex() != 0)
1366 {
1367 UNIMPLEMENTED();
1368 }
1369
Nicolas Capens264f1522015-01-09 17:21:17 -05001370 for(int i = 0; i < n; i++)
1371 {
1372 context->deleteFence(fences[i]);
1373 }
1374 }
1375}
1376
Nicolas Capensa9b49372015-01-30 00:33:26 -05001377void APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05001378{
1379 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
1380
1381 if(n < 0)
1382 {
1383 return error(GL_INVALID_VALUE);
1384 }
1385
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001386 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001387
1388 if(context)
1389 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001390 if(context->getListIndex() != 0)
1391 {
1392 UNIMPLEMENTED();
1393 }
1394
Nicolas Capens264f1522015-01-09 17:21:17 -05001395 for(int i = 0; i < n; i++)
1396 {
1397 if(framebuffers[i] != 0)
1398 {
1399 context->deleteFramebuffer(framebuffers[i]);
1400 }
1401 }
1402 }
1403}
1404
Nicolas Capensa9b49372015-01-30 00:33:26 -05001405void APIENTRY glDeleteProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05001406{
1407 TRACE("(GLuint program = %d)", program);
1408
1409 if(program == 0)
1410 {
1411 return;
1412 }
1413
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001414 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001415
1416 if(context)
1417 {
1418 if(!context->getProgram(program))
1419 {
1420 if(context->getShader(program))
1421 {
1422 return error(GL_INVALID_OPERATION);
1423 }
1424 else
1425 {
1426 return error(GL_INVALID_VALUE);
1427 }
1428 }
1429
1430 context->deleteProgram(program);
1431 }
1432}
1433
Nicolas Capensa9b49372015-01-30 00:33:26 -05001434void APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
Nicolas Capens264f1522015-01-09 17:21:17 -05001435{
1436 TRACE("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
1437
1438 if(n < 0)
1439 {
1440 return error(GL_INVALID_VALUE);
1441 }
1442
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001443 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001444
1445 if(context)
1446 {
1447 for(int i = 0; i < n; i++)
1448 {
1449 context->deleteQuery(ids[i]);
1450 }
1451 }
1452}
1453
Nicolas Capensa9b49372015-01-30 00:33:26 -05001454void APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05001455{
1456 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
1457
1458 if(n < 0)
1459 {
1460 return error(GL_INVALID_VALUE);
1461 }
1462
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001463 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001464
1465 if(context)
1466 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001467 if(context->getListIndex() != 0)
1468 {
1469 UNIMPLEMENTED();
1470 }
1471
Nicolas Capens264f1522015-01-09 17:21:17 -05001472 for(int i = 0; i < n; i++)
1473 {
1474 context->deleteRenderbuffer(renderbuffers[i]);
1475 }
1476 }
1477}
1478
Nicolas Capensa9b49372015-01-30 00:33:26 -05001479void APIENTRY glDeleteShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05001480{
1481 TRACE("(GLuint shader = %d)", shader);
1482
1483 if(shader == 0)
1484 {
1485 return;
1486 }
1487
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001488 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001489
1490 if(context)
1491 {
1492 if(!context->getShader(shader))
1493 {
1494 if(context->getProgram(shader))
1495 {
1496 return error(GL_INVALID_OPERATION);
1497 }
1498 else
1499 {
1500 return error(GL_INVALID_VALUE);
1501 }
1502 }
1503
1504 context->deleteShader(shader);
1505 }
1506}
1507
Nicolas Capensa9b49372015-01-30 00:33:26 -05001508void APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
Nicolas Capens264f1522015-01-09 17:21:17 -05001509{
1510 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
1511
1512 if(n < 0)
1513 {
1514 return error(GL_INVALID_VALUE);
1515 }
1516
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001517 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001518
1519 if(context)
1520 {
1521 for(int i = 0; i < n; i++)
1522 {
1523 if(textures[i] != 0)
1524 {
1525 context->deleteTexture(textures[i]);
1526 }
1527 }
1528 }
1529}
1530
Nicolas Capensa9b49372015-01-30 00:33:26 -05001531void APIENTRY glDepthFunc(GLenum func)
Nicolas Capens264f1522015-01-09 17:21:17 -05001532{
1533 TRACE("(GLenum func = 0x%X)", func);
1534
1535 switch(func)
1536 {
1537 case GL_NEVER:
1538 case GL_ALWAYS:
1539 case GL_LESS:
1540 case GL_LEQUAL:
1541 case GL_EQUAL:
1542 case GL_GREATER:
1543 case GL_GEQUAL:
1544 case GL_NOTEQUAL:
1545 break;
1546 default:
1547 return error(GL_INVALID_ENUM);
1548 }
1549
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001550 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001551
1552 if(context)
1553 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001554 if(context->getListIndex() != 0)
1555 {
1556 UNIMPLEMENTED();
1557 }
1558
Nicolas Capens264f1522015-01-09 17:21:17 -05001559 context->setDepthFunc(func);
1560 }
1561}
1562
Nicolas Capensa9b49372015-01-30 00:33:26 -05001563void APIENTRY glDepthMask(GLboolean flag)
Nicolas Capens264f1522015-01-09 17:21:17 -05001564{
1565 TRACE("(GLboolean flag = %d)", flag);
1566
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001567 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001568
1569 if(context)
1570 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001571 if(context->getListIndex() != 0)
1572 {
1573 UNIMPLEMENTED();
1574 }
1575
Nicolas Capens264f1522015-01-09 17:21:17 -05001576 context->setDepthMask(flag != GL_FALSE);
1577 }
1578}
1579
Nicolas Capensa9b49372015-01-30 00:33:26 -05001580void APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
Nicolas Capens264f1522015-01-09 17:21:17 -05001581{
1582 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
1583
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001584 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001585
1586 if(context)
1587 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001588 if(context->getListIndex() != 0)
1589 {
1590 UNIMPLEMENTED();
1591 }
1592
Nicolas Capens264f1522015-01-09 17:21:17 -05001593 context->setDepthRange(zNear, zFar);
1594 }
1595}
1596
Nicolas Capensa9b49372015-01-30 00:33:26 -05001597void APIENTRY glDetachShader(GLuint program, GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05001598{
1599 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
1600
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001601 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001602
1603 if(context)
1604 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001605 gl::Program *programObject = context->getProgram(program);
1606 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05001607
1608 if(!programObject)
1609 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001610 gl::Shader *shaderByProgramHandle;
Nicolas Capens264f1522015-01-09 17:21:17 -05001611 shaderByProgramHandle = context->getShader(program);
1612 if(!shaderByProgramHandle)
1613 {
1614 return error(GL_INVALID_VALUE);
1615 }
1616 else
1617 {
1618 return error(GL_INVALID_OPERATION);
1619 }
1620 }
1621
1622 if(!shaderObject)
1623 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001624 gl::Program *programByShaderHandle = context->getProgram(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05001625 if(!programByShaderHandle)
1626 {
1627 return error(GL_INVALID_VALUE);
1628 }
1629 else
1630 {
1631 return error(GL_INVALID_OPERATION);
1632 }
1633 }
1634
1635 if(!programObject->detachShader(shaderObject))
1636 {
1637 return error(GL_INVALID_OPERATION);
1638 }
1639 }
1640}
1641
Nicolas Capensa9b49372015-01-30 00:33:26 -05001642void APIENTRY glDisable(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05001643{
1644 TRACE("(GLenum cap = 0x%X)", cap);
1645
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001646 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001647
1648 if(context)
1649 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001650 if(context->getListIndex() != 0)
1651 {
1652 UNIMPLEMENTED();
1653 }
1654
Nicolas Capens264f1522015-01-09 17:21:17 -05001655 switch(cap)
1656 {
1657 case GL_CULL_FACE: context->setCullFace(false); break;
1658 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1659 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1660 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1661 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1662 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1663 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1664 case GL_BLEND: context->setBlend(false); break;
1665 case GL_DITHER: context->setDither(false); break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05001666 case GL_LIGHTING: context->setLighting(false); break;
1667 case GL_FOG: context->setFog(false); break;
1668 case GL_ALPHA_TEST: context->setAlphaTest(false); break;
1669 case GL_TEXTURE_2D: context->setTexture2D(false); break;
1670 case GL_LIGHT0: context->setLight(0, false); break;
1671 case GL_LIGHT1: context->setLight(1, false); break;
1672 case GL_LIGHT2: context->setLight(2, false); break;
1673 case GL_LIGHT3: context->setLight(3, false); break;
1674 case GL_LIGHT4: context->setLight(4, false); break;
1675 case GL_LIGHT5: context->setLight(5, false); break;
1676 case GL_LIGHT6: context->setLight(6, false); break;
1677 case GL_LIGHT7: context->setLight(7, false); break;
1678 case GL_COLOR_MATERIAL: context->setColorMaterial(false); break;
1679 case GL_RESCALE_NORMAL: context->setNormalizeNormals(false); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001680 default:
1681 return error(GL_INVALID_ENUM);
1682 }
1683 }
1684}
1685
Nicolas Capensa9b49372015-01-30 00:33:26 -05001686void APIENTRY glDisableVertexAttribArray(GLuint index)
Nicolas Capens264f1522015-01-09 17:21:17 -05001687{
1688 TRACE("(GLuint index = %d)", index);
1689
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001690 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05001691 {
1692 return error(GL_INVALID_VALUE);
1693 }
1694
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001695 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001696
1697 if(context)
1698 {
1699 context->setEnableVertexAttribArray(index, false);
1700 }
1701}
1702
Nicolas Capensa9b49372015-01-30 00:33:26 -05001703void APIENTRY glCaptureAttribs()
1704{
1705 TRACE("()");
1706
1707 gl::Context *context = gl::getContext();
1708
1709 if(context)
1710 {
1711 context->captureAttribs();
1712 }
1713}
1714
1715void APIENTRY glRestoreAttribs()
1716{
1717 TRACE("()");
1718
1719 gl::Context *context = gl::getContext();
1720
1721 if(context)
1722 {
1723 context->restoreAttribs();
1724 }
1725}
1726
1727void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
Nicolas Capens264f1522015-01-09 17:21:17 -05001728{
1729 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
1730
1731 if(count < 0 || first < 0)
1732 {
1733 return error(GL_INVALID_VALUE);
1734 }
1735
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001736 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001737
1738 if(context)
1739 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001740 if(context->getListIndex() != 0)
1741 {
1742 ASSERT(context->getListMode() != GL_COMPILE_AND_EXECUTE); // UNIMPLEMENTED!
1743
1744 context->listCommand(gl::newCommand(glCaptureAttribs));
1745 context->captureDrawArrays(mode, first, count);
1746 context->listCommand(gl::newCommand(glDrawArrays, mode, first, count));
1747 context->listCommand(gl::newCommand(glRestoreAttribs));
1748
1749 return;
1750 }
1751
Nicolas Capens264f1522015-01-09 17:21:17 -05001752 context->drawArrays(mode, first, count);
1753 }
1754}
1755
Nicolas Capensa9b49372015-01-30 00:33:26 -05001756void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
Nicolas Capens264f1522015-01-09 17:21:17 -05001757{
1758 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
1759 mode, count, type, indices);
1760
1761 if(count < 0)
1762 {
1763 return error(GL_INVALID_VALUE);
1764 }
1765
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001766 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001767
1768 if(context)
1769 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001770 if(context->getListIndex() != 0)
1771 {
1772 UNIMPLEMENTED();
1773 }
1774
Nicolas Capens264f1522015-01-09 17:21:17 -05001775 switch(type)
1776 {
1777 case GL_UNSIGNED_BYTE:
1778 case GL_UNSIGNED_SHORT:
1779 case GL_UNSIGNED_INT:
1780 break;
1781 default:
1782 return error(GL_INVALID_ENUM);
1783 }
1784
1785 context->drawElements(mode, count, type, indices);
1786 }
1787}
1788
Nicolas Capensa9b49372015-01-30 00:33:26 -05001789void APIENTRY glEnable(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05001790{
1791 TRACE("(GLenum cap = 0x%X)", cap);
1792
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001793 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001794
1795 if(context)
1796 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001797 if(context->getListIndex() != 0)
1798 {
1799 UNIMPLEMENTED();
1800 }
1801
Nicolas Capens264f1522015-01-09 17:21:17 -05001802 switch(cap)
1803 {
1804 case GL_CULL_FACE: context->setCullFace(true); break;
1805 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1806 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1807 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1808 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1809 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1810 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1811 case GL_BLEND: context->setBlend(true); break;
1812 case GL_DITHER: context->setDither(true); break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05001813 case GL_TEXTURE_2D: context->setTexture2D(true); break;
1814 case GL_ALPHA_TEST: context->setAlphaTest(true); break;
1815 case GL_COLOR_MATERIAL: context->setColorMaterial(true); break;
1816 case GL_FOG: context->setFog(true); break;
1817 case GL_LIGHTING: context->setLighting(true); break;
1818 case GL_LIGHT0: context->setLight(0, true); break;
1819 case GL_LIGHT1: context->setLight(1, true); break;
1820 case GL_LIGHT2: context->setLight(2, true); break;
1821 case GL_LIGHT3: context->setLight(3, true); break;
1822 case GL_LIGHT4: context->setLight(4, true); break;
1823 case GL_LIGHT5: context->setLight(5, true); break;
1824 case GL_LIGHT6: context->setLight(6, true); break;
1825 case GL_LIGHT7: context->setLight(7, true); break;
1826 case GL_RESCALE_NORMAL: context->setNormalizeNormals(true); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001827 default:
1828 return error(GL_INVALID_ENUM);
1829 }
1830 }
1831}
1832
Nicolas Capensa9b49372015-01-30 00:33:26 -05001833void APIENTRY glEnableVertexAttribArray(GLuint index)
Nicolas Capens264f1522015-01-09 17:21:17 -05001834{
1835 TRACE("(GLuint index = %d)", index);
1836
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001837 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05001838 {
1839 return error(GL_INVALID_VALUE);
1840 }
1841
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001842 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001843
1844 if(context)
1845 {
1846 context->setEnableVertexAttribArray(index, true);
1847 }
1848}
1849
Nicolas Capensa9b49372015-01-30 00:33:26 -05001850void APIENTRY glEndQueryEXT(GLenum target)
Nicolas Capens264f1522015-01-09 17:21:17 -05001851{
1852 TRACE("GLenum target = 0x%X)", target);
1853
1854 switch(target)
1855 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001856 case GL_ANY_SAMPLES_PASSED:
1857 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
Nicolas Capens264f1522015-01-09 17:21:17 -05001858 break;
1859 default:
1860 return error(GL_INVALID_ENUM);
1861 }
1862
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001863 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001864
1865 if(context)
1866 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001867 if(context->getListIndex() != 0)
1868 {
1869 UNIMPLEMENTED();
1870 }
1871
Nicolas Capens264f1522015-01-09 17:21:17 -05001872 context->endQuery(target);
1873 }
1874}
1875
Nicolas Capensa9b49372015-01-30 00:33:26 -05001876void APIENTRY glFinishFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05001877{
1878 TRACE("(GLuint fence = %d)", fence);
1879
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001880 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001881
1882 if(context)
1883 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001884 if(context->getListIndex() != 0)
1885 {
1886 UNIMPLEMENTED();
1887 }
1888
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001889 gl::Fence* fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05001890
1891 if(fenceObject == NULL)
1892 {
1893 return error(GL_INVALID_OPERATION);
1894 }
1895
1896 fenceObject->finishFence();
1897 }
1898}
1899
Nicolas Capensa9b49372015-01-30 00:33:26 -05001900void APIENTRY glFinish(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05001901{
1902 TRACE("()");
1903
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001904 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001905
1906 if(context)
1907 {
1908 context->finish();
1909 }
1910}
1911
Nicolas Capensa9b49372015-01-30 00:33:26 -05001912void APIENTRY glFlush(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05001913{
1914 TRACE("()");
1915
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001916 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001917
1918 if(context)
1919 {
1920 context->flush();
1921 }
1922}
1923
Nicolas Capensa9b49372015-01-30 00:33:26 -05001924void APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05001925{
1926 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1927 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
1928
Nicolas Capensa9b49372015-01-30 00:33:26 -05001929 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT) ||
Nicolas Capens264f1522015-01-09 17:21:17 -05001930 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
1931 {
1932 return error(GL_INVALID_ENUM);
1933 }
1934
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001935 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001936
1937 if(context)
1938 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001939 if(context->getListIndex() != 0)
1940 {
1941 UNIMPLEMENTED();
1942 }
1943
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001944 gl::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001945 GLuint framebufferName = 0;
Nicolas Capensa9b49372015-01-30 00:33:26 -05001946 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001947 {
1948 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001949 framebufferName = context->getReadFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05001950 }
1951 else
1952 {
1953 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001954 framebufferName = context->getDrawFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05001955 }
1956
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001957 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
Nicolas Capens264f1522015-01-09 17:21:17 -05001958 {
1959 return error(GL_INVALID_OPERATION);
1960 }
1961
1962 switch(attachment)
1963 {
1964 case GL_COLOR_ATTACHMENT0:
1965 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1966 break;
1967 case GL_DEPTH_ATTACHMENT:
1968 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1969 break;
1970 case GL_STENCIL_ATTACHMENT:
1971 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1972 break;
1973 default:
1974 return error(GL_INVALID_ENUM);
1975 }
1976 }
1977}
1978
Nicolas Capensa9b49372015-01-30 00:33:26 -05001979void APIENTRY glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1980{
1981 UNIMPLEMENTED();
1982}
1983
1984void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
Nicolas Capens264f1522015-01-09 17:21:17 -05001985{
1986 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1987 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
1988
Nicolas Capensa9b49372015-01-30 00:33:26 -05001989 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001990 {
1991 return error(GL_INVALID_ENUM);
1992 }
1993
1994 switch(attachment)
1995 {
1996 case GL_COLOR_ATTACHMENT0:
1997 case GL_DEPTH_ATTACHMENT:
1998 case GL_STENCIL_ATTACHMENT:
1999 break;
2000 default:
2001 return error(GL_INVALID_ENUM);
2002 }
2003
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002004 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002005
2006 if(context)
2007 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002008 if(context->getListIndex() != 0)
2009 {
2010 UNIMPLEMENTED();
2011 }
2012
Nicolas Capens264f1522015-01-09 17:21:17 -05002013 if(texture == 0)
2014 {
2015 textarget = GL_NONE;
2016 }
2017 else
2018 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002019 gl::Texture *tex = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -05002020
2021 if(tex == NULL)
2022 {
2023 return error(GL_INVALID_OPERATION);
2024 }
2025
2026 if(tex->isCompressed(textarget, level))
2027 {
2028 return error(GL_INVALID_OPERATION);
2029 }
2030
2031 switch(textarget)
2032 {
2033 case GL_TEXTURE_2D:
2034 if(tex->getTarget() != GL_TEXTURE_2D)
2035 {
2036 return error(GL_INVALID_OPERATION);
2037 }
2038 break;
2039 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2040 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2041 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2042 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2043 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2044 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2045 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2046 {
2047 return error(GL_INVALID_OPERATION);
2048 }
2049 break;
2050 default:
2051 return error(GL_INVALID_ENUM);
2052 }
2053
2054 if(level != 0)
2055 {
2056 return error(GL_INVALID_VALUE);
2057 }
2058 }
2059
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002060 gl::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002061 GLuint framebufferName = 0;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002062 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05002063 {
2064 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002065 framebufferName = context->getReadFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002066 }
2067 else
2068 {
2069 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002070 framebufferName = context->getDrawFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002071 }
2072
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002073 if(framebufferName == 0 || !framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05002074 {
2075 return error(GL_INVALID_OPERATION);
2076 }
2077
2078 switch(attachment)
2079 {
2080 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2081 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2082 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2083 }
2084 }
2085}
2086
Nicolas Capensa9b49372015-01-30 00:33:26 -05002087void APIENTRY glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
2088{
2089 UNIMPLEMENTED();
2090}
2091
2092void APIENTRY glFrontFace(GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05002093{
2094 TRACE("(GLenum mode = 0x%X)", mode);
2095
2096 switch(mode)
2097 {
2098 case GL_CW:
2099 case GL_CCW:
2100 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002101 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002102
2103 if(context)
2104 {
2105 context->setFrontFace(mode);
2106 }
2107 }
2108 break;
2109 default:
2110 return error(GL_INVALID_ENUM);
2111 }
2112}
2113
Nicolas Capensa9b49372015-01-30 00:33:26 -05002114void APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05002115{
2116 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
2117
2118 if(n < 0)
2119 {
2120 return error(GL_INVALID_VALUE);
2121 }
2122
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002123 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002124
2125 if(context)
2126 {
2127 for(int i = 0; i < n; i++)
2128 {
2129 buffers[i] = context->createBuffer();
2130 }
2131 }
2132}
2133
Nicolas Capensa9b49372015-01-30 00:33:26 -05002134void APIENTRY glGenerateMipmap(GLenum target)
Nicolas Capens264f1522015-01-09 17:21:17 -05002135{
2136 TRACE("(GLenum target = 0x%X)", target);
2137
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002138 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002139
2140 if(context)
2141 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002142 if(context->getListIndex() != 0)
2143 {
2144 UNIMPLEMENTED();
2145 }
2146
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002147 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05002148
2149 switch(target)
2150 {
2151 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05002152 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05002153 break;
2154 case GL_TEXTURE_CUBE_MAP:
2155 texture = context->getTextureCubeMap();
2156 break;
2157 default:
2158 return error(GL_INVALID_ENUM);
2159 }
2160
2161 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2162 {
2163 return error(GL_INVALID_OPERATION);
2164 }
2165
2166 texture->generateMipmaps();
2167 }
2168}
2169
Nicolas Capensa9b49372015-01-30 00:33:26 -05002170void APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
Nicolas Capens264f1522015-01-09 17:21:17 -05002171{
2172 TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
2173
2174 if(n < 0)
2175 {
2176 return error(GL_INVALID_VALUE);
2177 }
2178
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002179 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002180
2181 if(context)
2182 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002183 if(context->getListIndex() != 0)
2184 {
2185 UNIMPLEMENTED();
2186 }
2187
Nicolas Capens264f1522015-01-09 17:21:17 -05002188 for(int i = 0; i < n; i++)
2189 {
2190 fences[i] = context->createFence();
2191 }
2192 }
2193}
2194
Nicolas Capensa9b49372015-01-30 00:33:26 -05002195void APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05002196{
2197 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
2198
2199 if(n < 0)
2200 {
2201 return error(GL_INVALID_VALUE);
2202 }
2203
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002204 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002205
2206 if(context)
2207 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002208 if(context->getListIndex() != 0)
2209 {
2210 UNIMPLEMENTED();
2211 }
2212
Nicolas Capens264f1522015-01-09 17:21:17 -05002213 for(int i = 0; i < n; i++)
2214 {
2215 framebuffers[i] = context->createFramebuffer();
2216 }
2217 }
2218}
2219
Nicolas Capensa9b49372015-01-30 00:33:26 -05002220void APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
Nicolas Capens264f1522015-01-09 17:21:17 -05002221{
2222 TRACE("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
2223
2224 if(n < 0)
2225 {
2226 return error(GL_INVALID_VALUE);
2227 }
2228
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002229 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002230
2231 if(context)
2232 {
2233 for(int i = 0; i < n; i++)
2234 {
2235 ids[i] = context->createQuery();
2236 }
2237 }
2238}
2239
Nicolas Capensa9b49372015-01-30 00:33:26 -05002240void APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05002241{
2242 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
2243
2244 if(n < 0)
2245 {
2246 return error(GL_INVALID_VALUE);
2247 }
2248
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002249 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002250
2251 if(context)
2252 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002253 if(context->getListIndex() != 0)
2254 {
2255 UNIMPLEMENTED();
2256 }
2257
Nicolas Capens264f1522015-01-09 17:21:17 -05002258 for(int i = 0; i < n; i++)
2259 {
2260 renderbuffers[i] = context->createRenderbuffer();
2261 }
2262 }
2263}
2264
Nicolas Capensa9b49372015-01-30 00:33:26 -05002265void APIENTRY glGenTextures(GLsizei n, GLuint* textures)
Nicolas Capens264f1522015-01-09 17:21:17 -05002266{
2267 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
2268
2269 if(n < 0)
2270 {
2271 return error(GL_INVALID_VALUE);
2272 }
2273
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002274 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002275
2276 if(context)
2277 {
2278 for(int i = 0; i < n; i++)
2279 {
2280 textures[i] = context->createTexture();
2281 }
2282 }
2283}
2284
Nicolas Capensa9b49372015-01-30 00:33:26 -05002285void APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002286{
2287 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2288 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
2289 program, index, bufsize, length, size, type, name);
2290
2291 if(bufsize < 0)
2292 {
2293 return error(GL_INVALID_VALUE);
2294 }
2295
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002296 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002297
2298 if(context)
2299 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002300 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002301
2302 if(!programObject)
2303 {
2304 if(context->getShader(program))
2305 {
2306 return error(GL_INVALID_OPERATION);
2307 }
2308 else
2309 {
2310 return error(GL_INVALID_VALUE);
2311 }
2312 }
2313
2314 if(index >= (GLuint)programObject->getActiveAttributeCount())
2315 {
2316 return error(GL_INVALID_VALUE);
2317 }
2318
2319 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2320 }
2321}
2322
Nicolas Capensa9b49372015-01-30 00:33:26 -05002323void APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002324{
2325 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
2326 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = %s)",
2327 program, index, bufsize, length, size, type, name);
2328
2329 if(bufsize < 0)
2330 {
2331 return error(GL_INVALID_VALUE);
2332 }
2333
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002334 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002335
2336 if(context)
2337 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002338 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002339
2340 if(!programObject)
2341 {
2342 if(context->getShader(program))
2343 {
2344 return error(GL_INVALID_OPERATION);
2345 }
2346 else
2347 {
2348 return error(GL_INVALID_VALUE);
2349 }
2350 }
2351
2352 if(index >= (GLuint)programObject->getActiveUniformCount())
2353 {
2354 return error(GL_INVALID_VALUE);
2355 }
2356
2357 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2358 }
2359}
2360
Nicolas Capensa9b49372015-01-30 00:33:26 -05002361void APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
Nicolas Capens264f1522015-01-09 17:21:17 -05002362{
2363 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2364 program, maxcount, count, shaders);
2365
2366 if(maxcount < 0)
2367 {
2368 return error(GL_INVALID_VALUE);
2369 }
2370
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002371 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002372
2373 if(context)
2374 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002375 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002376
2377 if(!programObject)
2378 {
2379 if(context->getShader(program))
2380 {
2381 return error(GL_INVALID_OPERATION);
2382 }
2383 else
2384 {
2385 return error(GL_INVALID_VALUE);
2386 }
2387 }
2388
2389 return programObject->getAttachedShaders(maxcount, count, shaders);
2390 }
2391}
2392
Nicolas Capensa9b49372015-01-30 00:33:26 -05002393int APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002394{
2395 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
2396
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002397 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002398
2399 if(context)
2400 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002401 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002402
2403 if(!programObject)
2404 {
2405 if(context->getShader(program))
2406 {
2407 return error(GL_INVALID_OPERATION, -1);
2408 }
2409 else
2410 {
2411 return error(GL_INVALID_VALUE, -1);
2412 }
2413 }
2414
2415 if(!programObject->isLinked())
2416 {
2417 return error(GL_INVALID_OPERATION, -1);
2418 }
2419
2420 return programObject->getAttributeLocation(name);
2421 }
2422
2423 return -1;
2424}
2425
Nicolas Capensa9b49372015-01-30 00:33:26 -05002426void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002427{
2428 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
2429
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002430 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002431
2432 if(context)
2433 {
2434 if(!(context->getBooleanv(pname, params)))
2435 {
2436 GLenum nativeType;
2437 unsigned int numParams = 0;
2438 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2439 return error(GL_INVALID_ENUM);
2440
2441 if(numParams == 0)
2442 return; // it is known that the pname is valid, but there are no parameters to return
2443
2444 if(nativeType == GL_FLOAT)
2445 {
2446 GLfloat *floatParams = NULL;
2447 floatParams = new GLfloat[numParams];
2448
2449 context->getFloatv(pname, floatParams);
2450
2451 for(unsigned int i = 0; i < numParams; ++i)
2452 {
2453 if(floatParams[i] == 0.0f)
2454 params[i] = GL_FALSE;
2455 else
2456 params[i] = GL_TRUE;
2457 }
2458
2459 delete [] floatParams;
2460 }
2461 else if(nativeType == GL_INT)
2462 {
2463 GLint *intParams = NULL;
2464 intParams = new GLint[numParams];
2465
2466 context->getIntegerv(pname, intParams);
2467
2468 for(unsigned int i = 0; i < numParams; ++i)
2469 {
2470 if(intParams[i] == 0)
2471 params[i] = GL_FALSE;
2472 else
2473 params[i] = GL_TRUE;
2474 }
2475
2476 delete [] intParams;
2477 }
2478 }
2479 }
2480}
2481
Nicolas Capensa9b49372015-01-30 00:33:26 -05002482void APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002483{
2484 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
2485
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002486 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002487
2488 if(context)
2489 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002490 gl::Buffer *buffer;
Nicolas Capens264f1522015-01-09 17:21:17 -05002491
2492 switch(target)
2493 {
2494 case GL_ARRAY_BUFFER:
2495 buffer = context->getArrayBuffer();
2496 break;
2497 case GL_ELEMENT_ARRAY_BUFFER:
2498 buffer = context->getElementArrayBuffer();
2499 break;
2500 default:
2501 return error(GL_INVALID_ENUM);
2502 }
2503
2504 if(!buffer)
2505 {
2506 // A null buffer means that "0" is bound to the requested buffer target
2507 return error(GL_INVALID_OPERATION);
2508 }
2509
2510 switch(pname)
2511 {
2512 case GL_BUFFER_USAGE:
2513 *params = buffer->usage();
2514 break;
2515 case GL_BUFFER_SIZE:
2516 *params = buffer->size();
2517 break;
2518 default:
2519 return error(GL_INVALID_ENUM);
2520 }
2521 }
2522}
2523
Nicolas Capensa9b49372015-01-30 00:33:26 -05002524GLenum APIENTRY glGetError(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05002525{
2526 TRACE("()");
2527
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002528 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002529
2530 if(context)
2531 {
2532 return context->getError();
2533 }
2534
2535 return GL_NO_ERROR;
2536}
2537
Nicolas Capensa9b49372015-01-30 00:33:26 -05002538void APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002539{
2540 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
2541
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002542 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002543
2544 if(context)
2545 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002546 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05002547
2548 if(fenceObject == NULL)
2549 {
2550 return error(GL_INVALID_OPERATION);
2551 }
2552
2553 fenceObject->getFenceiv(pname, params);
2554 }
2555}
2556
Nicolas Capensa9b49372015-01-30 00:33:26 -05002557void APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002558{
2559 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
2560
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002561 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002562
2563 if(context)
2564 {
2565 if(!(context->getFloatv(pname, params)))
2566 {
2567 GLenum nativeType;
2568 unsigned int numParams = 0;
2569 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2570 return error(GL_INVALID_ENUM);
2571
2572 if(numParams == 0)
2573 return; // it is known that the pname is valid, but that there are no parameters to return.
2574
2575 if(nativeType == GL_BOOL)
2576 {
2577 GLboolean *boolParams = NULL;
2578 boolParams = new GLboolean[numParams];
2579
2580 context->getBooleanv(pname, boolParams);
2581
2582 for(unsigned int i = 0; i < numParams; ++i)
2583 {
2584 if(boolParams[i] == GL_FALSE)
2585 params[i] = 0.0f;
2586 else
2587 params[i] = 1.0f;
2588 }
2589
2590 delete [] boolParams;
2591 }
2592 else if(nativeType == GL_INT)
2593 {
2594 GLint *intParams = NULL;
2595 intParams = new GLint[numParams];
2596
2597 context->getIntegerv(pname, intParams);
2598
2599 for(unsigned int i = 0; i < numParams; ++i)
2600 {
2601 params[i] = (GLfloat)intParams[i];
2602 }
2603
2604 delete [] intParams;
2605 }
2606 }
2607 }
2608}
2609
Nicolas Capensa9b49372015-01-30 00:33:26 -05002610void APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002611{
2612 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2613 target, attachment, pname, params);
2614
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002615 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002616
2617 if(context)
2618 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002619 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05002620 {
2621 return error(GL_INVALID_ENUM);
2622 }
2623
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002624 gl::Framebuffer *framebuffer = NULL;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002625 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05002626 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002627 if(context->getReadFramebufferName() == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05002628 {
2629 return error(GL_INVALID_OPERATION);
2630 }
2631
2632 framebuffer = context->getReadFramebuffer();
2633 }
2634 else
2635 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002636 if(context->getDrawFramebufferName() == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05002637 {
2638 return error(GL_INVALID_OPERATION);
2639 }
2640
2641 framebuffer = context->getDrawFramebuffer();
2642 }
2643
2644 GLenum attachmentType;
2645 GLuint attachmentHandle;
2646 switch(attachment)
2647 {
2648 case GL_COLOR_ATTACHMENT0:
2649 attachmentType = framebuffer->getColorbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002650 attachmentHandle = framebuffer->getColorbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002651 break;
2652 case GL_DEPTH_ATTACHMENT:
2653 attachmentType = framebuffer->getDepthbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002654 attachmentHandle = framebuffer->getDepthbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002655 break;
2656 case GL_STENCIL_ATTACHMENT:
2657 attachmentType = framebuffer->getStencilbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002658 attachmentHandle = framebuffer->getStencilbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002659 break;
2660 default:
2661 return error(GL_INVALID_ENUM);
2662 }
2663
2664 GLenum attachmentObjectType; // Type category
2665 if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
2666 {
2667 attachmentObjectType = attachmentType;
2668 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002669 else if(gl::IsTextureTarget(attachmentType))
Nicolas Capens264f1522015-01-09 17:21:17 -05002670 {
2671 attachmentObjectType = GL_TEXTURE;
2672 }
2673 else UNREACHABLE();
2674
2675 switch(pname)
2676 {
2677 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2678 *params = attachmentObjectType;
2679 break;
2680 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2681 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2682 {
2683 *params = attachmentHandle;
2684 }
2685 else
2686 {
2687 return error(GL_INVALID_ENUM);
2688 }
2689 break;
2690 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2691 if(attachmentObjectType == GL_TEXTURE)
2692 {
2693 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2694 }
2695 else
2696 {
2697 return error(GL_INVALID_ENUM);
2698 }
2699 break;
2700 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2701 if(attachmentObjectType == GL_TEXTURE)
2702 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002703 if(gl::IsCubemapTextureTarget(attachmentType))
Nicolas Capens264f1522015-01-09 17:21:17 -05002704 {
2705 *params = attachmentType;
2706 }
2707 else
2708 {
2709 *params = 0;
2710 }
2711 }
2712 else
2713 {
2714 return error(GL_INVALID_ENUM);
2715 }
2716 break;
2717 default:
2718 return error(GL_INVALID_ENUM);
2719 }
2720 }
2721}
2722
Nicolas Capensa9b49372015-01-30 00:33:26 -05002723GLenum APIENTRY glGetGraphicsResetStatusEXT(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05002724{
2725 TRACE("()");
2726
2727 return GL_NO_ERROR;
2728}
2729
Nicolas Capensa9b49372015-01-30 00:33:26 -05002730void APIENTRY glGetIntegerv(GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002731{
2732 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
2733
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002734 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002735
2736 if(context)
2737 {
2738 if(!(context->getIntegerv(pname, params)))
2739 {
2740 GLenum nativeType;
2741 unsigned int numParams = 0;
2742 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2743 return error(GL_INVALID_ENUM);
2744
2745 if(numParams == 0)
2746 return; // it is known that pname is valid, but there are no parameters to return
2747
2748 if(nativeType == GL_BOOL)
2749 {
2750 GLboolean *boolParams = NULL;
2751 boolParams = new GLboolean[numParams];
2752
2753 context->getBooleanv(pname, boolParams);
2754
2755 for(unsigned int i = 0; i < numParams; ++i)
2756 {
2757 if(boolParams[i] == GL_FALSE)
2758 params[i] = 0;
2759 else
2760 params[i] = 1;
2761 }
2762
2763 delete [] boolParams;
2764 }
2765 else if(nativeType == GL_FLOAT)
2766 {
2767 GLfloat *floatParams = NULL;
2768 floatParams = new GLfloat[numParams];
2769
2770 context->getFloatv(pname, floatParams);
2771
2772 for(unsigned int i = 0; i < numParams; ++i)
2773 {
2774 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
2775 {
2776 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
2777 }
2778 else
2779 {
2780 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
2781 }
2782 }
2783
2784 delete [] floatParams;
2785 }
2786 }
2787 }
2788}
2789
Nicolas Capensa9b49372015-01-30 00:33:26 -05002790void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002791{
2792 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", program, pname, params);
2793
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002794 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002795
2796 if(context)
2797 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002798 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002799
2800 if(!programObject)
2801 {
2802 return error(GL_INVALID_VALUE);
2803 }
2804
2805 switch(pname)
2806 {
2807 case GL_DELETE_STATUS:
2808 *params = programObject->isFlaggedForDeletion();
2809 return;
2810 case GL_LINK_STATUS:
2811 *params = programObject->isLinked();
2812 return;
2813 case GL_VALIDATE_STATUS:
2814 *params = programObject->isValidated();
2815 return;
2816 case GL_INFO_LOG_LENGTH:
2817 *params = programObject->getInfoLogLength();
2818 return;
2819 case GL_ATTACHED_SHADERS:
2820 *params = programObject->getAttachedShadersCount();
2821 return;
2822 case GL_ACTIVE_ATTRIBUTES:
2823 *params = programObject->getActiveAttributeCount();
2824 return;
2825 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2826 *params = programObject->getActiveAttributeMaxLength();
2827 return;
2828 case GL_ACTIVE_UNIFORMS:
2829 *params = programObject->getActiveUniformCount();
2830 return;
2831 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2832 *params = programObject->getActiveUniformMaxLength();
2833 return;
2834 default:
2835 return error(GL_INVALID_ENUM);
2836 }
2837 }
2838}
2839
Nicolas Capensa9b49372015-01-30 00:33:26 -05002840void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
Nicolas Capens264f1522015-01-09 17:21:17 -05002841{
2842 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
2843 program, bufsize, length, infolog);
2844
2845 if(bufsize < 0)
2846 {
2847 return error(GL_INVALID_VALUE);
2848 }
2849
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002850 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002851
2852 if(context)
2853 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002854 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002855
2856 if(!programObject)
2857 {
2858 return error(GL_INVALID_VALUE);
2859 }
2860
2861 programObject->getInfoLog(bufsize, length, infolog);
2862 }
2863}
2864
Nicolas Capensa9b49372015-01-30 00:33:26 -05002865void APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002866{
2867 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
2868
2869 switch(pname)
2870 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002871 case GL_CURRENT_QUERY:
Nicolas Capens264f1522015-01-09 17:21:17 -05002872 break;
2873 default:
2874 return error(GL_INVALID_ENUM);
2875 }
2876
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002877 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002878
2879 if(context)
2880 {
2881 params[0] = context->getActiveQuery(target);
2882 }
2883}
2884
Nicolas Capensa9b49372015-01-30 00:33:26 -05002885void APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002886{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002887 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", name, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002888
2889 switch(pname)
2890 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002891 case GL_QUERY_RESULT:
2892 case GL_QUERY_RESULT_AVAILABLE:
Nicolas Capens264f1522015-01-09 17:21:17 -05002893 break;
2894 default:
2895 return error(GL_INVALID_ENUM);
2896 }
2897
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002898 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002899
2900 if(context)
2901 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002902 gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
Nicolas Capens264f1522015-01-09 17:21:17 -05002903
2904 if(!queryObject)
2905 {
2906 return error(GL_INVALID_OPERATION);
2907 }
2908
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002909 if(context->getActiveQuery(queryObject->getType()) == name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002910 {
2911 return error(GL_INVALID_OPERATION);
2912 }
2913
2914 switch(pname)
2915 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002916 case GL_QUERY_RESULT:
Nicolas Capens264f1522015-01-09 17:21:17 -05002917 params[0] = queryObject->getResult();
2918 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002919 case GL_QUERY_RESULT_AVAILABLE:
Nicolas Capens264f1522015-01-09 17:21:17 -05002920 params[0] = queryObject->isResultAvailable();
2921 break;
2922 default:
2923 ASSERT(false);
2924 }
2925 }
2926}
2927
Nicolas Capensa9b49372015-01-30 00:33:26 -05002928void APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002929{
2930 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
2931
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002932 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002933
2934 if(context)
2935 {
2936 if(target != GL_RENDERBUFFER)
2937 {
2938 return error(GL_INVALID_ENUM);
2939 }
2940
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002941 if(context->getRenderbufferName() == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05002942 {
2943 return error(GL_INVALID_OPERATION);
2944 }
2945
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002946 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
Nicolas Capens264f1522015-01-09 17:21:17 -05002947
2948 switch(pname)
2949 {
2950 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
2951 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
2952 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
2953 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
2954 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
2955 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
2956 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
2957 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
2958 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002959 case GL_RENDERBUFFER_SAMPLES_EXT: *params = renderbuffer->getSamples(); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05002960 default:
2961 return error(GL_INVALID_ENUM);
2962 }
2963 }
2964}
2965
Nicolas Capensa9b49372015-01-30 00:33:26 -05002966void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002967{
2968 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
2969
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002970 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002971
2972 if(context)
2973 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002974 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05002975
2976 if(!shaderObject)
2977 {
2978 return error(GL_INVALID_VALUE);
2979 }
2980
2981 switch(pname)
2982 {
2983 case GL_SHADER_TYPE:
2984 *params = shaderObject->getType();
2985 return;
2986 case GL_DELETE_STATUS:
2987 *params = shaderObject->isFlaggedForDeletion();
2988 return;
2989 case GL_COMPILE_STATUS:
2990 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2991 return;
2992 case GL_INFO_LOG_LENGTH:
2993 *params = shaderObject->getInfoLogLength();
2994 return;
2995 case GL_SHADER_SOURCE_LENGTH:
2996 *params = shaderObject->getSourceLength();
2997 return;
2998 default:
2999 return error(GL_INVALID_ENUM);
3000 }
3001 }
3002}
3003
Nicolas Capensa9b49372015-01-30 00:33:26 -05003004void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
Nicolas Capens264f1522015-01-09 17:21:17 -05003005{
3006 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
3007 shader, bufsize, length, infolog);
3008
3009 if(bufsize < 0)
3010 {
3011 return error(GL_INVALID_VALUE);
3012 }
3013
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003014 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003015
3016 if(context)
3017 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003018 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003019
3020 if(!shaderObject)
3021 {
3022 return error(GL_INVALID_VALUE);
3023 }
3024
3025 shaderObject->getInfoLog(bufsize, length, infolog);
3026 }
3027}
3028
Nicolas Capensa9b49372015-01-30 00:33:26 -05003029void APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
Nicolas Capens264f1522015-01-09 17:21:17 -05003030{
3031 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
3032 shadertype, precisiontype, range, precision);
3033
3034 switch(shadertype)
3035 {
3036 case GL_VERTEX_SHADER:
3037 case GL_FRAGMENT_SHADER:
3038 break;
3039 default:
3040 return error(GL_INVALID_ENUM);
3041 }
3042
3043 switch(precisiontype)
3044 {
3045 case GL_LOW_FLOAT:
3046 case GL_MEDIUM_FLOAT:
3047 case GL_HIGH_FLOAT:
3048 // IEEE 754 single-precision
3049 range[0] = 127;
3050 range[1] = 127;
3051 *precision = 23;
3052 break;
3053 case GL_LOW_INT:
3054 case GL_MEDIUM_INT:
3055 case GL_HIGH_INT:
3056 // Single-precision floating-point numbers can accurately represent integers up to +/-16777216
3057 range[0] = 24;
3058 range[1] = 24;
3059 *precision = 0;
3060 break;
3061 default:
3062 return error(GL_INVALID_ENUM);
3063 }
3064}
3065
Nicolas Capensa9b49372015-01-30 00:33:26 -05003066void APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
Nicolas Capens264f1522015-01-09 17:21:17 -05003067{
3068 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3069 shader, bufsize, length, source);
3070
3071 if(bufsize < 0)
3072 {
3073 return error(GL_INVALID_VALUE);
3074 }
3075
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003076 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003077
3078 if(context)
3079 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003080 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003081
3082 if(!shaderObject)
3083 {
3084 return error(GL_INVALID_OPERATION);
3085 }
3086
3087 shaderObject->getSource(bufsize, length, source);
3088 }
3089}
3090
Nicolas Capensa9b49372015-01-30 00:33:26 -05003091const GLubyte* APIENTRY glGetString(GLenum name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003092{
3093 TRACE("(GLenum name = 0x%X)", name);
3094
Nicolas Capens264f1522015-01-09 17:21:17 -05003095 switch(name)
3096 {
3097 case GL_VENDOR:
3098 return (GLubyte*)"TransGaming Inc.";
3099 case GL_RENDERER:
3100 return (GLubyte*)"SwiftShader";
3101 case GL_VERSION:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003102 return (GLubyte*)"2.1 SwiftShader "VERSION_STRING;
Nicolas Capens264f1522015-01-09 17:21:17 -05003103 case GL_SHADING_LANGUAGE_VERSION:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003104 return (GLubyte*)"3.30 SwiftShader "VERSION_STRING;
Nicolas Capens264f1522015-01-09 17:21:17 -05003105 case GL_EXTENSIONS:
3106 // Keep list sorted in following order:
3107 // OES extensions
3108 // EXT extensions
3109 // Vendor extensions
3110 return (GLubyte*)
Nicolas Capensa9b49372015-01-30 00:33:26 -05003111 "GL_ARB_framebuffer_object "
Nicolas Capens264f1522015-01-09 17:21:17 -05003112 "GL_EXT_blend_minmax "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003113 "GL_EXT_depth_texture "
3114 "GL_EXT_depth_texture_cube_map "
3115 "GL_EXT_element_index_uint "
3116 "GL_EXT_packed_depth_stencil "
3117 "GL_EXT_rgb8_rgba8 "
3118 "GL_EXT_standard_derivatives "
3119 "GL_EXT_texture_float "
3120 "GL_EXT_texture_float_linear "
3121 "GL_EXT_texture_half_float "
3122 "GL_EXT_texture_half_float_linear "
3123 "GL_EXT_texture_npot "
Nicolas Capens264f1522015-01-09 17:21:17 -05003124 "GL_EXT_occlusion_query_boolean "
3125 "GL_EXT_read_format_bgra "
3126 #if (S3TC_SUPPORT)
3127 "GL_EXT_texture_compression_dxt1 "
3128 #endif
Nicolas Capensa9b49372015-01-30 00:33:26 -05003129 "GL_EXT_blend_func_separate "
3130 "GL_EXT_secondary_color "
Nicolas Capens264f1522015-01-09 17:21:17 -05003131 "GL_EXT_texture_filter_anisotropic "
3132 "GL_EXT_texture_format_BGRA8888 "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003133 "GL_EXT_framebuffer_blit "
3134 "GL_EXT_framebuffer_multisample "
Nicolas Capens264f1522015-01-09 17:21:17 -05003135 #if (S3TC_SUPPORT)
Nicolas Capensa9b49372015-01-30 00:33:26 -05003136 "GL_EXT_texture_compression_dxt3 "
3137 "GL_EXT_texture_compression_dxt5 "
Nicolas Capens264f1522015-01-09 17:21:17 -05003138 #endif
3139 "GL_NV_fence";
3140 default:
3141 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3142 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05003143
3144 return NULL;
Nicolas Capens264f1522015-01-09 17:21:17 -05003145}
3146
Nicolas Capensa9b49372015-01-30 00:33:26 -05003147void APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003148{
3149 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
3150
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003151 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003152
3153 if(context)
3154 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003155 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05003156
3157 switch(target)
3158 {
3159 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003160 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05003161 break;
3162 case GL_TEXTURE_CUBE_MAP:
3163 texture = context->getTextureCubeMap();
3164 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003165 default:
3166 return error(GL_INVALID_ENUM);
3167 }
3168
3169 switch(pname)
3170 {
3171 case GL_TEXTURE_MAG_FILTER:
3172 *params = (GLfloat)texture->getMagFilter();
3173 break;
3174 case GL_TEXTURE_MIN_FILTER:
3175 *params = (GLfloat)texture->getMinFilter();
3176 break;
3177 case GL_TEXTURE_WRAP_S:
3178 *params = (GLfloat)texture->getWrapS();
3179 break;
3180 case GL_TEXTURE_WRAP_T:
3181 *params = (GLfloat)texture->getWrapT();
3182 break;
3183 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3184 *params = texture->getMaxAnisotropy();
3185 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003186 default:
3187 return error(GL_INVALID_ENUM);
3188 }
3189 }
3190}
3191
Nicolas Capensa9b49372015-01-30 00:33:26 -05003192void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003193{
3194 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
3195
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003196 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003197
3198 if(context)
3199 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003200 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05003201
3202 switch(target)
3203 {
3204 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003205 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05003206 break;
3207 case GL_TEXTURE_CUBE_MAP:
3208 texture = context->getTextureCubeMap();
3209 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003210 default:
3211 return error(GL_INVALID_ENUM);
3212 }
3213
3214 switch(pname)
3215 {
3216 case GL_TEXTURE_MAG_FILTER:
3217 *params = texture->getMagFilter();
3218 break;
3219 case GL_TEXTURE_MIN_FILTER:
3220 *params = texture->getMinFilter();
3221 break;
3222 case GL_TEXTURE_WRAP_S:
3223 *params = texture->getWrapS();
3224 break;
3225 case GL_TEXTURE_WRAP_T:
3226 *params = texture->getWrapT();
3227 break;
3228 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3229 *params = (GLint)texture->getMaxAnisotropy();
3230 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003231 default:
3232 return error(GL_INVALID_ENUM);
3233 }
3234 }
3235}
3236
Nicolas Capensa9b49372015-01-30 00:33:26 -05003237void APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003238{
3239 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3240 program, location, bufSize, params);
3241
3242 if(bufSize < 0)
3243 {
3244 return error(GL_INVALID_VALUE);
3245 }
3246
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003247 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003248
3249 if(context)
3250 {
3251 if(program == 0)
3252 {
3253 return error(GL_INVALID_VALUE);
3254 }
3255
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003256 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003257
3258 if(!programObject || !programObject->isLinked())
3259 {
3260 return error(GL_INVALID_OPERATION);
3261 }
3262
3263 if(!programObject->getUniformfv(location, &bufSize, params))
3264 {
3265 return error(GL_INVALID_OPERATION);
3266 }
3267 }
3268}
3269
Nicolas Capensa9b49372015-01-30 00:33:26 -05003270void APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003271{
3272 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
3273
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003274 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003275
3276 if(context)
3277 {
3278 if(program == 0)
3279 {
3280 return error(GL_INVALID_VALUE);
3281 }
3282
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003283 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003284
3285 if(!programObject || !programObject->isLinked())
3286 {
3287 return error(GL_INVALID_OPERATION);
3288 }
3289
3290 if(!programObject->getUniformfv(location, NULL, params))
3291 {
3292 return error(GL_INVALID_OPERATION);
3293 }
3294 }
3295}
3296
Nicolas Capensa9b49372015-01-30 00:33:26 -05003297void APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003298{
3299 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3300 program, location, bufSize, params);
3301
3302 if(bufSize < 0)
3303 {
3304 return error(GL_INVALID_VALUE);
3305 }
3306
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003307 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003308
3309 if(context)
3310 {
3311 if(program == 0)
3312 {
3313 return error(GL_INVALID_VALUE);
3314 }
3315
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003316 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003317
3318 if(!programObject || !programObject->isLinked())
3319 {
3320 return error(GL_INVALID_OPERATION);
3321 }
3322
3323 if(!programObject)
3324 {
3325 return error(GL_INVALID_OPERATION);
3326 }
3327
3328 if(!programObject->getUniformiv(location, &bufSize, params))
3329 {
3330 return error(GL_INVALID_OPERATION);
3331 }
3332 }
3333}
3334
Nicolas Capensa9b49372015-01-30 00:33:26 -05003335void APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003336{
3337 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
3338
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003339 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003340
3341 if(context)
3342 {
3343 if(program == 0)
3344 {
3345 return error(GL_INVALID_VALUE);
3346 }
3347
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003348 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003349
3350 if(!programObject || !programObject->isLinked())
3351 {
3352 return error(GL_INVALID_OPERATION);
3353 }
3354
3355 if(!programObject)
3356 {
3357 return error(GL_INVALID_OPERATION);
3358 }
3359
3360 if(!programObject->getUniformiv(location, NULL, params))
3361 {
3362 return error(GL_INVALID_OPERATION);
3363 }
3364 }
3365}
3366
Nicolas Capensa9b49372015-01-30 00:33:26 -05003367int APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003368{
3369 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
3370
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003371 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003372
3373 if(strstr(name, "gl_") == name)
3374 {
3375 return -1;
3376 }
3377
3378 if(context)
3379 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003380 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003381
3382 if(!programObject)
3383 {
3384 if(context->getShader(program))
3385 {
3386 return error(GL_INVALID_OPERATION, -1);
3387 }
3388 else
3389 {
3390 return error(GL_INVALID_VALUE, -1);
3391 }
3392 }
3393
3394 if(!programObject->isLinked())
3395 {
3396 return error(GL_INVALID_OPERATION, -1);
3397 }
3398
3399 return programObject->getUniformLocation(name);
3400 }
3401
3402 return -1;
3403}
3404
Nicolas Capensa9b49372015-01-30 00:33:26 -05003405void APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003406{
3407 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
3408
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003409 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003410
3411 if(context)
3412 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003413 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003414 {
3415 return error(GL_INVALID_VALUE);
3416 }
3417
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003418 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
Nicolas Capens264f1522015-01-09 17:21:17 -05003419
3420 switch(pname)
3421 {
3422 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3423 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3424 break;
3425 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3426 *params = (GLfloat)attribState.mSize;
3427 break;
3428 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3429 *params = (GLfloat)attribState.mStride;
3430 break;
3431 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3432 *params = (GLfloat)attribState.mType;
3433 break;
3434 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3435 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
3436 break;
3437 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003438 *params = (GLfloat)attribState.mBoundBuffer.name();
Nicolas Capens264f1522015-01-09 17:21:17 -05003439 break;
3440 case GL_CURRENT_VERTEX_ATTRIB:
3441 for(int i = 0; i < 4; ++i)
3442 {
3443 params[i] = attribState.mCurrentValue[i];
3444 }
3445 break;
3446 default: return error(GL_INVALID_ENUM);
3447 }
3448 }
3449}
3450
Nicolas Capensa9b49372015-01-30 00:33:26 -05003451void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003452{
3453 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
3454
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003455 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003456
3457 if(context)
3458 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003459 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003460 {
3461 return error(GL_INVALID_VALUE);
3462 }
3463
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003464 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
Nicolas Capens264f1522015-01-09 17:21:17 -05003465
3466 switch(pname)
3467 {
3468 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3469 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3470 break;
3471 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3472 *params = attribState.mSize;
3473 break;
3474 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3475 *params = attribState.mStride;
3476 break;
3477 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3478 *params = attribState.mType;
3479 break;
3480 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3481 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
3482 break;
3483 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003484 *params = attribState.mBoundBuffer.name();
Nicolas Capens264f1522015-01-09 17:21:17 -05003485 break;
3486 case GL_CURRENT_VERTEX_ATTRIB:
3487 for(int i = 0; i < 4; ++i)
3488 {
3489 float currentValue = attribState.mCurrentValue[i];
3490 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3491 }
3492 break;
3493 default: return error(GL_INVALID_ENUM);
3494 }
3495 }
3496}
3497
Nicolas Capensa9b49372015-01-30 00:33:26 -05003498void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003499{
3500 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
3501
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003502 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003503
3504 if(context)
3505 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003506 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003507 {
3508 return error(GL_INVALID_VALUE);
3509 }
3510
3511 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3512 {
3513 return error(GL_INVALID_ENUM);
3514 }
3515
3516 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
3517 }
3518}
3519
Nicolas Capensa9b49372015-01-30 00:33:26 -05003520void APIENTRY glHint(GLenum target, GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05003521{
3522 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
3523
3524 switch(mode)
3525 {
3526 case GL_FASTEST:
3527 case GL_NICEST:
3528 case GL_DONT_CARE:
3529 break;
3530 default:
3531 return error(GL_INVALID_ENUM);
3532 }
3533
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003534 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003535 switch(target)
3536 {
3537 case GL_GENERATE_MIPMAP_HINT:
3538 if(context) context->setGenerateMipmapHint(mode);
3539 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05003540 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
Nicolas Capens264f1522015-01-09 17:21:17 -05003541 if(context) context->setFragmentShaderDerivativeHint(mode);
3542 break;
3543 default:
3544 return error(GL_INVALID_ENUM);
3545 }
3546}
3547
Nicolas Capensa9b49372015-01-30 00:33:26 -05003548GLboolean APIENTRY glIsBuffer(GLuint buffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003549{
3550 TRACE("(GLuint buffer = %d)", buffer);
3551
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003552 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003553
3554 if(context && buffer)
3555 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003556 gl::Buffer *bufferObject = context->getBuffer(buffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003557
3558 if(bufferObject)
3559 {
3560 return GL_TRUE;
3561 }
3562 }
3563
3564 return GL_FALSE;
3565}
3566
Nicolas Capensa9b49372015-01-30 00:33:26 -05003567GLboolean APIENTRY glIsEnabled(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05003568{
3569 TRACE("(GLenum cap = 0x%X)", cap);
3570
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003571 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003572
3573 if(context)
3574 {
3575 switch(cap)
3576 {
3577 case GL_CULL_FACE: return context->isCullFaceEnabled();
3578 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3579 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3580 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3581 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3582 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3583 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3584 case GL_BLEND: return context->isBlendEnabled();
3585 case GL_DITHER: return context->isDitherEnabled();
3586 default:
3587 return error(GL_INVALID_ENUM, false);
3588 }
3589 }
3590
3591 return false;
3592}
3593
Nicolas Capensa9b49372015-01-30 00:33:26 -05003594GLboolean APIENTRY glIsFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05003595{
3596 TRACE("(GLuint fence = %d)", fence);
3597
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003598 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003599
3600 if(context)
3601 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003602 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05003603
3604 if(fenceObject == NULL)
3605 {
3606 return GL_FALSE;
3607 }
3608
3609 return fenceObject->isFence();
3610 }
3611
3612 return GL_FALSE;
3613}
3614
Nicolas Capensa9b49372015-01-30 00:33:26 -05003615GLboolean APIENTRY glIsFramebuffer(GLuint framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003616{
3617 TRACE("(GLuint framebuffer = %d)", framebuffer);
3618
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003619 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003620
3621 if(context && framebuffer)
3622 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003623 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003624
3625 if(framebufferObject)
3626 {
3627 return GL_TRUE;
3628 }
3629 }
3630
3631 return GL_FALSE;
3632}
3633
Nicolas Capensa9b49372015-01-30 00:33:26 -05003634GLboolean APIENTRY glIsProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05003635{
3636 TRACE("(GLuint program = %d)", program);
3637
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003638 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003639
3640 if(context && program)
3641 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003642 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003643
3644 if(programObject)
3645 {
3646 return GL_TRUE;
3647 }
3648 }
3649
3650 return GL_FALSE;
3651}
3652
Nicolas Capensa9b49372015-01-30 00:33:26 -05003653GLboolean APIENTRY glIsQueryEXT(GLuint name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003654{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003655 TRACE("(GLuint name = %d)", name);
Nicolas Capens264f1522015-01-09 17:21:17 -05003656
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003657 if(name == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05003658 {
3659 return GL_FALSE;
3660 }
3661
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003662 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003663
3664 if(context)
3665 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003666 gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
Nicolas Capens264f1522015-01-09 17:21:17 -05003667
3668 if(queryObject)
3669 {
3670 return GL_TRUE;
3671 }
3672 }
3673
3674 return GL_FALSE;
3675}
3676
Nicolas Capensa9b49372015-01-30 00:33:26 -05003677GLboolean APIENTRY glIsRenderbuffer(GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003678{
3679 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
3680
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003681 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003682
3683 if(context && renderbuffer)
3684 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003685 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003686
3687 if(renderbufferObject)
3688 {
3689 return GL_TRUE;
3690 }
3691 }
3692
3693 return GL_FALSE;
3694}
3695
Nicolas Capensa9b49372015-01-30 00:33:26 -05003696GLboolean APIENTRY glIsShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05003697{
3698 TRACE("(GLuint shader = %d)", shader);
3699
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003700 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003701
3702 if(context && shader)
3703 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003704 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003705
3706 if(shaderObject)
3707 {
3708 return GL_TRUE;
3709 }
3710 }
3711
3712 return GL_FALSE;
3713}
3714
Nicolas Capensa9b49372015-01-30 00:33:26 -05003715GLboolean APIENTRY glIsTexture(GLuint texture)
Nicolas Capens264f1522015-01-09 17:21:17 -05003716{
3717 TRACE("(GLuint texture = %d)", texture);
3718
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003719 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003720
3721 if(context && texture)
3722 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003723 gl::Texture *textureObject = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -05003724
3725 if(textureObject)
3726 {
3727 return GL_TRUE;
3728 }
3729 }
3730
3731 return GL_FALSE;
3732}
3733
Nicolas Capensa9b49372015-01-30 00:33:26 -05003734void APIENTRY glLineWidth(GLfloat width)
Nicolas Capens264f1522015-01-09 17:21:17 -05003735{
3736 TRACE("(GLfloat width = %f)", width);
3737
3738 if(width <= 0.0f)
3739 {
3740 return error(GL_INVALID_VALUE);
3741 }
3742
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003743 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003744
3745 if(context)
3746 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003747 if(context->getListIndex() != 0)
3748 {
3749 UNIMPLEMENTED();
3750 }
3751
Nicolas Capens264f1522015-01-09 17:21:17 -05003752 context->setLineWidth(width);
3753 }
3754}
3755
Nicolas Capensa9b49372015-01-30 00:33:26 -05003756void APIENTRY glLinkProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05003757{
3758 TRACE("(GLuint program = %d)", program);
3759
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003760 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003761
3762 if(context)
3763 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003764 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003765
3766 if(!programObject)
3767 {
3768 if(context->getShader(program))
3769 {
3770 return error(GL_INVALID_OPERATION);
3771 }
3772 else
3773 {
3774 return error(GL_INVALID_VALUE);
3775 }
3776 }
3777
3778 programObject->link();
3779 }
3780}
3781
Nicolas Capensa9b49372015-01-30 00:33:26 -05003782void APIENTRY glPixelStorei(GLenum pname, GLint param)
Nicolas Capens264f1522015-01-09 17:21:17 -05003783{
3784 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
3785
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003786 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003787
3788 if(context)
3789 {
3790 switch(pname)
3791 {
3792 case GL_UNPACK_ALIGNMENT:
3793 if(param != 1 && param != 2 && param != 4 && param != 8)
3794 {
3795 return error(GL_INVALID_VALUE);
3796 }
3797 context->setUnpackAlignment(param);
3798 break;
3799 case GL_PACK_ALIGNMENT:
3800 if(param != 1 && param != 2 && param != 4 && param != 8)
3801 {
3802 return error(GL_INVALID_VALUE);
3803 }
3804 context->setPackAlignment(param);
3805 break;
3806 default:
3807 return error(GL_INVALID_ENUM);
3808 }
3809 }
3810}
3811
Nicolas Capensa9b49372015-01-30 00:33:26 -05003812void APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
Nicolas Capens264f1522015-01-09 17:21:17 -05003813{
3814 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
3815
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003816 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003817
3818 if(context)
3819 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003820 if(context->getListIndex() != 0)
3821 {
3822 UNIMPLEMENTED();
3823 }
3824
Nicolas Capens264f1522015-01-09 17:21:17 -05003825 context->setPolygonOffsetParams(factor, units);
3826 }
3827}
3828
Nicolas Capensa9b49372015-01-30 00:33:26 -05003829void APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -05003830 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
3831{
3832 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
3833 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
3834 x, y, width, height, format, type, bufSize, data);
3835
3836 if(width < 0 || height < 0 || bufSize < 0)
3837 {
3838 return error(GL_INVALID_VALUE);
3839 }
3840
3841 if(!validReadFormatType(format, type))
3842 {
3843 return error(GL_INVALID_OPERATION);
3844 }
3845
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003846 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003847
3848 if(context)
3849 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003850 if(context->getListIndex() != 0)
3851 {
3852 UNIMPLEMENTED();
3853 }
3854
Nicolas Capens264f1522015-01-09 17:21:17 -05003855 context->readPixels(x, y, width, height, format, type, &bufSize, data);
3856 }
3857}
3858
Nicolas Capensa9b49372015-01-30 00:33:26 -05003859void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
Nicolas Capens264f1522015-01-09 17:21:17 -05003860{
3861 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
3862 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
3863 x, y, width, height, format, type, pixels);
3864
3865 if(width < 0 || height < 0)
3866 {
3867 return error(GL_INVALID_VALUE);
3868 }
3869
3870 if(!validReadFormatType(format, type))
3871 {
3872 return error(GL_INVALID_OPERATION);
3873 }
3874
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003875 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003876
3877 if(context)
3878 {
3879 context->readPixels(x, y, width, height, format, type, NULL, pixels);
3880 }
3881}
3882
Nicolas Capensa9b49372015-01-30 00:33:26 -05003883void APIENTRY glReleaseShaderCompiler(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05003884{
3885 TRACE("()");
3886
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003887 gl::Shader::releaseCompiler();
Nicolas Capens264f1522015-01-09 17:21:17 -05003888}
3889
Nicolas Capensa9b49372015-01-30 00:33:26 -05003890void APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05003891{
3892 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3893 target, samples, internalformat, width, height);
3894
3895 switch(target)
3896 {
3897 case GL_RENDERBUFFER:
3898 break;
3899 default:
3900 return error(GL_INVALID_ENUM);
3901 }
3902
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003903 if(!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
Nicolas Capens264f1522015-01-09 17:21:17 -05003904 {
3905 return error(GL_INVALID_ENUM);
3906 }
3907
3908 if(width < 0 || height < 0 || samples < 0)
3909 {
3910 return error(GL_INVALID_VALUE);
3911 }
3912
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003913 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003914
3915 if(context)
3916 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003917 if(context->getListIndex() != 0)
3918 {
3919 UNIMPLEMENTED();
3920 }
3921
3922 if(width > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003923 height > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
3924 samples > gl::IMPLEMENTATION_MAX_SAMPLES)
Nicolas Capens264f1522015-01-09 17:21:17 -05003925 {
3926 return error(GL_INVALID_VALUE);
3927 }
3928
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003929 GLuint handle = context->getRenderbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05003930 if(handle == 0)
3931 {
3932 return error(GL_INVALID_OPERATION);
3933 }
3934
3935 switch(internalformat)
3936 {
3937 case GL_DEPTH_COMPONENT16:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003938 case GL_DEPTH_COMPONENT24:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003939 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003940 break;
3941 case GL_RGBA4:
3942 case GL_RGB5_A1:
3943 case GL_RGB565:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003944 case GL_RGB8_EXT:
3945 case GL_RGBA8_EXT:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003946 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003947 break;
3948 case GL_STENCIL_INDEX8:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003949 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003950 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05003951 case GL_DEPTH24_STENCIL8_EXT:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003952 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003953 break;
3954 default:
3955 return error(GL_INVALID_ENUM);
3956 }
3957 }
3958}
3959
Nicolas Capensa9b49372015-01-30 00:33:26 -05003960void APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05003961{
3962 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
3963}
3964
Nicolas Capensa9b49372015-01-30 00:33:26 -05003965void APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
Nicolas Capens264f1522015-01-09 17:21:17 -05003966{
3967 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
3968
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003969 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003970
3971 if(context)
3972 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003973 if(context->getListIndex() != 0)
3974 {
3975 UNIMPLEMENTED();
3976 }
3977
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003978 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
Nicolas Capens264f1522015-01-09 17:21:17 -05003979 }
3980}
3981
Nicolas Capensa9b49372015-01-30 00:33:26 -05003982void APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
Nicolas Capens264f1522015-01-09 17:21:17 -05003983{
3984 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
3985
3986 if(condition != GL_ALL_COMPLETED_NV)
3987 {
3988 return error(GL_INVALID_ENUM);
3989 }
3990
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003991 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003992
3993 if(context)
3994 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003995 if(context->getListIndex() != 0)
3996 {
3997 UNIMPLEMENTED();
3998 }
3999
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004000 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05004001
4002 if(fenceObject == NULL)
4003 {
4004 return error(GL_INVALID_OPERATION);
4005 }
4006
4007 fenceObject->setFence(condition);
4008 }
4009}
4010
Nicolas Capensa9b49372015-01-30 00:33:26 -05004011void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05004012{
4013 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4014
4015 if(width < 0 || height < 0)
4016 {
4017 return error(GL_INVALID_VALUE);
4018 }
4019
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004020 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004021
4022 if(context)
4023 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004024 if(context->getListIndex() != 0)
4025 {
4026 UNIMPLEMENTED();
4027 }
4028
Nicolas Capens264f1522015-01-09 17:21:17 -05004029 context->setScissorParams(x, y, width, height);
4030 }
4031}
4032
Nicolas Capensa9b49372015-01-30 00:33:26 -05004033void APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
Nicolas Capens264f1522015-01-09 17:21:17 -05004034{
4035 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
4036 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
4037 n, shaders, binaryformat, binary, length);
4038
4039 // No binary shader formats are supported.
4040 return error(GL_INVALID_ENUM);
4041}
4042
Nicolas Capensa9b49372015-01-30 00:33:26 -05004043void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
Nicolas Capens264f1522015-01-09 17:21:17 -05004044{
4045 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
4046 shader, count, string, length);
4047
4048 if(count < 0)
4049 {
4050 return error(GL_INVALID_VALUE);
4051 }
4052
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004053 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004054
4055 if(context)
4056 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004057 if(context->getListIndex() != 0)
4058 {
4059 UNIMPLEMENTED();
4060 }
4061
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004062 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05004063
4064 if(!shaderObject)
4065 {
4066 if(context->getProgram(shader))
4067 {
4068 return error(GL_INVALID_OPERATION);
4069 }
4070 else
4071 {
4072 return error(GL_INVALID_VALUE);
4073 }
4074 }
4075
4076 shaderObject->setSource(count, string, length);
4077 }
4078}
4079
Nicolas Capensa9b49372015-01-30 00:33:26 -05004080void APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004081{
4082 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4083}
4084
Nicolas Capensa9b49372015-01-30 00:33:26 -05004085void APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004086{
4087 TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
4088
4089 switch(face)
4090 {
4091 case GL_FRONT:
4092 case GL_BACK:
4093 case GL_FRONT_AND_BACK:
4094 break;
4095 default:
4096 return error(GL_INVALID_ENUM);
4097 }
4098
4099 switch(func)
4100 {
4101 case GL_NEVER:
4102 case GL_ALWAYS:
4103 case GL_LESS:
4104 case GL_LEQUAL:
4105 case GL_EQUAL:
4106 case GL_GEQUAL:
4107 case GL_GREATER:
4108 case GL_NOTEQUAL:
4109 break;
4110 default:
4111 return error(GL_INVALID_ENUM);
4112 }
4113
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004114 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004115
4116 if(context)
4117 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004118 if(context->getListIndex() != 0)
4119 {
4120 UNIMPLEMENTED();
4121 }
4122
Nicolas Capens264f1522015-01-09 17:21:17 -05004123 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4124 {
4125 context->setStencilParams(func, ref, mask);
4126 }
4127
4128 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4129 {
4130 context->setStencilBackParams(func, ref, mask);
4131 }
4132 }
4133}
4134
Nicolas Capensa9b49372015-01-30 00:33:26 -05004135void APIENTRY glStencilMask(GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004136{
4137 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4138}
4139
Nicolas Capensa9b49372015-01-30 00:33:26 -05004140void APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004141{
4142 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
4143
4144 switch(face)
4145 {
4146 case GL_FRONT:
4147 case GL_BACK:
4148 case GL_FRONT_AND_BACK:
4149 break;
4150 default:
4151 return error(GL_INVALID_ENUM);
4152 }
4153
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004154 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004155
4156 if(context)
4157 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004158 if(context->getListIndex() != 0)
4159 {
4160 UNIMPLEMENTED();
4161 }
4162
Nicolas Capens264f1522015-01-09 17:21:17 -05004163 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4164 {
4165 context->setStencilWritemask(mask);
4166 }
4167
4168 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4169 {
4170 context->setStencilBackWritemask(mask);
4171 }
4172 }
4173}
4174
Nicolas Capensa9b49372015-01-30 00:33:26 -05004175void APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
Nicolas Capens264f1522015-01-09 17:21:17 -05004176{
4177 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4178}
4179
Nicolas Capensa9b49372015-01-30 00:33:26 -05004180void APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
Nicolas Capens264f1522015-01-09 17:21:17 -05004181{
4182 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4183 face, fail, zfail, zpass);
4184
4185 switch(face)
4186 {
4187 case GL_FRONT:
4188 case GL_BACK:
4189 case GL_FRONT_AND_BACK:
4190 break;
4191 default:
4192 return error(GL_INVALID_ENUM);
4193 }
4194
4195 switch(fail)
4196 {
4197 case GL_ZERO:
4198 case GL_KEEP:
4199 case GL_REPLACE:
4200 case GL_INCR:
4201 case GL_DECR:
4202 case GL_INVERT:
4203 case GL_INCR_WRAP:
4204 case GL_DECR_WRAP:
4205 break;
4206 default:
4207 return error(GL_INVALID_ENUM);
4208 }
4209
4210 switch(zfail)
4211 {
4212 case GL_ZERO:
4213 case GL_KEEP:
4214 case GL_REPLACE:
4215 case GL_INCR:
4216 case GL_DECR:
4217 case GL_INVERT:
4218 case GL_INCR_WRAP:
4219 case GL_DECR_WRAP:
4220 break;
4221 default:
4222 return error(GL_INVALID_ENUM);
4223 }
4224
4225 switch(zpass)
4226 {
4227 case GL_ZERO:
4228 case GL_KEEP:
4229 case GL_REPLACE:
4230 case GL_INCR:
4231 case GL_DECR:
4232 case GL_INVERT:
4233 case GL_INCR_WRAP:
4234 case GL_DECR_WRAP:
4235 break;
4236 default:
4237 return error(GL_INVALID_ENUM);
4238 }
4239
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004240 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004241
4242 if(context)
4243 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004244 if(context->getListIndex() != 0)
4245 {
4246 UNIMPLEMENTED();
4247 }
4248
Nicolas Capens264f1522015-01-09 17:21:17 -05004249 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4250 {
4251 context->setStencilOperations(fail, zfail, zpass);
4252 }
4253
4254 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4255 {
4256 context->setStencilBackOperations(fail, zfail, zpass);
4257 }
4258 }
4259}
4260
Nicolas Capensa9b49372015-01-30 00:33:26 -05004261GLboolean APIENTRY glTestFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05004262{
4263 TRACE("(GLuint fence = %d)", fence);
4264
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004265 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004266
4267 if(context)
4268 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004269 if(context->getListIndex() != 0)
4270 {
4271 UNIMPLEMENTED();
4272 }
4273
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004274 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05004275
4276 if(fenceObject == NULL)
4277 {
4278 return error(GL_INVALID_OPERATION, GL_TRUE);
4279 }
4280
4281 return fenceObject->testFence();
4282 }
4283
4284 return GL_TRUE;
4285}
4286
Nicolas Capensa9b49372015-01-30 00:33:26 -05004287void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -05004288 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4289{
4290 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
4291 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
4292 target, level, internalformat, width, height, border, format, type, pixels);
4293
4294 if(!validImageSize(level, width, height))
4295 {
4296 return error(GL_INVALID_VALUE);
4297 }
4298
4299 if(internalformat != format)
4300 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004301 //TRACE("UNIMPLEMENTED!!");
4302 //return error(GL_INVALID_OPERATION);
Nicolas Capens264f1522015-01-09 17:21:17 -05004303 }
4304
4305 switch(format)
4306 {
4307 case GL_ALPHA:
4308 case GL_LUMINANCE:
4309 case GL_LUMINANCE_ALPHA:
4310 switch(type)
4311 {
4312 case GL_UNSIGNED_BYTE:
4313 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004314 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004315 break;
4316 default:
4317 return error(GL_INVALID_ENUM);
4318 }
4319 break;
4320 case GL_RGB:
4321 switch(type)
4322 {
4323 case GL_UNSIGNED_BYTE:
4324 case GL_UNSIGNED_SHORT_5_6_5:
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_RGBA:
4333 switch(type)
4334 {
4335 case GL_UNSIGNED_BYTE:
4336 case GL_UNSIGNED_SHORT_4_4_4_4:
4337 case GL_UNSIGNED_SHORT_5_5_5_1:
4338 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004339 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004340 break;
4341 default:
4342 return error(GL_INVALID_ENUM);
4343 }
4344 break;
4345 case GL_BGRA_EXT:
4346 switch(type)
4347 {
4348 case GL_UNSIGNED_BYTE:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004349 case GL_UNSIGNED_SHORT_5_6_5:
4350 case GL_UNSIGNED_INT_8_8_8_8_REV:
Nicolas Capens264f1522015-01-09 17:21:17 -05004351 break;
4352 default:
4353 return error(GL_INVALID_ENUM);
4354 }
4355 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004356 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
Nicolas Capens264f1522015-01-09 17:21:17 -05004357 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004358 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
4359 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
4360 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004361 case GL_DEPTH_COMPONENT:
4362 switch(type)
4363 {
4364 case GL_UNSIGNED_SHORT:
4365 case GL_UNSIGNED_INT:
4366 break;
4367 default:
4368 return error(GL_INVALID_ENUM);
4369 }
4370 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004371 case GL_DEPTH_STENCIL_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004372 switch(type)
4373 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004374 case GL_UNSIGNED_INT_24_8_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004375 break;
4376 default:
4377 return error(GL_INVALID_ENUM);
4378 }
4379 break;
4380 default:
4381 return error(GL_INVALID_VALUE);
4382 }
4383
4384 if(border != 0)
4385 {
4386 return error(GL_INVALID_VALUE);
4387 }
4388
Nicolas Capensa9b49372015-01-30 00:33:26 -05004389 switch(target)
4390 {
4391 case GL_TEXTURE_2D:
4392 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4393 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4394 {
4395 return error(GL_INVALID_VALUE);
4396 }
4397 break;
4398 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4399 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4400 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4401 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4402 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4403 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4404 if(width != height)
4405 {
4406 return error(GL_INVALID_VALUE);
4407 }
4408
4409 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
4410 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
4411 {
4412 return error(GL_INVALID_VALUE);
4413 }
4414 break;
4415 case GL_PROXY_TEXTURE_2D:
4416 pixels = 0;
4417
4418 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4419 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4420 {
4421 //UNIMPLEMENTED();
4422 width = 0;
4423 height = 0;
4424 internalformat = GL_NONE;
4425 format = GL_NONE;
4426 type = GL_NONE;
4427
4428 //return;// error(GL_INVALID_VALUE);
4429 }
4430 break;
4431 default:
4432 return error(GL_INVALID_ENUM);
4433 }
4434
4435 if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4436 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
4437 format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
4438 format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
4439 {
4440 if(S3TC_SUPPORT)
4441 {
4442 return error(GL_INVALID_OPERATION);
4443 }
4444 else
4445 {
4446 return error(GL_INVALID_ENUM);
4447 }
4448 }
4449
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004450 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004451
4452 if(context)
4453 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004454 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05004455 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004456 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05004457 }
4458
Nicolas Capensa9b49372015-01-30 00:33:26 -05004459 if(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D)
Nicolas Capens264f1522015-01-09 17:21:17 -05004460 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004461 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004462
4463 if(!texture)
4464 {
4465 return error(GL_INVALID_OPERATION);
4466 }
4467
4468 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
4469 }
4470 else
4471 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004472 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05004473
4474 if(!texture)
4475 {
4476 return error(GL_INVALID_OPERATION);
4477 }
4478
4479 texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
4480 }
4481 }
4482}
4483
Nicolas Capensa9b49372015-01-30 00:33:26 -05004484void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
Nicolas Capens264f1522015-01-09 17:21:17 -05004485{
4486 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
4487
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004488 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004489
4490 if(context)
4491 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004492 if(context->getListIndex() != 0)
4493 {
4494 UNIMPLEMENTED();
4495 }
4496
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004497 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05004498
4499 switch(target)
4500 {
4501 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004502 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004503 break;
4504 case GL_TEXTURE_CUBE_MAP:
4505 texture = context->getTextureCubeMap();
4506 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004507 default:
4508 return error(GL_INVALID_ENUM);
4509 }
4510
4511 switch(pname)
4512 {
4513 case GL_TEXTURE_WRAP_S:
4514 if(!texture->setWrapS((GLenum)param))
4515 {
4516 return error(GL_INVALID_ENUM);
4517 }
4518 break;
4519 case GL_TEXTURE_WRAP_T:
4520 if(!texture->setWrapT((GLenum)param))
4521 {
4522 return error(GL_INVALID_ENUM);
4523 }
4524 break;
4525 case GL_TEXTURE_MIN_FILTER:
4526 if(!texture->setMinFilter((GLenum)param))
4527 {
4528 return error(GL_INVALID_ENUM);
4529 }
4530 break;
4531 case GL_TEXTURE_MAG_FILTER:
4532 if(!texture->setMagFilter((GLenum)param))
4533 {
4534 return error(GL_INVALID_ENUM);
4535 }
4536 break;
4537 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4538 if(!texture->setMaxAnisotropy(param))
4539 {
4540 return error(GL_INVALID_VALUE);
4541 }
4542 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004543 case GL_TEXTURE_MIN_LOD:
4544 //TRACE("() UNIMPLEMENTED!!"); // FIXME
4545 //UNIMPLEMENTED();
4546 break;
4547 case GL_TEXTURE_MAX_LOD:
4548 //TRACE("() UNIMPLEMENTED!!"); // FIXME
4549 //UNIMPLEMENTED();
4550 break;
4551 case GL_TEXTURE_LOD_BIAS:
4552 if(param != 0.0f)
4553 {
4554 UNIMPLEMENTED();
4555 }
4556 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004557 default:
4558 return error(GL_INVALID_ENUM);
4559 }
4560 }
4561}
4562
Nicolas Capensa9b49372015-01-30 00:33:26 -05004563void APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05004564{
4565 glTexParameterf(target, pname, *params);
4566}
4567
Nicolas Capensa9b49372015-01-30 00:33:26 -05004568void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
Nicolas Capens264f1522015-01-09 17:21:17 -05004569{
4570 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
4571
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004572 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004573
4574 if(context)
4575 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004576 if(context->getListIndex() != 0)
4577 {
4578 UNIMPLEMENTED();
4579 }
4580
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004581 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05004582
4583 switch(target)
4584 {
4585 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004586 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004587 break;
4588 case GL_TEXTURE_CUBE_MAP:
4589 texture = context->getTextureCubeMap();
4590 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004591 default:
4592 return error(GL_INVALID_ENUM);
4593 }
4594
4595 switch(pname)
4596 {
4597 case GL_TEXTURE_WRAP_S:
4598 if(!texture->setWrapS((GLenum)param))
4599 {
4600 return error(GL_INVALID_ENUM);
4601 }
4602 break;
4603 case GL_TEXTURE_WRAP_T:
4604 if(!texture->setWrapT((GLenum)param))
4605 {
4606 return error(GL_INVALID_ENUM);
4607 }
4608 break;
4609 case GL_TEXTURE_MIN_FILTER:
4610 if(!texture->setMinFilter((GLenum)param))
4611 {
4612 return error(GL_INVALID_ENUM);
4613 }
4614 break;
4615 case GL_TEXTURE_MAG_FILTER:
4616 if(!texture->setMagFilter((GLenum)param))
4617 {
4618 return error(GL_INVALID_ENUM);
4619 }
4620 break;
4621 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4622 if(!texture->setMaxAnisotropy((GLfloat)param))
4623 {
4624 return error(GL_INVALID_VALUE);
4625 }
4626 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004627 case GL_TEXTURE_MAX_LEVEL:
4628 if(!texture->setMaxLevel(param))
4629 {
4630 return error(GL_INVALID_ENUM);
4631 }
4632 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004633 default:
4634 return error(GL_INVALID_ENUM);
4635 }
4636 }
4637}
4638
Nicolas Capensa9b49372015-01-30 00:33:26 -05004639void APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05004640{
4641 glTexParameteri(target, pname, *params);
4642}
4643
Nicolas Capensa9b49372015-01-30 00:33:26 -05004644void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4645 GLenum format, GLenum type, const GLvoid* pixels)
Nicolas Capens264f1522015-01-09 17:21:17 -05004646{
4647 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4648 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
4649 "const GLvoid* pixels = 0x%0.8p)",
4650 target, level, xoffset, yoffset, width, height, format, type, pixels);
4651
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004652 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05004653 {
4654 return error(GL_INVALID_ENUM);
4655 }
4656
4657 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
4658 {
4659 return error(GL_INVALID_VALUE);
4660 }
4661
4662 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4663 {
4664 return error(GL_INVALID_VALUE);
4665 }
4666
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004667 if(!gl::CheckTextureFormatType(format, type))
Nicolas Capens264f1522015-01-09 17:21:17 -05004668 {
4669 return error(GL_INVALID_ENUM);
4670 }
4671
4672 if(width == 0 || height == 0 || pixels == NULL)
4673 {
4674 return;
4675 }
4676
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004677 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004678
4679 if(context)
4680 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004681 if(context->getListIndex() != 0)
4682 {
4683 UNIMPLEMENTED();
4684 }
4685
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004686 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -05004687 {
4688 return error(GL_INVALID_VALUE);
4689 }
4690
4691 if(target == GL_TEXTURE_2D)
4692 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004693 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004694
4695 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
4696 {
4697 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4698 }
4699 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004700 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05004701 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004702 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05004703
4704 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
4705 {
4706 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4707 }
4708 }
4709 else
4710 {
4711 UNREACHABLE();
4712 }
4713 }
4714}
4715
Nicolas Capensa9b49372015-01-30 00:33:26 -05004716void APIENTRY glUniform1f(GLint location, GLfloat x)
Nicolas Capens264f1522015-01-09 17:21:17 -05004717{
4718 glUniform1fv(location, 1, &x);
4719}
4720
Nicolas Capensa9b49372015-01-30 00:33:26 -05004721void APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004722{
4723 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
4724
4725 if(count < 0)
4726 {
4727 return error(GL_INVALID_VALUE);
4728 }
4729
4730 if(location == -1)
4731 {
4732 return;
4733 }
4734
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004735 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004736
4737 if(context)
4738 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004739 if(context->getListIndex() != 0)
4740 {
4741 UNIMPLEMENTED();
4742 }
4743
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004744 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004745
4746 if(!program)
4747 {
4748 return error(GL_INVALID_OPERATION);
4749 }
4750
4751 if(!program->setUniform1fv(location, count, v))
4752 {
4753 return error(GL_INVALID_OPERATION);
4754 }
4755 }
4756}
4757
Nicolas Capensa9b49372015-01-30 00:33:26 -05004758void APIENTRY glUniform1i(GLint location, GLint x)
Nicolas Capens264f1522015-01-09 17:21:17 -05004759{
4760 glUniform1iv(location, 1, &x);
4761}
4762
Nicolas Capensa9b49372015-01-30 00:33:26 -05004763void APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004764{
4765 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
4766
4767 if(count < 0)
4768 {
4769 return error(GL_INVALID_VALUE);
4770 }
4771
4772 if(location == -1)
4773 {
4774 return;
4775 }
4776
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004777 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004778
4779 if(context)
4780 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004781 if(context->getListIndex() != 0)
4782 {
4783 UNIMPLEMENTED();
4784 }
4785
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004786 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004787
4788 if(!program)
4789 {
4790 return error(GL_INVALID_OPERATION);
4791 }
4792
4793 if(!program->setUniform1iv(location, count, v))
4794 {
4795 return error(GL_INVALID_OPERATION);
4796 }
4797 }
4798}
4799
Nicolas Capensa9b49372015-01-30 00:33:26 -05004800void APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
Nicolas Capens264f1522015-01-09 17:21:17 -05004801{
4802 GLfloat xy[2] = {x, y};
4803
4804 glUniform2fv(location, 1, (GLfloat*)&xy);
4805}
4806
Nicolas Capensa9b49372015-01-30 00:33:26 -05004807void APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004808{
4809 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
4810
4811 if(count < 0)
4812 {
4813 return error(GL_INVALID_VALUE);
4814 }
4815
4816 if(location == -1)
4817 {
4818 return;
4819 }
4820
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004821 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004822
4823 if(context)
4824 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004825 if(context->getListIndex() != 0)
4826 {
4827 UNIMPLEMENTED();
4828 }
4829
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004830 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004831
4832 if(!program)
4833 {
4834 return error(GL_INVALID_OPERATION);
4835 }
4836
4837 if(!program->setUniform2fv(location, count, v))
4838 {
4839 return error(GL_INVALID_OPERATION);
4840 }
4841 }
4842}
4843
Nicolas Capensa9b49372015-01-30 00:33:26 -05004844void APIENTRY glUniform2i(GLint location, GLint x, GLint y)
Nicolas Capens264f1522015-01-09 17:21:17 -05004845{
4846 GLint xy[4] = {x, y};
4847
4848 glUniform2iv(location, 1, (GLint*)&xy);
4849}
4850
Nicolas Capensa9b49372015-01-30 00:33:26 -05004851void APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004852{
4853 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
4854
4855 if(count < 0)
4856 {
4857 return error(GL_INVALID_VALUE);
4858 }
4859
4860 if(location == -1)
4861 {
4862 return;
4863 }
4864
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004865 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004866
4867 if(context)
4868 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004869 if(context->getListIndex() != 0)
4870 {
4871 UNIMPLEMENTED();
4872 }
4873
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004874 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004875
4876 if(!program)
4877 {
4878 return error(GL_INVALID_OPERATION);
4879 }
4880
4881 if(!program->setUniform2iv(location, count, v))
4882 {
4883 return error(GL_INVALID_OPERATION);
4884 }
4885 }
4886}
4887
Nicolas Capensa9b49372015-01-30 00:33:26 -05004888void APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
Nicolas Capens264f1522015-01-09 17:21:17 -05004889{
4890 GLfloat xyz[3] = {x, y, z};
4891
4892 glUniform3fv(location, 1, (GLfloat*)&xyz);
4893}
4894
Nicolas Capensa9b49372015-01-30 00:33:26 -05004895void APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004896{
4897 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
4898
4899 if(count < 0)
4900 {
4901 return error(GL_INVALID_VALUE);
4902 }
4903
4904 if(location == -1)
4905 {
4906 return;
4907 }
4908
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004909 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004910
4911 if(context)
4912 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004913 if(context->getListIndex() != 0)
4914 {
4915 UNIMPLEMENTED();
4916 }
4917
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004918 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004919
4920 if(!program)
4921 {
4922 return error(GL_INVALID_OPERATION);
4923 }
4924
4925 if(!program->setUniform3fv(location, count, v))
4926 {
4927 return error(GL_INVALID_OPERATION);
4928 }
4929 }
4930}
4931
Nicolas Capensa9b49372015-01-30 00:33:26 -05004932void APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
Nicolas Capens264f1522015-01-09 17:21:17 -05004933{
4934 GLint xyz[3] = {x, y, z};
4935
4936 glUniform3iv(location, 1, (GLint*)&xyz);
4937}
4938
Nicolas Capensa9b49372015-01-30 00:33:26 -05004939void APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004940{
4941 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
4942
4943 if(count < 0)
4944 {
4945 return error(GL_INVALID_VALUE);
4946 }
4947
4948 if(location == -1)
4949 {
4950 return;
4951 }
4952
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004953 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004954
4955 if(context)
4956 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004957 if(context->getListIndex() != 0)
4958 {
4959 UNIMPLEMENTED();
4960 }
4961
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004962 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004963
4964 if(!program)
4965 {
4966 return error(GL_INVALID_OPERATION);
4967 }
4968
4969 if(!program->setUniform3iv(location, count, v))
4970 {
4971 return error(GL_INVALID_OPERATION);
4972 }
4973 }
4974}
4975
Nicolas Capensa9b49372015-01-30 00:33:26 -05004976void APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Nicolas Capens264f1522015-01-09 17:21:17 -05004977{
4978 GLfloat xyzw[4] = {x, y, z, w};
4979
4980 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4981}
4982
Nicolas Capensa9b49372015-01-30 00:33:26 -05004983void APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004984{
4985 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
4986
4987 if(count < 0)
4988 {
4989 return error(GL_INVALID_VALUE);
4990 }
4991
4992 if(location == -1)
4993 {
4994 return;
4995 }
4996
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004997 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004998
4999 if(context)
5000 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005001 if(context->getListIndex() != 0)
5002 {
5003 UNIMPLEMENTED();
5004 }
5005
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005006 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005007
5008 if(!program)
5009 {
5010 return error(GL_INVALID_OPERATION);
5011 }
5012
5013 if(!program->setUniform4fv(location, count, v))
5014 {
5015 return error(GL_INVALID_OPERATION);
5016 }
5017 }
5018}
5019
Nicolas Capensa9b49372015-01-30 00:33:26 -05005020void APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
Nicolas Capens264f1522015-01-09 17:21:17 -05005021{
5022 GLint xyzw[4] = {x, y, z, w};
5023
5024 glUniform4iv(location, 1, (GLint*)&xyzw);
5025}
5026
Nicolas Capensa9b49372015-01-30 00:33:26 -05005027void APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05005028{
5029 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
5030
5031 if(count < 0)
5032 {
5033 return error(GL_INVALID_VALUE);
5034 }
5035
5036 if(location == -1)
5037 {
5038 return;
5039 }
5040
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005041 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005042
5043 if(context)
5044 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005045 if(context->getListIndex() != 0)
5046 {
5047 UNIMPLEMENTED();
5048 }
5049
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005050 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005051
5052 if(!program)
5053 {
5054 return error(GL_INVALID_OPERATION);
5055 }
5056
5057 if(!program->setUniform4iv(location, count, v))
5058 {
5059 return error(GL_INVALID_OPERATION);
5060 }
5061 }
5062}
5063
Nicolas Capensa9b49372015-01-30 00:33:26 -05005064void APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005065{
5066 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5067 location, count, transpose, value);
5068
5069 if(count < 0 || transpose != GL_FALSE)
5070 {
5071 return error(GL_INVALID_VALUE);
5072 }
5073
5074 if(location == -1)
5075 {
5076 return;
5077 }
5078
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005079 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005080
5081 if(context)
5082 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005083 if(context->getListIndex() != 0)
5084 {
5085 UNIMPLEMENTED();
5086 }
5087
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005088 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005089
5090 if(!program)
5091 {
5092 return error(GL_INVALID_OPERATION);
5093 }
5094
5095 if(!program->setUniformMatrix2fv(location, count, value))
5096 {
5097 return error(GL_INVALID_OPERATION);
5098 }
5099 }
5100}
5101
Nicolas Capensa9b49372015-01-30 00:33:26 -05005102void APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005103{
5104 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5105 location, count, transpose, value);
5106
5107 if(count < 0 || transpose != GL_FALSE)
5108 {
5109 return error(GL_INVALID_VALUE);
5110 }
5111
5112 if(location == -1)
5113 {
5114 return;
5115 }
5116
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005117 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005118
5119 if(context)
5120 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005121 if(context->getListIndex() != 0)
5122 {
5123 UNIMPLEMENTED();
5124 }
5125
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005126 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005127
5128 if(!program)
5129 {
5130 return error(GL_INVALID_OPERATION);
5131 }
5132
5133 if(!program->setUniformMatrix3fv(location, count, value))
5134 {
5135 return error(GL_INVALID_OPERATION);
5136 }
5137 }
5138}
5139
Nicolas Capensa9b49372015-01-30 00:33:26 -05005140void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005141{
5142 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5143 location, count, transpose, value);
5144
5145 if(count < 0 || transpose != GL_FALSE)
5146 {
5147 return error(GL_INVALID_VALUE);
5148 }
5149
5150 if(location == -1)
5151 {
5152 return;
5153 }
5154
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005155 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005156
5157 if(context)
5158 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005159 if(context->getListIndex() != 0)
5160 {
5161 UNIMPLEMENTED();
5162 }
5163
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005164 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005165
5166 if(!program)
5167 {
5168 return error(GL_INVALID_OPERATION);
5169 }
5170
5171 if(!program->setUniformMatrix4fv(location, count, value))
5172 {
5173 return error(GL_INVALID_OPERATION);
5174 }
5175 }
5176}
5177
Nicolas Capensa9b49372015-01-30 00:33:26 -05005178void APIENTRY glUseProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05005179{
5180 TRACE("(GLuint program = %d)", program);
5181
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005182 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005183
5184 if(context)
5185 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005186 if(context->getListIndex() != 0)
5187 {
5188 UNIMPLEMENTED();
5189 }
5190
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005191 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05005192
5193 if(!programObject && program != 0)
5194 {
5195 if(context->getShader(program))
5196 {
5197 return error(GL_INVALID_OPERATION);
5198 }
5199 else
5200 {
5201 return error(GL_INVALID_VALUE);
5202 }
5203 }
5204
5205 if(program != 0 && !programObject->isLinked())
5206 {
5207 return error(GL_INVALID_OPERATION);
5208 }
5209
5210 context->useProgram(program);
5211 }
5212}
5213
Nicolas Capensa9b49372015-01-30 00:33:26 -05005214void APIENTRY glValidateProgram(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 Capensf4486fd2015-01-22 11:10:37 -05005222 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05005223
5224 if(!programObject)
5225 {
5226 if(context->getShader(program))
5227 {
5228 return error(GL_INVALID_OPERATION);
5229 }
5230 else
5231 {
5232 return error(GL_INVALID_VALUE);
5233 }
5234 }
5235
5236 programObject->validate();
5237 }
5238}
5239
Nicolas Capensa9b49372015-01-30 00:33:26 -05005240void APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
Nicolas Capens264f1522015-01-09 17:21:17 -05005241{
5242 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
5243
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005244 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005245 {
5246 return error(GL_INVALID_VALUE);
5247 }
5248
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005249 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005250
5251 if(context)
5252 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005253 if(context->getListIndex() != 0)
5254 {
5255 UNIMPLEMENTED();
5256 }
5257
5258 //GLfloat vals[4] = { x, 0, 0, 1 };
5259 context->setVertexAttrib(index, x, 0, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005260 }
5261}
5262
Nicolas Capensa9b49372015-01-30 00:33:26 -05005263void APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005264{
5265 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
5266
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005267 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005268 {
5269 return error(GL_INVALID_VALUE);
5270 }
5271
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005272 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005273
5274 if(context)
5275 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005276 if(context->getListIndex() != 0)
5277 {
5278 UNIMPLEMENTED();
5279 }
5280
5281 //GLfloat vals[4] = { values[0], 0, 0, 1 };
5282 context->setVertexAttrib(index, values[0], 0, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005283 }
5284}
5285
Nicolas Capensa9b49372015-01-30 00:33:26 -05005286void APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
Nicolas Capens264f1522015-01-09 17:21:17 -05005287{
5288 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
5289
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005290 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005291 {
5292 return error(GL_INVALID_VALUE);
5293 }
5294
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005295 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005296
5297 if(context)
5298 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005299 if(context->getListIndex() != 0)
5300 {
5301 UNIMPLEMENTED();
5302 }
5303
5304 //GLfloat vals[4] = { x, y, 0, 1 };
5305 context->setVertexAttrib(index, x, y, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005306 }
5307}
5308
Nicolas Capensa9b49372015-01-30 00:33:26 -05005309void APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005310{
5311 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
5312
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005313 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005314 {
5315 return error(GL_INVALID_VALUE);
5316 }
5317
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005318 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005319
5320 if(context)
5321 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005322 if(context->getListIndex() != 0)
5323 {
5324 UNIMPLEMENTED();
5325 }
5326
5327 //GLfloat vals[4] = { };
5328 context->setVertexAttrib(index, values[0], values[1], 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005329 }
5330}
5331
Nicolas Capensa9b49372015-01-30 00:33:26 -05005332void APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
Nicolas Capens264f1522015-01-09 17:21:17 -05005333{
5334 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
5335
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005336 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005337 {
5338 return error(GL_INVALID_VALUE);
5339 }
5340
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005341 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005342
5343 if(context)
5344 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005345 if(context->getListIndex() != 0)
5346 {
5347 UNIMPLEMENTED();
5348 }
5349
5350 //GLfloat vals[4] = { x, y, z, 1 };
5351 context->setVertexAttrib(index, x, y, z, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005352 }
5353}
5354
Nicolas Capensa9b49372015-01-30 00:33:26 -05005355void APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005356{
5357 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
5358
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005359 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005360 {
5361 return error(GL_INVALID_VALUE);
5362 }
5363
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005364 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005365
5366 if(context)
5367 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005368 if(context->getListIndex() != 0)
5369 {
5370 UNIMPLEMENTED();
5371 }
5372
5373 //GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5374 context->setVertexAttrib(index, values[0], values[1], values[2], 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005375 }
5376}
5377
Nicolas Capensa9b49372015-01-30 00:33:26 -05005378void APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Nicolas Capens264f1522015-01-09 17:21:17 -05005379{
5380 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
5381
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005382 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005383 {
5384 return error(GL_INVALID_VALUE);
5385 }
5386
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005387 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005388
5389 if(context)
5390 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005391 if(context->getListIndex() != 0)
5392 {
5393 UNIMPLEMENTED();
5394 }
5395
5396 //GLfloat vals[4] = { x, y, z, w };
5397 context->setVertexAttrib(index, x, y, z, w);
Nicolas Capens264f1522015-01-09 17:21:17 -05005398 }
5399}
5400
Nicolas Capensa9b49372015-01-30 00:33:26 -05005401void APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005402{
5403 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
5404
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005405 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005406 {
5407 return error(GL_INVALID_VALUE);
5408 }
5409
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005410 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005411
5412 if(context)
5413 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005414 if(context->getListIndex() != 0)
5415 {
5416 UNIMPLEMENTED();
5417 }
5418
5419 context->setVertexAttrib(index, values[0], values[1], values[2], values[3]);
Nicolas Capens264f1522015-01-09 17:21:17 -05005420 }
5421}
5422
Nicolas Capensa9b49372015-01-30 00:33:26 -05005423void APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
Nicolas Capens264f1522015-01-09 17:21:17 -05005424{
5425 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
5426 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
5427 index, size, type, normalized, stride, ptr);
5428
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005429 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005430 {
5431 return error(GL_INVALID_VALUE);
5432 }
5433
5434 if(size < 1 || size > 4)
5435 {
5436 return error(GL_INVALID_VALUE);
5437 }
5438
5439 switch(type)
5440 {
5441 case GL_BYTE:
5442 case GL_UNSIGNED_BYTE:
5443 case GL_SHORT:
5444 case GL_UNSIGNED_SHORT:
5445 case GL_FIXED:
5446 case GL_FLOAT:
5447 break;
5448 default:
5449 return error(GL_INVALID_ENUM);
5450 }
5451
5452 if(stride < 0)
5453 {
5454 return error(GL_INVALID_VALUE);
5455 }
5456
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005457 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005458
5459 if(context)
5460 {
5461 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
5462 }
5463}
5464
Nicolas Capensa9b49372015-01-30 00:33:26 -05005465void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05005466{
5467 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
5468
5469 if(width < 0 || height < 0)
5470 {
5471 return error(GL_INVALID_VALUE);
5472 }
5473
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005474 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005475
5476 if(context)
5477 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005478 if(context->getListIndex() != 0)
5479 {
5480 UNIMPLEMENTED();
5481 }
5482
Nicolas Capens264f1522015-01-09 17:21:17 -05005483 context->setViewportParams(x, y, width, height);
5484 }
5485}
5486
Nicolas Capensa9b49372015-01-30 00:33:26 -05005487void 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 -05005488 GLbitfield mask, GLenum filter)
5489{
5490 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5491 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5492 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5493 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5494
5495 switch(filter)
5496 {
5497 case GL_NEAREST:
5498 break;
5499 default:
5500 return error(GL_INVALID_ENUM);
5501 }
5502
5503 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5504 {
5505 return error(GL_INVALID_VALUE);
5506 }
5507
5508 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5509 {
5510 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5511 return error(GL_INVALID_OPERATION);
5512 }
5513
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005514 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005515
5516 if(context)
5517 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005518 if(context->getListIndex() != 0)
5519 {
5520 UNIMPLEMENTED();
5521 }
5522
Nicolas Capens7cc75e12015-01-29 14:44:24 -05005523 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
Nicolas Capens264f1522015-01-09 17:21:17 -05005524 {
5525 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5526 return error(GL_INVALID_OPERATION);
5527 }
5528
5529 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5530 }
5531}
5532
Nicolas Capensa9b49372015-01-30 00:33:26 -05005533void APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
Nicolas Capens264f1522015-01-09 17:21:17 -05005534 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
5535{
5536 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5537 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
5538 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
5539 target, level, internalformat, width, height, depth, border, format, type, pixels);
5540
5541 UNIMPLEMENTED(); // FIXME
5542}
5543
Nicolas Capensa9b49372015-01-30 00:33:26 -05005544void WINAPI GlmfBeginGlsBlock()
Nicolas Capens264f1522015-01-09 17:21:17 -05005545{
Nicolas Capensa9b49372015-01-30 00:33:26 -05005546 UNIMPLEMENTED();
5547}
5548
5549void WINAPI GlmfCloseMetaFile()
5550{
5551 UNIMPLEMENTED();
5552}
5553
5554void WINAPI GlmfEndGlsBlock()
5555{
5556 UNIMPLEMENTED();
5557}
5558
5559void WINAPI GlmfEndPlayback()
5560{
5561 UNIMPLEMENTED();
5562}
5563
5564void WINAPI GlmfInitPlayback()
5565{
5566 UNIMPLEMENTED();
5567}
5568
5569void WINAPI GlmfPlayGlsRecord()
5570{
5571 UNIMPLEMENTED();
5572}
5573
5574void APIENTRY glAccum(GLenum op, GLfloat value)
5575{
5576 UNIMPLEMENTED();
5577}
5578
5579void APIENTRY glAlphaFunc(GLenum func, GLclampf ref)
5580{
5581 TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);
5582
5583 gl::Context *context = gl::getContext();
5584
5585 if(context)
Nicolas Capens264f1522015-01-09 17:21:17 -05005586 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005587 if(context->getListIndex() != 0)
5588 {
5589 UNIMPLEMENTED();
5590 }
5591
5592 context->alphaFunc(func, ref);
Nicolas Capens264f1522015-01-09 17:21:17 -05005593 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05005594}
Nicolas Capens264f1522015-01-09 17:21:17 -05005595
Nicolas Capensa9b49372015-01-30 00:33:26 -05005596GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
5597{
5598 UNIMPLEMENTED();
5599 return GL_FALSE;
5600}
Nicolas Capens264f1522015-01-09 17:21:17 -05005601
Nicolas Capensa9b49372015-01-30 00:33:26 -05005602void APIENTRY glArrayElement(GLint i)
5603{
5604 UNIMPLEMENTED();
5605}
5606
5607void APIENTRY glBegin(GLenum mode)
5608{
5609 TRACE("(GLenum mode = 0x%X)", mode);
5610
5611 switch(mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05005612 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005613 case GL_POINTS:
5614 case GL_LINES:
5615 case GL_LINE_STRIP:
5616 case GL_LINE_LOOP:
5617 case GL_TRIANGLES:
5618 case GL_TRIANGLE_STRIP:
5619 case GL_TRIANGLE_FAN:
5620 case GL_QUADS:
5621 case GL_QUAD_STRIP:
5622 case GL_POLYGON:
Nicolas Capens264f1522015-01-09 17:21:17 -05005623 break;
5624 default:
5625 return error(GL_INVALID_ENUM);
5626 }
5627
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005628 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005629
5630 if(context)
5631 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005632 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05005633 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005634 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05005635 }
5636
Nicolas Capensa9b49372015-01-30 00:33:26 -05005637 context->begin(mode);
Nicolas Capens264f1522015-01-09 17:21:17 -05005638 }
5639}
5640
Nicolas Capensa9b49372015-01-30 00:33:26 -05005641void APIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
Nicolas Capens264f1522015-01-09 17:21:17 -05005642{
Nicolas Capens264f1522015-01-09 17:21:17 -05005643 UNIMPLEMENTED();
5644}
5645
Nicolas Capensa9b49372015-01-30 00:33:26 -05005646void APIENTRY glCallList(GLuint list)
Nicolas Capens264f1522015-01-09 17:21:17 -05005647{
Nicolas Capensa9b49372015-01-30 00:33:26 -05005648 TRACE("(GLuint list = %d)", list);
5649
5650 if(list == 0)
5651 {
5652 return error(GL_INVALID_VALUE);
5653 }
5654
5655 gl::Context *context = gl::getContext();
5656
5657 if(context)
5658 {
5659 if(context->getListIndex() != 0)
5660 {
5661 UNIMPLEMENTED();
5662 }
5663
5664 context->callList(list);
5665 }
5666}
5667
5668void APIENTRY glCallLists(GLsizei n, GLenum type, const GLvoid *lists)
5669{
5670 TRACE("(GLsizei n = %d, GLenum type = 0x%X, const GLvoid *lists)", n, type);
5671
5672 gl::Context *context = gl::getContext();
5673
5674 if(context)
5675 {
5676 if(context->getListIndex() != 0)
5677 {
5678 UNIMPLEMENTED();
5679 }
5680
5681 for(int i = 0; i < n; i++)
5682 {
5683 switch(type)
5684 {
5685 case GL_UNSIGNED_INT: context->callList(((unsigned int*)lists)[i]); break;
5686 default:
5687 UNIMPLEMENTED();
5688 UNREACHABLE();
5689 }
5690 }
5691 }
5692}
5693
5694void APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
5695{
5696 UNIMPLEMENTED();
5697}
5698
5699void APIENTRY glClearDepth(GLclampd depth)
5700{
5701 TRACE("(GLclampd depth = %d)", depth);
5702
5703 glClearDepthf((float)depth); // FIXME
5704}
5705
5706void APIENTRY glClearIndex(GLfloat c)
5707{
5708 UNIMPLEMENTED();
5709}
5710
5711void APIENTRY glClipPlane(GLenum plane, const GLdouble *equation)
5712{
5713 UNIMPLEMENTED();
5714}
5715
5716void APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue)
5717{
5718 UNIMPLEMENTED();
5719}
5720
5721void APIENTRY glColor3bv(const GLbyte *v)
5722{
5723 UNIMPLEMENTED();
5724}
5725
5726void APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue)
5727{
5728 UNIMPLEMENTED();
5729}
5730
5731void APIENTRY glColor3dv(const GLdouble *v)
5732{
5733 UNIMPLEMENTED();
5734}
5735
5736void APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue)
5737{
5738 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f)", red, green, blue);
5739
5740 gl::Context *context = gl::getContext();
5741
5742 if(context)
5743 {
5744 if(context->getListIndex() != 0)
5745 {
5746 UNIMPLEMENTED();
5747 }
5748
5749 //context->color(red, green, blue, 1.0f);
5750 //GLfloat vals[4] = {};
5751 context->setVertexAttrib(sw::Color0, red, green, blue, 1);
5752 }
5753}
5754
5755void APIENTRY glColor3fv(const GLfloat *v)
5756{
5757 UNIMPLEMENTED();
5758}
5759
5760void APIENTRY glColor3i(GLint red, GLint green, GLint blue)
5761{
5762 UNIMPLEMENTED();
5763}
5764
5765void APIENTRY glColor3iv(const GLint *v)
5766{
5767 UNIMPLEMENTED();
5768}
5769
5770void APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue)
5771{
5772 UNIMPLEMENTED();
5773}
5774
5775void APIENTRY glColor3sv(const GLshort *v)
5776{
5777 UNIMPLEMENTED();
5778}
5779
5780void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue)
5781{
5782 UNIMPLEMENTED();
5783}
5784
5785void APIENTRY glColor3ubv(const GLubyte *v)
5786{
5787 UNIMPLEMENTED();
5788}
5789
5790void APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue)
5791{
5792 UNIMPLEMENTED();
5793}
5794
5795void APIENTRY glColor3uiv(const GLuint *v)
5796{
5797 UNIMPLEMENTED();
5798}
5799
5800void APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue)
5801{
5802 UNIMPLEMENTED();
5803}
5804
5805void APIENTRY glColor3usv(const GLushort *v)
5806{
5807 UNIMPLEMENTED();
5808}
5809
5810void APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
5811{
5812 UNIMPLEMENTED();
5813}
5814
5815void APIENTRY glColor4bv(const GLbyte *v)
5816{
5817 UNIMPLEMENTED();
5818}
5819
5820void APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
5821{
5822 UNIMPLEMENTED();
5823}
5824
5825void APIENTRY glColor4dv(const GLdouble *v)
5826{
5827 UNIMPLEMENTED();
5828}
5829
5830void APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
5831{
5832 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);
5833
5834 gl::Context *context = gl::getContext();
5835
5836 if(context)
5837 {
5838 if(context->getListIndex() != 0)
5839 {
5840 UNIMPLEMENTED();
5841 }
5842
5843 //context->color(red, green, blue, alpha);
5844 //GLfloat vals[4] = {red, green, blue, alpha};
5845 context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
5846 }
5847}
5848
5849void APIENTRY glColor4fv(const GLfloat *v)
5850{
5851 UNIMPLEMENTED();
5852}
5853
5854void APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha)
5855{
5856 UNIMPLEMENTED();
5857}
5858
5859void APIENTRY glColor4iv(const GLint *v)
5860{
5861 UNIMPLEMENTED();
5862}
5863
5864void APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
5865{
5866 UNIMPLEMENTED();
5867}
5868
5869void APIENTRY glColor4sv(const GLshort *v)
5870{
5871 UNIMPLEMENTED();
5872}
5873
5874void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
5875{
5876 UNIMPLEMENTED();
5877}
5878
5879void APIENTRY glColor4ubv(const GLubyte *v)
5880{
5881 UNIMPLEMENTED();
5882}
5883
5884void APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
5885{
5886 UNIMPLEMENTED();
5887}
5888
5889void APIENTRY glColor4uiv(const GLuint *v)
5890{
5891 UNIMPLEMENTED();
5892}
5893
5894void APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
5895{
5896 UNIMPLEMENTED();
5897}
5898
5899void APIENTRY glColor4usv(const GLushort *v)
5900{
5901 UNIMPLEMENTED();
5902}
5903
5904void APIENTRY glColorMaterial(GLenum face, GLenum mode)
5905{
5906 TRACE("(GLenum face = 0x%X, GLenum mode = 0x%X)", face, mode);
5907
5908 // FIXME: Validate enums
5909
5910 gl::Context *context = gl::getContext();
5911
5912 if(context)
5913 {
5914 if(context->getListIndex() != 0)
5915 {
5916 UNIMPLEMENTED();
5917 }
5918
5919 switch(face)
5920 {
5921 case GL_FRONT:
5922 context->setColorMaterialMode(mode); // FIXME: Front only
5923 break;
5924 case GL_FRONT_AND_BACK:
5925 context->setColorMaterialMode(mode);
5926 break;
5927 default:
5928 UNIMPLEMENTED();
5929 return error(GL_INVALID_ENUM);
5930 }
5931 }
5932}
5933
5934void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
5935{
5936 TRACE("(*)");
5937
5938 glVertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
5939}
5940
5941void APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
5942{
5943 UNIMPLEMENTED();
5944}
5945
5946void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)
5947{
5948 UNIMPLEMENTED();
5949}
5950
5951void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
5952{
5953 UNIMPLEMENTED();
5954}
5955
5956void APIENTRY glDebugEntry()
5957{
5958 UNIMPLEMENTED();
5959}
5960
5961void APIENTRY glDeleteLists(GLuint list, GLsizei range)
5962{
5963 TRACE("(GLuint list = %d, GLsizei range = %d)", list, range);
5964
5965 if(range < 0)
5966 {
5967 return error(GL_INVALID_VALUE);
5968 }
5969
5970 gl::Context *context = gl::getContext();
5971
5972 if(context)
5973 {
Alexis Hetuf7be67f2015-02-11 16:11:07 -05005974 for(GLuint i = list; i < list + range; i++)
Nicolas Capensa9b49372015-01-30 00:33:26 -05005975 {
5976 context->deleteList(i);
5977 }
5978 }
5979}
5980
5981void APIENTRY glDepthRange(GLclampd zNear, GLclampd zFar)
5982{
5983 UNIMPLEMENTED();
5984}
5985
5986void APIENTRY glDisableClientState(GLenum array)
5987{
5988 TRACE("(GLenum array = 0x%X)", array);
5989
5990 gl::Context *context = gl::getContext();
5991
5992 if(context)
5993 {
5994 GLenum texture = context->getClientActiveTexture();
5995
5996 switch(array)
5997 {
5998 case GL_VERTEX_ARRAY: context->setEnableVertexAttribArray(sw::Position, false); break;
5999 case GL_COLOR_ARRAY: context->setEnableVertexAttribArray(sw::Color0, false); break;
6000 case GL_TEXTURE_COORD_ARRAY: context->setEnableVertexAttribArray(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
6001 case GL_NORMAL_ARRAY: context->setEnableVertexAttribArray(sw::Normal, false); break;
6002 default: UNIMPLEMENTED();
6003 }
6004 }
6005}
6006
6007void APIENTRY glDrawBuffer(GLenum mode)
6008{
6009 UNIMPLEMENTED();
6010}
6011
6012void APIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
6013{
6014 UNIMPLEMENTED();
6015}
6016
6017void APIENTRY glEdgeFlag(GLboolean flag)
6018{
6019 UNIMPLEMENTED();
6020}
6021
6022void APIENTRY glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)
6023{
6024 UNIMPLEMENTED();
6025}
6026
6027void APIENTRY glEdgeFlagv(const GLboolean *flag)
6028{
6029 UNIMPLEMENTED();
6030}
6031
6032void APIENTRY glEnableClientState(GLenum array)
6033{
6034 TRACE("(GLenum array = 0x%X)", array);
6035
6036 gl::Context *context = gl::getContext();
6037
6038 if(context)
6039 {
6040 GLenum texture = context->getClientActiveTexture();
6041
6042 switch(array)
6043 {
6044 case GL_VERTEX_ARRAY: context->setEnableVertexAttribArray(sw::Position, true); break;
6045 case GL_COLOR_ARRAY: context->setEnableVertexAttribArray(sw::Color0, true); break;
6046 case GL_TEXTURE_COORD_ARRAY: context->setEnableVertexAttribArray(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
6047 case GL_NORMAL_ARRAY: context->setEnableVertexAttribArray(sw::Normal, true); break;
6048 default: UNIMPLEMENTED();
6049 }
6050 }
6051}
6052
6053void APIENTRY glEnd()
6054{
6055 TRACE("()");
6056
6057 gl::Context *context = gl::getContext();
6058
6059 if(context)
6060 {
6061 if(context->getListIndex() != 0)
6062 {
6063 UNIMPLEMENTED();
6064 }
6065
6066 context->end();
6067 }
6068}
6069
6070void APIENTRY glEndList()
6071{
6072 TRACE("()");
6073
6074 gl::Context *context = gl::getContext();
6075
6076 if(context)
6077 {
6078 context->endList();
6079 }
6080}
6081
6082void APIENTRY glEvalCoord1d(GLdouble u)
6083{
6084 UNIMPLEMENTED();
6085}
6086
6087void APIENTRY glEvalCoord1dv(const GLdouble *u)
6088{
6089 UNIMPLEMENTED();
6090}
6091
6092void APIENTRY glEvalCoord1f(GLfloat u)
6093{
6094 UNIMPLEMENTED();
6095}
6096
6097void APIENTRY glEvalCoord1fv(const GLfloat *u)
6098{
6099 UNIMPLEMENTED();
6100}
6101
6102void APIENTRY glEvalCoord2d(GLdouble u, GLdouble v)
6103{
6104 UNIMPLEMENTED();
6105}
6106
6107void APIENTRY glEvalCoord2dv(const GLdouble *u)
6108{
6109 UNIMPLEMENTED();
6110}
6111
6112void APIENTRY glEvalCoord2f(GLfloat u, GLfloat v)
6113{
6114 UNIMPLEMENTED();
6115}
6116
6117void APIENTRY glEvalCoord2fv(const GLfloat *u)
6118{
6119 UNIMPLEMENTED();
6120}
6121
6122void APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2)
6123{
6124 UNIMPLEMENTED();
6125}
6126
6127void APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
6128{
6129 UNIMPLEMENTED();
6130}
6131
6132void APIENTRY glEvalPoint1(GLint i)
6133{
6134 UNIMPLEMENTED();
6135}
6136
6137void APIENTRY glEvalPoint2(GLint i, GLint j)
6138{
6139 UNIMPLEMENTED();
6140}
6141
6142void APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
6143{
6144 UNIMPLEMENTED();
6145}
6146
6147void APIENTRY glFogf(GLenum pname, GLfloat param)
6148{
6149 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
6150
6151 gl::Context *context = gl::getContext();
6152
6153 if(context)
6154 {
6155 if(context->getListIndex() != 0)
6156 {
6157 UNIMPLEMENTED();
6158 }
6159
6160 gl::Device *device = gl::getDevice(); // FIXME
6161
6162 switch(pname)
6163 {
6164 case GL_FOG_START: device->setFogStart(param); break;
6165 case GL_FOG_END: device->setFogEnd(param); break;
6166 default:
6167 UNIMPLEMENTED();
6168 return error(GL_INVALID_ENUM);
6169 }
6170 }
6171}
6172
6173void APIENTRY glFogfv(GLenum pname, const GLfloat *params)
6174{
6175 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
6176
6177 gl::Context *context = gl::getContext();
6178
6179 if(context)
6180 {
6181 if(context->getListIndex() != 0)
6182 {
6183 UNIMPLEMENTED();
6184 }
6185
6186 switch(pname)
6187 {
6188 case GL_FOG_COLOR:
6189 {
6190 gl::Device *device = gl::getDevice(); // FIXME
6191 device->setFogColor(sw::Color<float>(params[0], params[1], params[2], params[3]));
6192 }
6193 break;
6194 default:
6195 UNIMPLEMENTED();
6196 return error(GL_INVALID_ENUM);
6197 }
6198 }
6199}
6200
6201void APIENTRY glFogi(GLenum pname, GLint param)
6202{
6203 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
6204
6205 gl::Context *context = gl::getContext();
6206
6207 if(context)
6208 {
6209 if(context->getListIndex() != 0)
6210 {
6211 UNIMPLEMENTED();
6212 }
6213
6214 switch(pname)
6215 {
6216 case GL_FOG_MODE:
6217 {
6218 gl::Device *device = gl::getDevice(); // FIXME
6219 switch(param)
6220 {
6221 case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
6222 default:
6223 UNIMPLEMENTED();
6224 return error(GL_INVALID_ENUM);
6225 }
6226 }
6227 break;
6228 default:
6229 UNIMPLEMENTED();
6230 return error(GL_INVALID_ENUM);
6231 }
6232 }
6233}
6234
6235void APIENTRY glFogiv(GLenum pname, const GLint *params)
6236{
6237 UNIMPLEMENTED();
6238}
6239
6240void APIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
6241{
6242 UNIMPLEMENTED();
6243}
6244
6245GLuint APIENTRY glGenLists(GLsizei range)
6246{
6247 TRACE("(GLsizei range = %d)", range);
6248
6249 if(range < 0)
6250 {
6251 return error(GL_INVALID_VALUE, 0);
6252 }
6253
6254 gl::Context *context = gl::getContext();
6255
6256 if(context)
6257 {
6258 return context->genLists(range);
6259 }
6260
6261 return 0;
6262}
6263
6264void APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation)
6265{
6266 UNIMPLEMENTED();
6267}
6268
6269void APIENTRY glGetDoublev(GLenum pname, GLdouble *params)
6270{
6271 UNIMPLEMENTED();
6272}
6273
6274void APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
6275{
6276 UNIMPLEMENTED();
6277}
6278
6279void APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params)
6280{
6281 UNIMPLEMENTED();
6282}
6283
6284void APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v)
6285{
6286 UNIMPLEMENTED();
6287}
6288
6289void APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v)
6290{
6291 UNIMPLEMENTED();
6292}
6293
6294void APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v)
6295{
6296 UNIMPLEMENTED();
6297}
6298
6299void APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
6300{
6301 UNIMPLEMENTED();
6302}
6303
6304void APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params)
6305{
6306 UNIMPLEMENTED();
6307}
6308
6309void APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values)
6310{
6311 UNIMPLEMENTED();
6312}
6313
6314void APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values)
6315{
6316 UNIMPLEMENTED();
6317}
6318
6319void APIENTRY glGetPixelMapusv(GLenum map, GLushort *values)
6320{
6321 UNIMPLEMENTED();
6322}
6323
6324void APIENTRY glGetPointerv(GLenum pname, GLvoid* *params)
6325{
6326 UNIMPLEMENTED();
6327}
6328
6329void APIENTRY glGetPolygonStipple(GLubyte *mask)
6330{
6331 UNIMPLEMENTED();
6332}
6333
6334void APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
6335{
6336 UNIMPLEMENTED();
6337}
6338
6339void APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params)
6340{
6341 UNIMPLEMENTED();
6342}
6343
6344void APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
6345{
6346 UNIMPLEMENTED();
6347}
6348
6349void APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
6350{
6351 UNIMPLEMENTED();
6352}
6353
6354void APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
6355{
6356 UNIMPLEMENTED();
6357}
6358
6359void APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
6360{
6361 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum format = 0x%X, GLenum type = 0x%X, GLint *pixels0x%0.8p)", target, level, format, type, pixels);
6362
6363 gl::Context *context = gl::getContext();
6364
6365 if(context)
6366 {
6367 gl::Texture *texture;
6368
6369 switch(target)
6370 {
6371 case GL_TEXTURE_2D:
6372 texture = context->getTexture2D(target);
6373 break;
6374 case GL_TEXTURE_CUBE_MAP:
6375 texture = context->getTextureCubeMap();
6376 break;
6377 default:
6378 UNIMPLEMENTED();
6379 return error(GL_INVALID_ENUM);
6380 }
6381
6382 if(format == texture->getFormat(target, level) && type == texture->getType(target, level))
6383 {
6384 gl::Image *image = texture->getRenderTarget(target, level);
6385 void *source = image->lock(0, 0, sw::LOCK_READONLY);
6386 memcpy(pixels, source, image->getPitch() * image->getHeight());
6387 image->unlock();
6388 }
6389 else
6390 {
6391 UNIMPLEMENTED();
6392 }
6393 }
6394}
6395
6396void APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
6397{
6398 UNIMPLEMENTED();
6399}
6400
6401void APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
6402{
6403 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, level, pname, params);
6404
6405 gl::Context *context = gl::getContext();
6406
6407 if(context)
6408 {
6409 gl::Texture *texture;
6410
6411 switch(target)
6412 {
6413 case GL_TEXTURE_2D:
6414 case GL_PROXY_TEXTURE_2D:
6415 texture = context->getTexture2D(target);
6416 break;
6417 case GL_TEXTURE_CUBE_MAP:
6418 texture = context->getTextureCubeMap();
6419 break;
6420 default:
6421 UNIMPLEMENTED();
6422 return error(GL_INVALID_ENUM);
6423 }
6424
6425 switch(pname)
6426 {
6427 case GL_TEXTURE_MAG_FILTER:
6428 *params = texture->getMagFilter();
6429 break;
6430 case GL_TEXTURE_MIN_FILTER:
6431 *params = texture->getMinFilter();
6432 break;
6433 case GL_TEXTURE_WRAP_S:
6434 *params = texture->getWrapS();
6435 break;
6436 case GL_TEXTURE_WRAP_T:
6437 *params = texture->getWrapT();
6438 break;
6439 case GL_TEXTURE_WIDTH:
6440 *params = texture->getWidth(target, level);
6441 break;
6442 case GL_TEXTURE_HEIGHT:
6443 *params = texture->getHeight(target, level);
6444 break;
6445 case GL_TEXTURE_INTERNAL_FORMAT:
6446 *params = texture->getInternalFormat(target, level);
6447 break;
6448 case GL_TEXTURE_BORDER_COLOR:
6449 UNIMPLEMENTED();
6450 break;
6451 case GL_TEXTURE_BORDER:
6452 UNIMPLEMENTED();
6453 break;
6454 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6455 *params = (GLint)texture->getMaxAnisotropy();
6456 break;
6457 default:
6458 return error(GL_INVALID_ENUM);
6459 }
6460 }
6461}
6462
6463void APIENTRY glIndexMask(GLuint mask)
6464{
6465 UNIMPLEMENTED();
6466}
6467
6468void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
6469{
6470 UNIMPLEMENTED();
6471}
6472
6473void APIENTRY glIndexd(GLdouble c)
6474{
6475 UNIMPLEMENTED();
6476}
6477
6478void APIENTRY glIndexdv(const GLdouble *c)
6479{
6480 UNIMPLEMENTED();
6481}
6482
6483void APIENTRY glIndexf(GLfloat c)
6484{
6485 UNIMPLEMENTED();
6486}
6487
6488void APIENTRY glIndexfv(const GLfloat *c)
6489{
6490 UNIMPLEMENTED();
6491}
6492
6493void APIENTRY glIndexi(GLint c)
6494{
6495 UNIMPLEMENTED();
6496}
6497
6498void APIENTRY glIndexiv(const GLint *c)
6499{
6500 UNIMPLEMENTED();
6501}
6502
6503void APIENTRY glIndexs(GLshort c)
6504{
6505 UNIMPLEMENTED();
6506}
6507
6508void APIENTRY glIndexsv(const GLshort *c)
6509{
6510 UNIMPLEMENTED();
6511}
6512
6513void APIENTRY glIndexub(GLubyte c)
6514{
6515 UNIMPLEMENTED();
6516}
6517
6518void APIENTRY glIndexubv(const GLubyte *c)
6519{
6520 UNIMPLEMENTED();
6521}
6522
6523void APIENTRY glInitNames(void)
6524{
6525 UNIMPLEMENTED();
6526}
6527
6528void APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
6529{
6530 UNIMPLEMENTED();
6531}
6532
6533GLboolean APIENTRY glIsList(GLuint list)
6534{
6535 UNIMPLEMENTED();
6536 return GL_FALSE;
6537}
6538
6539void APIENTRY glLightModelf(GLenum pname, GLfloat param)
6540{
6541 UNIMPLEMENTED();
6542}
6543
6544void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
6545{
6546 TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
6547
6548 gl::Context *context = gl::getContext();
6549
6550 if(context)
6551 {
6552 if(context->getListIndex() != 0)
6553 {
6554 UNIMPLEMENTED();
6555 }
6556
6557 gl::Device *device = gl::getDevice(); // FIXME
6558
6559 switch(pname)
6560 {
6561 case GL_LIGHT_MODEL_AMBIENT:
6562 device->setGlobalAmbient(sw::Color<float>(params[0], params[1], params[2], params[3]));
6563 break;
6564 default:
6565 UNIMPLEMENTED();
6566 return error(GL_INVALID_ENUM);
6567 }
6568 }
6569}
6570
6571void APIENTRY glLightModeli(GLenum pname, GLint param)
6572{
6573 UNIMPLEMENTED();
6574}
6575
6576void APIENTRY glLightModeliv(GLenum pname, const GLint *params)
6577{
6578 TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
6579 UNIMPLEMENTED();
6580}
6581
6582void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
6583{
6584 UNIMPLEMENTED();
6585}
6586
6587void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
6588{
6589 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
6590
6591 gl::Context *context = gl::getContext();
6592
6593 if(context)
6594 {
6595 if(context->getListIndex() != 0)
6596 {
6597 UNIMPLEMENTED();
6598 }
6599
6600 gl::Device *device = gl::getDevice(); // FIXME
6601
6602 switch(pname)
6603 {
6604 case GL_AMBIENT: device->setLightAmbient(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6605 case GL_DIFFUSE: device->setLightDiffuse(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6606 case GL_SPECULAR: device->setLightSpecular(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6607 case GL_POSITION:
6608 if(params[3] == 0.0f) // Directional light
6609 {
6610 // Create a very far out point light
6611 float max = std::max(std::max(abs(params[0]), abs(params[1])), abs(params[2]));
6612 device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / max * 1e10f, params[1] / max * 1e10f, params[2] / max * 1e10f));
6613 }
6614 else
6615 {
6616 device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / params[3], params[1] / params[3], params[2] / params[3]));
6617 }
6618 break;
6619 default:
6620 UNIMPLEMENTED();
6621 return error(GL_INVALID_ENUM);
6622 }
6623 }
6624}
6625
6626void APIENTRY glLighti(GLenum light, GLenum pname, GLint param)
6627{
6628 UNIMPLEMENTED();
6629}
6630
6631void APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params)
6632{
6633 UNIMPLEMENTED();
6634}
6635
6636void APIENTRY glLineStipple(GLint factor, GLushort pattern)
6637{
6638 UNIMPLEMENTED();
6639}
6640
6641void APIENTRY glListBase(GLuint base)
6642{
6643 UNIMPLEMENTED();
6644}
6645
6646void APIENTRY glLoadIdentity()
6647{
6648 TRACE("()");
6649
6650 gl::Context *context = gl::getContext();
6651
6652 if(context)
6653 {
6654 if(context->getListIndex() != 0)
6655 {
6656 UNIMPLEMENTED();
6657 }
6658
6659 context->loadIdentity();
6660 }
6661}
6662
6663void APIENTRY glLoadMatrixd(const GLdouble *m)
6664{
6665 UNIMPLEMENTED();
6666}
6667
6668void APIENTRY glLoadMatrixf(const GLfloat *m)
6669{
6670 UNIMPLEMENTED();
6671}
6672
6673void APIENTRY glLoadName(GLuint name)
6674{
6675 UNIMPLEMENTED();
6676}
6677
6678void APIENTRY glLogicOp(GLenum opcode)
6679{
6680 UNIMPLEMENTED();
6681}
6682
6683void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
6684{
6685 UNIMPLEMENTED();
6686}
6687
6688void APIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
6689{
6690 UNIMPLEMENTED();
6691}
6692
6693void APIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)
6694{
6695 UNIMPLEMENTED();
6696}
6697
6698void APIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)
6699{
6700 UNIMPLEMENTED();
6701}
6702
6703void APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
6704{
6705 UNIMPLEMENTED();
6706}
6707
6708void APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
6709{
6710 UNIMPLEMENTED();
6711}
6712
6713void APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
6714{
6715 UNIMPLEMENTED();
6716}
6717
6718void APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
6719{
6720 UNIMPLEMENTED();
6721}
6722
6723void APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
6724{
6725 UNIMPLEMENTED();
6726}
6727
6728void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
6729{
6730 UNIMPLEMENTED();
6731}
6732
6733void APIENTRY glMateriali(GLenum face, GLenum pname, GLint param)
6734{
6735 UNIMPLEMENTED();
6736}
6737
6738void APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params)
6739{
6740 UNIMPLEMENTED();
6741}
6742
6743void APIENTRY glMatrixMode(GLenum mode)
6744{
6745 TRACE("(*)");
6746
6747 gl::Context *context = gl::getContext();
6748
6749 if(context)
6750 {
6751 if(context->getListIndex() != 0)
6752 {
6753 UNIMPLEMENTED();
6754 }
6755
6756 context->setMatrixMode(mode);
6757 }
6758}
6759
6760void APIENTRY glMultMatrixd(const GLdouble *m)
6761{
Maxime Gregoire53ff8d82015-03-04 14:51:58 -05006762 TRACE("(*)");
6763
6764 gl::Context *context = gl::getContext();
6765
6766 if(context)
6767 {
6768 if(context->getListIndex() != 0)
6769 {
6770 UNIMPLEMENTED();
6771 }
6772
6773 context->multiply(m);
6774 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05006775}
6776
6777void APIENTRY glMultMatrixm(sw::Matrix m)
6778{
6779 gl::Context *context = gl::getContext();
6780
6781 if(context)
6782 {
6783 context->multiply((GLfloat*)m.m);
6784 }
6785}
6786
6787void APIENTRY glMultMatrixf(const GLfloat *m)
6788{
6789 TRACE("(*)");
6790
6791 gl::Context *context = gl::getContext();
6792
6793 if(context)
6794 {
6795 if(context->getListIndex() != 0)
6796 {
6797 return context->listCommand(gl::newCommand(glMultMatrixm, sw::Matrix(m)));
6798 }
6799
6800 context->multiply(m);
6801 }
6802}
6803
6804void APIENTRY glNewList(GLuint list, GLenum mode)
6805{
6806 TRACE("(GLuint list = %d, GLenum mode = 0x%X)", list, mode);
6807
6808 if(list == 0)
6809 {
6810 return error(GL_INVALID_VALUE);
6811 }
6812
6813 switch(mode)
6814 {
6815 case GL_COMPILE:
6816 case GL_COMPILE_AND_EXECUTE:
6817 break;
6818 default:
6819 return error(GL_INVALID_ENUM);
6820 }
6821
6822 gl::Context *context = gl::getContext();
6823
6824 if(context)
6825 {
6826 if(context->getListIndex() != 0)
6827 {
6828 UNIMPLEMENTED();
6829 }
6830
6831 context->newList(list, mode);
6832 }
6833}
6834
6835void APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
6836{
6837 UNIMPLEMENTED();
6838}
6839
6840void APIENTRY glNormal3bv(const GLbyte *v)
6841{
6842 UNIMPLEMENTED();
6843}
6844
6845void APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
6846{
6847 UNIMPLEMENTED();
6848}
6849
6850void APIENTRY glNormal3dv(const GLdouble *v)
6851{
6852 UNIMPLEMENTED();
6853}
6854
6855void APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
6856{
6857 TRACE("(GLfloat nx = %f, GLfloat ny = %f, GLfloat nz = %f)", nx, ny, nz);
6858
6859 gl::Context *context = gl::getContext();
6860
6861 if(context)
6862 {
6863 if(context->getListIndex() != 0)
6864 {
6865 UNIMPLEMENTED();
6866 }
6867
6868 //context->normal(nx, ny, nz);
6869 context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
6870 }
6871}
6872
6873void APIENTRY glNormal3fv(const GLfloat *v)
6874{
6875 UNIMPLEMENTED();
6876}
6877
6878void APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz)
6879{
6880 UNIMPLEMENTED();
6881}
6882
6883void APIENTRY glNormal3iv(const GLint *v)
6884{
6885 UNIMPLEMENTED();
6886}
6887
6888void APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz)
6889{
6890 UNIMPLEMENTED();
6891}
6892
6893void APIENTRY glNormal3sv(const GLshort *v)
6894{
6895 UNIMPLEMENTED();
6896}
6897
6898void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
6899{
6900 TRACE("(*)");
6901
6902 glVertexAttribPointer(sw::Normal, 3, type, false, stride, pointer);
6903}
6904
6905void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
6906{
6907 TRACE("(*)");
6908
6909 gl::Context *context = gl::getContext();
6910
6911 if(context)
6912 {
6913 if(context->getListIndex() != 0)
6914 {
6915 UNIMPLEMENTED();
6916 }
6917
6918 context->ortho(left, right, bottom, top, zNear, zFar);
6919 }
6920}
6921
6922void APIENTRY glPassThrough(GLfloat token)
6923{
6924 UNIMPLEMENTED();
6925}
6926
6927void APIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)
6928{
6929 UNIMPLEMENTED();
6930}
6931
6932void APIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)
6933{
6934 UNIMPLEMENTED();
6935}
6936
6937void APIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)
6938{
6939 UNIMPLEMENTED();
6940}
6941
6942void APIENTRY glPixelStoref(GLenum pname, GLfloat param)
6943{
6944 UNIMPLEMENTED();
6945}
6946
6947void APIENTRY glPixelTransferf(GLenum pname, GLfloat param)
6948{
6949 UNIMPLEMENTED();
6950}
6951
6952void APIENTRY glPixelTransferi(GLenum pname, GLint param)
6953{
6954 UNIMPLEMENTED();
6955}
6956
6957void APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
6958{
6959 UNIMPLEMENTED();
6960}
6961
6962void APIENTRY glPointSize(GLfloat size)
6963{
6964 UNIMPLEMENTED();
6965}
6966
6967void APIENTRY glPolygonMode(GLenum face, GLenum mode)
6968{
6969 UNIMPLEMENTED();
6970}
6971
6972void APIENTRY glPolygonStipple(const GLubyte *mask)
6973{
6974 UNIMPLEMENTED();
6975}
6976
6977void APIENTRY glPopAttrib(void)
6978{
6979 UNIMPLEMENTED();
6980}
6981
6982void APIENTRY glPopClientAttrib(void)
6983{
6984 UNIMPLEMENTED();
6985}
6986
6987void APIENTRY glPopMatrix(void)
6988{
6989 TRACE("()");
6990
6991 gl::Context *context = gl::getContext();
6992
6993 if(context)
6994 {
6995 if(context->getListIndex() != 0)
6996 {
6997 return context->listCommand(gl::newCommand(glPopMatrix));
6998 }
6999
7000 context->popMatrix();
7001 }
7002}
7003
7004void APIENTRY glPopName(void)
7005{
7006 UNIMPLEMENTED();
7007}
7008
7009void APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities)
7010{
7011 UNIMPLEMENTED();
7012}
7013
7014void APIENTRY glPushAttrib(GLbitfield mask)
7015{
7016 UNIMPLEMENTED();
7017}
7018
7019void APIENTRY glPushClientAttrib(GLbitfield mask)
7020{
7021 UNIMPLEMENTED();
7022}
7023
7024void APIENTRY glPushMatrix(void)
7025{
7026 TRACE("()");
7027
7028 gl::Context *context = gl::getContext();
7029
7030 if(context)
7031 {
7032 if(context->getListIndex() != 0)
7033 {
7034 return context->listCommand(gl::newCommand(glPushMatrix));
7035 }
7036
7037 context->pushMatrix();
7038 }
7039}
7040
7041void APIENTRY glPushName(GLuint name)
7042{
7043 UNIMPLEMENTED();
7044}
7045
7046void APIENTRY glRasterPos2d(GLdouble x, GLdouble y)
7047{
7048 UNIMPLEMENTED();
7049}
7050
7051void APIENTRY glRasterPos2dv(const GLdouble *v)
7052{
7053 UNIMPLEMENTED();
7054}
7055
7056void APIENTRY glRasterPos2f(GLfloat x, GLfloat y)
7057{
7058 UNIMPLEMENTED();
7059}
7060
7061void APIENTRY glRasterPos2fv(const GLfloat *v)
7062{
7063 UNIMPLEMENTED();
7064}
7065
7066void APIENTRY glRasterPos2i(GLint x, GLint y)
7067{
7068 UNIMPLEMENTED();
7069}
7070
7071void APIENTRY glRasterPos2iv(const GLint *v)
7072{
7073 UNIMPLEMENTED();
7074}
7075
7076void APIENTRY glRasterPos2s(GLshort x, GLshort y)
7077{
7078 UNIMPLEMENTED();
7079}
7080
7081void APIENTRY glRasterPos2sv(const GLshort *v)
7082{
7083 UNIMPLEMENTED();
7084}
7085
7086void APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
7087{
7088 UNIMPLEMENTED();
7089}
7090
7091void APIENTRY glRasterPos3dv(const GLdouble *v)
7092{
7093 UNIMPLEMENTED();
7094}
7095
7096void APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
7097{
7098 UNIMPLEMENTED();
7099}
7100
7101void APIENTRY glRasterPos3fv(const GLfloat *v)
7102{
7103 UNIMPLEMENTED();
7104}
7105
7106void APIENTRY glRasterPos3i(GLint x, GLint y, GLint z)
7107{
7108 UNIMPLEMENTED();
7109}
7110
7111void APIENTRY glRasterPos3iv(const GLint *v)
7112{
7113 UNIMPLEMENTED();
7114}
7115
7116void APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z)
7117{
7118 UNIMPLEMENTED();
7119}
7120
7121void APIENTRY glRasterPos3sv(const GLshort *v)
7122{
7123 UNIMPLEMENTED();
7124}
7125
7126void APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
7127{
7128 UNIMPLEMENTED();
7129}
7130
7131void APIENTRY glRasterPos4dv(const GLdouble *v)
7132{
7133 UNIMPLEMENTED();
7134}
7135
7136void APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
7137{
7138 UNIMPLEMENTED();
7139}
7140
7141void APIENTRY glRasterPos4fv(const GLfloat *v)
7142{
7143 UNIMPLEMENTED();
7144}
7145
7146void APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w)
7147{
7148 UNIMPLEMENTED();
7149}
7150
7151void APIENTRY glRasterPos4iv(const GLint *v)
7152{
7153 UNIMPLEMENTED();
7154}
7155
7156void APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
7157{
7158 UNIMPLEMENTED();
7159}
7160
7161void APIENTRY glRasterPos4sv(const GLshort *v)
7162{
7163 UNIMPLEMENTED();
7164}
7165
7166void APIENTRY glReadBuffer(GLenum mode)
7167{
7168 UNIMPLEMENTED();
7169}
7170
7171void APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
7172{
7173 UNIMPLEMENTED();
7174}
7175
7176void APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2)
7177{
7178 UNIMPLEMENTED();
7179}
7180
7181void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
7182{
7183 UNIMPLEMENTED();
7184}
7185
7186void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2)
7187{
7188 UNIMPLEMENTED();
7189}
7190
7191void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2)
7192{
7193 UNIMPLEMENTED();
7194}
7195
7196void APIENTRY glRectiv(const GLint *v1, const GLint *v2)
7197{
7198 UNIMPLEMENTED();
7199}
7200
7201void APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
7202{
7203 UNIMPLEMENTED();
7204}
7205
7206void APIENTRY glRectsv(const GLshort *v1, const GLshort *v2)
7207{
7208 UNIMPLEMENTED();
7209}
7210
7211GLint APIENTRY glRenderMode(GLenum mode)
7212{
7213 UNIMPLEMENTED();
7214 return 0;
7215}
7216
7217void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
7218{
7219 UNIMPLEMENTED();
7220}
7221
7222void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
7223{
7224 TRACE("(*)");
7225
7226 gl::Context *context = gl::getContext();
7227
7228 if(context)
7229 {
7230 if(context->getListIndex() != 0)
7231 {
7232 UNIMPLEMENTED();
7233 }
7234
7235 context->rotate(angle, x, y, z);
7236 }
7237}
7238
7239void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)
7240{
7241 UNIMPLEMENTED();
7242}
7243
7244void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
7245{
7246 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7247
7248 gl::Context *context = gl::getContext();
7249
7250 if(context)
7251 {
7252 if(context->getListIndex() != 0)
7253 {
7254 return context->listCommand(gl::newCommand(glScalef, x, y, z));
7255 }
7256
7257 context->scale(x, y, z);
7258 }
7259}
7260
7261void APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer)
7262{
7263 UNIMPLEMENTED();
7264}
7265
7266void APIENTRY glShadeModel(GLenum mode)
7267{
7268 TRACE("(*)");
7269
7270 gl::Context *context = gl::getContext();
7271
7272 if(context)
7273 {
7274 if(context->getListIndex() != 0)
7275 {
7276 UNIMPLEMENTED();
7277 }
7278
7279 context->setShadeModel(mode);
7280 }
7281}
7282
7283void APIENTRY glTexCoord1d(GLdouble s)
7284{
7285 UNIMPLEMENTED();
7286}
7287
7288void APIENTRY glTexCoord1dv(const GLdouble *v)
7289{
7290 UNIMPLEMENTED();
7291}
7292
7293void APIENTRY glTexCoord1f(GLfloat s)
7294{
7295 UNIMPLEMENTED();
7296}
7297
7298void APIENTRY glTexCoord1fv(const GLfloat *v)
7299{
7300 UNIMPLEMENTED();
7301}
7302
7303void APIENTRY glTexCoord1i(GLint s)
7304{
7305 UNIMPLEMENTED();
7306}
7307
7308void APIENTRY glTexCoord1iv(const GLint *v)
7309{
7310 UNIMPLEMENTED();
7311}
7312
7313void APIENTRY glTexCoord1s(GLshort s)
7314{
7315 UNIMPLEMENTED();
7316}
7317
7318void APIENTRY glTexCoord1sv(const GLshort *v)
7319{
7320 UNIMPLEMENTED();
7321}
7322
7323void APIENTRY glTexCoord2d(GLdouble s, GLdouble t)
7324{
7325 UNIMPLEMENTED();
7326}
7327
7328void APIENTRY glTexCoord2dv(const GLdouble *v)
7329{
7330 UNIMPLEMENTED();
7331}
7332
7333void APIENTRY glTexCoord2f(GLfloat s, GLfloat t)
7334{
7335 TRACE("(GLfloat s = %f, GLfloat t = %f)", s, t);
7336
7337 gl::Context *context = gl::getContext();
7338
7339 if(context)
7340 {
7341 if(context->getListIndex() != 0)
7342 {
7343 UNIMPLEMENTED();
7344 }
7345
7346 //context->texCoord(s, t, 0.0f, 1.0f);
7347 unsigned int texture = context->getActiveTexture();
7348 context->setVertexAttrib(sw::TexCoord0/* + texture*/, s, t, 0.0f, 1.0f);
7349 }
7350}
7351
7352void APIENTRY glTexCoord2fv(const GLfloat *v)
7353{
7354 UNIMPLEMENTED();
7355}
7356
7357void APIENTRY glTexCoord2i(GLint s, GLint t)
7358{
7359 UNIMPLEMENTED();
7360}
7361
7362void APIENTRY glTexCoord2iv(const GLint *v)
7363{
7364 UNIMPLEMENTED();
7365}
7366
7367void APIENTRY glTexCoord2s(GLshort s, GLshort t)
7368{
7369 UNIMPLEMENTED();
7370}
7371
7372void APIENTRY glTexCoord2sv(const GLshort *v)
7373{
7374 UNIMPLEMENTED();
7375}
7376
7377void APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
7378{
7379 UNIMPLEMENTED();
7380}
7381
7382void APIENTRY glTexCoord3dv(const GLdouble *v)
7383{
7384 UNIMPLEMENTED();
7385}
7386
7387void APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
7388{
7389 UNIMPLEMENTED();
7390}
7391
7392void APIENTRY glTexCoord3fv(const GLfloat *v)
7393{
7394 UNIMPLEMENTED();
7395}
7396
7397void APIENTRY glTexCoord3i(GLint s, GLint t, GLint r)
7398{
7399 UNIMPLEMENTED();
7400}
7401
7402void APIENTRY glTexCoord3iv(const GLint *v)
7403{
7404 UNIMPLEMENTED();
7405}
7406
7407void APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r)
7408{
7409 UNIMPLEMENTED();
7410}
7411
7412void APIENTRY glTexCoord3sv(const GLshort *v)
7413{
7414 UNIMPLEMENTED();
7415}
7416
7417void APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
7418{
7419 UNIMPLEMENTED();
7420}
7421
7422void APIENTRY glTexCoord4dv(const GLdouble *v)
7423{
7424 UNIMPLEMENTED();
7425}
7426
7427void APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
7428{
7429 UNIMPLEMENTED();
7430}
7431
7432void APIENTRY glTexCoord4fv(const GLfloat *v)
7433{
7434 UNIMPLEMENTED();
7435}
7436
7437void APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q)
7438{
7439 UNIMPLEMENTED();
7440}
7441
7442void APIENTRY glTexCoord4iv(const GLint *v)
7443{
7444 UNIMPLEMENTED();
7445}
7446
7447void APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
7448{
7449 UNIMPLEMENTED();
7450}
7451
7452void APIENTRY glTexCoord4sv(const GLshort *v)
7453{
7454 UNIMPLEMENTED();
7455}
7456
7457void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
7458{
7459 TRACE("(*)");
7460
7461 gl::Context *context = gl::getContext();
7462
7463 if(context)
7464 {
7465 GLenum texture = context->getClientActiveTexture();
7466
7467 glVertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
7468 }
7469}
7470
7471void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
7472{
7473 UNIMPLEMENTED();
7474}
7475
7476void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
7477{
7478 UNIMPLEMENTED();
7479}
7480
7481void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
7482{
7483 UNIMPLEMENTED();
7484}
7485
7486void APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
7487{
7488 UNIMPLEMENTED();
7489}
7490
7491void APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param)
7492{
7493 UNIMPLEMENTED();
7494}
7495
7496void APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
7497{
7498 UNIMPLEMENTED();
7499}
7500
7501void APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param)
7502{
7503 UNIMPLEMENTED();
7504}
7505
7506void APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
7507{
7508 UNIMPLEMENTED();
7509}
7510
7511void APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param)
7512{
7513 UNIMPLEMENTED();
7514}
7515
7516void APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params)
7517{
7518 UNIMPLEMENTED();
7519}
7520
7521void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
7522{
7523 UNIMPLEMENTED();
7524}
7525
7526void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
7527{
7528 UNIMPLEMENTED();
7529}
7530
7531void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)
7532{
7533 TRACE("(*)");
7534
7535 gl::Context *context = gl::getContext();
7536
7537 if(context)
7538 {
7539 if(context->getListIndex() != 0)
7540 {
7541 return context->listCommand(gl::newCommand(glTranslated, x, y, z));
7542 }
7543
7544 context->translate(x, y, z); // FIXME
7545 }
7546}
7547
7548void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
7549{
7550 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7551
7552 gl::Context *context = gl::getContext();
7553
7554 if(context)
7555 {
7556 if(context->getListIndex() != 0)
7557 {
7558 return context->listCommand(gl::newCommand(glTranslatef, x, y, z));
7559 }
7560
7561 context->translate(x, y, z);
7562 }
7563}
7564
7565void APIENTRY glVertex2d(GLdouble x, GLdouble y)
7566{
7567 UNIMPLEMENTED();
7568}
7569
7570void APIENTRY glVertex2dv(const GLdouble *v)
7571{
7572 UNIMPLEMENTED();
7573}
7574
7575void APIENTRY glVertex2f(GLfloat x, GLfloat y)
7576{
7577 UNIMPLEMENTED();
7578}
7579
7580void APIENTRY glVertex2fv(const GLfloat *v)
7581{
7582 UNIMPLEMENTED();
7583}
7584
7585void APIENTRY glVertex2i(GLint x, GLint y)
7586{
7587 UNIMPLEMENTED();
7588}
7589
7590void APIENTRY glVertex2iv(const GLint *v)
7591{
7592 UNIMPLEMENTED();
7593}
7594
7595void APIENTRY glVertex2s(GLshort x, GLshort y)
7596{
7597 UNIMPLEMENTED();
7598}
7599
7600void APIENTRY glVertex2sv(const GLshort *v)
7601{
7602 UNIMPLEMENTED();
7603}
7604
7605void APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
7606{
7607 UNIMPLEMENTED();
7608}
7609
7610void APIENTRY glVertex3dv(const GLdouble *v)
7611{
7612 UNIMPLEMENTED();
7613}
7614
7615void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
7616{
7617 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7618
7619 gl::Context *context = gl::getContext();
7620
7621 if(context)
7622 {
7623 if(context->getListIndex() != 0)
7624 {
7625 UNIMPLEMENTED();
7626 }
7627
7628 context->position(x, y, z, 1.0f);
7629 }
7630}
7631
7632void APIENTRY glVertex3fv(const GLfloat *v)
7633{
7634 UNIMPLEMENTED();
7635}
7636
7637void APIENTRY glVertex3i(GLint x, GLint y, GLint z)
7638{
7639 UNIMPLEMENTED();
7640}
7641
7642void APIENTRY glVertex3iv(const GLint *v)
7643{
7644 UNIMPLEMENTED();
7645}
7646
7647void APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z)
7648{
7649 UNIMPLEMENTED();
7650}
7651
7652void APIENTRY glVertex3sv(const GLshort *v)
7653{
7654 UNIMPLEMENTED();
7655}
7656
7657void APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
7658{
7659 UNIMPLEMENTED();
7660}
7661
7662void APIENTRY glVertex4dv(const GLdouble *v)
7663{
7664 UNIMPLEMENTED();
7665}
7666
7667void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
7668{
7669 UNIMPLEMENTED();
7670}
7671
7672void APIENTRY glVertex4fv(const GLfloat *v)
7673{
7674 UNIMPLEMENTED();
7675}
7676
7677void APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w)
7678{
7679 UNIMPLEMENTED();
7680}
7681
7682void APIENTRY glVertex4iv(const GLint *v)
7683{
7684 UNIMPLEMENTED();
7685}
7686
7687void APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
7688{
7689 UNIMPLEMENTED();
7690}
7691
7692void APIENTRY glVertex4sv(const GLshort *v)
7693{
7694 UNIMPLEMENTED();
7695}
7696
7697void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
7698{
7699 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = 0x%0.8p)", size, type, stride, pointer);
7700
7701 glVertexAttribPointer(sw::Position, size, type, false, stride, pointer);
7702}
7703
7704void APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) {UNIMPLEMENTED();}
7705void APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}
7706void 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();}
7707void APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
7708
7709void APIENTRY glClientActiveTexture(GLenum texture)
7710{
7711 TRACE("(GLenum texture = 0x%X)", texture);
7712
7713 switch(texture)
7714 {
7715 case GL_TEXTURE0:
7716 case GL_TEXTURE1:
7717 break;
7718 default:
7719 UNIMPLEMENTED();
7720 UNREACHABLE();
7721 }
7722
7723 gl::Context *context = gl::getContext();
7724
7725 if(context)
7726 {
7727 context->clientActiveTexture(texture);
7728 }
7729}
7730
7731void APIENTRY glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7732void APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7733void APIENTRY glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7734void 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();}
7735void APIENTRY glGetCompressedTexImage(GLenum target, GLint level, void *img) {UNIMPLEMENTED();}
7736void APIENTRY glMultiTexCoord1f(GLenum target, GLfloat s) {UNIMPLEMENTED();}
7737void APIENTRY glMultiTexCoord1d(GLenum target, GLdouble s) {UNIMPLEMENTED();}
7738
7739void APIENTRY glMultiTexCoord2f(GLenum texture, GLfloat s, GLfloat t)
7740{
7741 TRACE("(GLenum texture = 0x%X, GLfloat s = %f, GLfloat t = %f)", texture, s, t);
7742
7743 gl::Context *context = gl::getContext();
7744
7745 if(context)
7746 {
7747 if(context->getListIndex() != 0)
7748 {
7749 UNIMPLEMENTED();
7750 }
7751
7752 //context->texCoord(s, t, 0.0f, 1.0f);
7753 context->setVertexAttrib(sw::TexCoord0 + (texture - GL_TEXTURE0), s, t, 0.0f, 1.0f);
7754 }
7755}
7756
7757void APIENTRY glMultiTexCoord2d(GLenum target, GLdouble s, GLdouble t) {UNIMPLEMENTED();}
7758void APIENTRY glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {UNIMPLEMENTED();}
7759void APIENTRY glMultiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r) {UNIMPLEMENTED();}
7760void APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {UNIMPLEMENTED();}
7761void APIENTRY glMultiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) {UNIMPLEMENTED();}
7762void APIENTRY glLoadTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
7763void APIENTRY glLoadTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
7764void APIENTRY glMultTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
7765void APIENTRY glMultTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
7766void APIENTRY glFogCoordf(GLfloat coord) {UNIMPLEMENTED();}
7767void APIENTRY glFogCoordd(GLdouble coord) {UNIMPLEMENTED();}
7768void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
7769void APIENTRY glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) {UNIMPLEMENTED();}
7770void APIENTRY glPointParameteri(GLenum pname, GLint param) {UNIMPLEMENTED();}
7771void APIENTRY glPointParameterf(GLenum pname, GLfloat param) {UNIMPLEMENTED();}
7772void APIENTRY glPointParameteriv(GLenum pname, const GLint *params) {UNIMPLEMENTED();}
7773void APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params) {UNIMPLEMENTED();}
7774void APIENTRY glSecondaryColor3b(GLbyte red, GLbyte green, GLbyte blue) {UNIMPLEMENTED();}
7775void APIENTRY glSecondaryColor3f(GLfloat red, GLfloat green, GLfloat blue) {UNIMPLEMENTED();}
7776void APIENTRY glSecondaryColor3d(GLdouble red, GLdouble green, GLdouble blue) {UNIMPLEMENTED();}
7777void APIENTRY glSecondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue) {UNIMPLEMENTED();}
7778void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
7779void APIENTRY glWindowPos2f(GLfloat x, GLfloat y) {UNIMPLEMENTED();}
7780void APIENTRY glWindowPos2d(GLdouble x, GLdouble y) {UNIMPLEMENTED();}
7781void APIENTRY glWindowPos2i(GLint x, GLint y) {UNIMPLEMENTED();}
7782void APIENTRY glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) {UNIMPLEMENTED();}
7783void APIENTRY glWindowPos3d(GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
7784void APIENTRY glWindowPos3i(GLint x, GLint y, GLint z) {UNIMPLEMENTED();}
7785void APIENTRY glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data) {UNIMPLEMENTED();}
7786void *APIENTRY glMapBuffer(GLenum target, GLenum access) {UNIMPLEMENTED(); return 0;}
7787GLboolean APIENTRY glUnmapBuffer(GLenum target) {UNIMPLEMENTED(); return GL_FALSE;}
7788void APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params) {UNIMPLEMENTED();}
7789void APIENTRY glGenQueries(GLsizei n, GLuint *ids) {UNIMPLEMENTED();}
7790void APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids) {UNIMPLEMENTED();}
7791GLboolean APIENTRY glIsQuery(GLuint id) {UNIMPLEMENTED(); return 0;}
7792void APIENTRY glBeginQuery(GLenum target, GLuint id) {UNIMPLEMENTED();}
7793void APIENTRY glEndQuery(GLenum target) {UNIMPLEMENTED();}
7794void APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params) {UNIMPLEMENTED();}
7795void APIENTRY glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) {UNIMPLEMENTED();}
7796void APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) {UNIMPLEMENTED();}
7797void APIENTRY glVertexAttrib1s(GLuint index, GLshort x) {UNIMPLEMENTED();}
7798void APIENTRY glVertexAttrib1d(GLuint index, GLdouble x) {UNIMPLEMENTED();}
7799void APIENTRY glVertexAttrib2s(GLuint index, GLshort x, GLshort y) {UNIMPLEMENTED();}
7800void APIENTRY glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y) {UNIMPLEMENTED();}
7801void APIENTRY glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z) {UNIMPLEMENTED();}
7802void APIENTRY glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
7803void APIENTRY glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) {UNIMPLEMENTED();}
7804void APIENTRY glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {UNIMPLEMENTED();}
7805void APIENTRY glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {UNIMPLEMENTED();}
7806void APIENTRY glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {UNIMPLEMENTED();}
7807void APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs) {UNIMPLEMENTED();}
7808void APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7809void APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7810void APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7811void APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7812void APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7813void APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7814
7815void APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {UNIMPLEMENTED();}
7816void APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
7817void APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {UNIMPLEMENTED();}
7818
7819BOOL WINAPI wglSwapIntervalEXT(int interval)
7820{
7821 gl::Surface *drawSurface = static_cast<gl::Surface*>(gl::getCurrentDrawSurface());
7822
7823 if(drawSurface)
7824 {
7825 drawSurface->setSwapInterval(interval);
7826 return TRUE;
7827 }
7828
7829 SetLastError(ERROR_DC_NOT_FOUND);
7830 return FALSE;
7831}
7832
7833int WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)
7834{
7835 TRACE("(*)");
7836
7837 return 1;
7838}
7839
7840BOOL WINAPI wglCopyContext(HGLRC, HGLRC, UINT)
7841{
7842 UNIMPLEMENTED();
7843 return FALSE;
7844}
7845
7846HGLRC WINAPI wglCreateContext(HDC hdc)
7847{
7848 TRACE("(*)");
7849
7850 gl::Display *display = gl::Display::getDisplay(hdc);
7851 display->initialize();
7852
7853 gl::Context *context = display->createContext(nullptr);
7854
7855 return (HGLRC)context;
7856}
7857
7858HGLRC WINAPI wglCreateLayerContext(HDC, int)
7859{
7860 UNIMPLEMENTED();
7861 return 0;
7862}
7863
7864BOOL WINAPI wglDeleteContext(HGLRC context)
7865{
7866 gl::Display *display = gl::getDisplay();
7867
7868 if(display && context)
7869 {
7870 display->destroyContext(reinterpret_cast<gl::Context*>(context));
7871
7872 return TRUE;
7873 }
7874
7875 return FALSE;
7876}
7877
7878BOOL WINAPI wglDescribeLayerPlane(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR)
7879{
7880 UNIMPLEMENTED();
7881 return FALSE;
7882}
7883
7884int WINAPI wglDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
7885{
7886 TRACE("(*)");
7887
7888 ASSERT(nBytes == sizeof(PIXELFORMATDESCRIPTOR)); // FIXME
7889
7890 ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
7891 ppfd->nVersion = 1;
7892 ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
7893 ppfd->iPixelType = PFD_TYPE_RGBA;
7894 ppfd->cColorBits = 32;
7895 ppfd->cRedBits = 8;
7896 ppfd->cRedShift = 16;
7897 ppfd->cGreenBits = 8;
7898 ppfd->cGreenShift = 8;
7899 ppfd->cBlueBits = 8;
7900 ppfd->cBlueShift = 0;
7901 ppfd->cAlphaBits = 0;
7902 ppfd->cAlphaShift = 24;
7903 ppfd->cAccumBits = 0;
7904 ppfd->cAccumRedBits = 0;
7905 ppfd->cAccumGreenBits = 0;
7906 ppfd->cAccumBlueBits = 0;
7907 ppfd->cAccumAlphaBits = 0;
7908 ppfd->cDepthBits = 24;
7909 ppfd->cStencilBits = 0;
7910 ppfd->cAuxBuffers = 0;
7911 ppfd->iLayerType = 0;
7912 ppfd->bReserved = 0;
7913 ppfd->dwLayerMask = 0;
7914 ppfd->dwVisibleMask = 0;
7915 ppfd->dwDamageMask = 0;
7916
7917 return 1;
7918}
7919
7920HGLRC WINAPI wglGetCurrentContext(VOID)
7921{
7922 TRACE("(*)");
7923 return (HGLRC)gl::getContext();
7924}
7925
7926HDC WINAPI wglGetCurrentDC(VOID)
7927{
7928 TRACE("(*)");
7929 gl::Display *display = gl::getDisplay();
7930 return display ? display->getNativeDisplay() : 0;
7931}
7932
7933void WINAPI wglGetDefaultProcAddress()
7934{
7935 UNIMPLEMENTED();
7936}
7937
7938int WINAPI wglGetLayerPaletteEntries(HDC, int, int, int, COLORREF*)
7939{
7940 UNIMPLEMENTED();
7941 return 0;
7942}
7943
7944void WINAPI wglGetPixelFormat()
7945{
7946 UNIMPLEMENTED();
7947}
7948
7949const char *WINAPI wglGetExtensionsStringARB(HDC hdc)
7950{
7951 TRACE("(*)");
7952
7953 return "GL_ARB_framebuffer_object "
7954 "WGL_EXT_extensions_string "
7955 "WGL_EXT_swap_control";
7956}
7957
7958const char *WINAPI wglGetExtensionsStringEXT()
7959{
7960 TRACE("(*)");
7961 return wglGetExtensionsStringARB(0);
7962}
7963
7964PROC WINAPI wglGetProcAddress(LPCSTR lpszProc)
7965{
7966 TRACE("(LPCSTR lpszProc = \"%s\")", lpszProc);
7967
Nicolas Capens264f1522015-01-09 17:21:17 -05007968 struct Extension
7969 {
7970 const char *name;
Nicolas Capensa9b49372015-01-30 00:33:26 -05007971 PROC address;
Nicolas Capens264f1522015-01-09 17:21:17 -05007972 };
7973
7974 static const Extension glExtensions[] =
7975 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05007976 #define EXT(function) {#function, (PROC)function}
7977
7978 // Core 2.1
7979 EXT(glDrawRangeElements),
7980 EXT(glTexImage3D),
7981 EXT(glTexSubImage3D),
7982 EXT(glCopyTexSubImage3D),
7983 EXT(glActiveTexture),
7984 EXT(glClientActiveTexture),
7985 EXT(glCompressedTexImage1D),
7986 EXT(glCompressedTexImage2D),
7987 EXT(glCompressedTexImage3D),
7988 EXT(glCompressedTexSubImage1D),
7989 EXT(glCompressedTexSubImage2D),
7990 EXT(glCompressedTexSubImage3D),
7991 EXT(glGetCompressedTexImage),
7992 EXT(glMultiTexCoord1f),
7993 EXT(glMultiTexCoord1d),
7994 EXT(glMultiTexCoord2f),
7995 EXT(glMultiTexCoord2d),
7996 EXT(glMultiTexCoord3f),
7997 EXT(glMultiTexCoord3d),
7998 EXT(glMultiTexCoord4f),
7999 EXT(glMultiTexCoord4d),
8000 EXT(glLoadTransposeMatrixf),
8001 EXT(glLoadTransposeMatrixd),
8002 EXT(glMultTransposeMatrixf),
8003 EXT(glMultTransposeMatrixd),
8004 EXT(glSampleCoverage),
8005 EXT(glBlendEquation),
8006 EXT(glBlendColor),
8007 EXT(glFogCoordf),
8008 EXT(glFogCoordd),
8009 EXT(glFogCoordPointer),
8010 EXT(glMultiDrawArrays),
8011 EXT(glPointParameteri),
8012 EXT(glPointParameterf),
8013 EXT(glPointParameteriv),
8014 EXT(glPointParameterfv),
8015 EXT(glSecondaryColor3b),
8016 EXT(glSecondaryColor3f),
8017 EXT(glSecondaryColor3d),
8018 EXT(glSecondaryColor3ub),
8019 EXT(glSecondaryColorPointer),
8020 EXT(glBlendFuncSeparate),
8021 EXT(glWindowPos2f),
8022 EXT(glWindowPos2d),
8023 EXT(glWindowPos2i),
8024 EXT(glWindowPos3f),
8025 EXT(glWindowPos3d),
8026 EXT(glWindowPos3i),
8027 EXT(glBindBuffer),
8028 EXT(glDeleteBuffers),
8029 EXT(glGenBuffers),
8030 EXT(glIsBuffer),
8031 EXT(glBufferData),
8032 EXT(glBufferSubData),
8033 EXT(glGetBufferSubData),
8034 EXT(glMapBuffer),
8035 EXT(glUnmapBuffer),
8036 EXT(glGetBufferParameteriv),
8037 EXT(glGetBufferPointerv),
8038 EXT(glGenQueries),
8039 EXT(glDeleteQueries),
8040 EXT(glIsQuery),
8041 EXT(glBeginQuery),
8042 EXT(glEndQuery),
8043 EXT(glGetQueryiv),
8044 EXT(glGetQueryObjectiv),
8045 EXT(glGetQueryObjectuiv),
8046 EXT(glShaderSource),
8047 EXT(glCreateShader),
8048 EXT(glIsShader),
8049 EXT(glCompileShader),
8050 EXT(glDeleteShader),
8051 EXT(glCreateProgram),
8052 EXT(glIsProgram),
8053 EXT(glAttachShader),
8054 EXT(glDetachShader),
8055 EXT(glLinkProgram),
8056 EXT(glUseProgram),
8057 EXT(glValidateProgram),
8058 EXT(glDeleteProgram),
8059 EXT(glUniform1f),
8060 EXT(glUniform2f),
8061 EXT(glUniform3f),
8062 EXT(glUniform4f),
8063 EXT(glUniform1i),
8064 EXT(glUniform2i),
8065 EXT(glUniform3i),
8066 EXT(glUniform4i),
8067 EXT(glUniform1fv),
8068 EXT(glUniform2fv),
8069 EXT(glUniform3fv),
8070 EXT(glUniform4fv),
8071 EXT(glUniform1iv),
8072 EXT(glUniform2iv),
8073 EXT(glUniform3iv),
8074 EXT(glUniform4iv),
8075 EXT(glUniformMatrix2fv),
8076 EXT(glUniformMatrix3fv),
8077 EXT(glUniformMatrix4fv),
8078 EXT(glGetShaderiv),
8079 EXT(glGetProgramiv),
8080 EXT(glGetShaderInfoLog),
8081 EXT(glGetProgramInfoLog),
8082 EXT(glGetAttachedShaders),
8083 EXT(glGetUniformLocation),
8084 EXT(glGetActiveUniform),
8085 EXT(glGetUniformfv),
8086 EXT(glGetUniformiv),
8087 EXT(glGetShaderSource),
8088 EXT(glVertexAttrib1s),
8089 EXT(glVertexAttrib1f),
8090 EXT(glVertexAttrib1d),
8091 EXT(glVertexAttrib2s),
8092 EXT(glVertexAttrib2f),
8093 EXT(glVertexAttrib2d),
8094 EXT(glVertexAttrib3s),
8095 EXT(glVertexAttrib3f),
8096 EXT(glVertexAttrib3d),
8097 EXT(glVertexAttrib4s),
8098 EXT(glVertexAttrib4f),
8099 EXT(glVertexAttrib4d),
8100 EXT(glVertexAttrib4Nub),
8101 EXT(glVertexAttribPointer),
8102 EXT(glEnableVertexAttribArray),
8103 EXT(glDisableVertexAttribArray),
8104 EXT(glGetVertexAttribfv),
8105 EXT(glGetVertexAttribdv),
8106 EXT(glGetVertexAttribiv),
8107 EXT(glGetVertexAttribPointerv),
8108 EXT(glBindAttribLocation),
8109 EXT(glGetActiveAttrib),
8110 EXT(glGetAttribLocation),
8111 EXT(glDrawBuffers),
8112 EXT(glStencilOpSeparate),
8113 EXT(glStencilFuncSeparate),
8114 EXT(glStencilMaskSeparate),
8115 EXT(glBlendEquationSeparate),
8116 EXT(glUniformMatrix2x3fv),
8117 EXT(glUniformMatrix3x2fv),
8118 EXT(glUniformMatrix2x4fv),
8119 EXT(glUniformMatrix4x2fv),
8120 EXT(glUniformMatrix3x4fv),
8121 EXT(glUniformMatrix4x3fv),
8122 EXT(glGenFencesNV),
8123 EXT(glDeleteFencesNV),
8124 EXT(glSetFenceNV),
8125 EXT(glTestFenceNV),
8126 EXT(glFinishFenceNV),
8127 EXT(glIsFenceNV),
8128 EXT(glGetFenceivNV),
8129
8130 EXT(glIsRenderbuffer),
8131 EXT(glBindRenderbuffer),
8132 EXT(glDeleteRenderbuffers),
8133 EXT(glGenRenderbuffers),
8134 EXT(glRenderbufferStorage),
8135 EXT(glGetRenderbufferParameteriv),
8136 EXT(glIsFramebuffer),
8137 EXT(glBindFramebuffer),
8138 EXT(glDeleteFramebuffers),
8139 EXT(glGenFramebuffers),
8140 EXT(glCheckFramebufferStatus),
8141 EXT(glFramebufferTexture1D),
8142 EXT(glFramebufferTexture2D),
8143 EXT(glFramebufferTexture3D),
8144 EXT(glFramebufferRenderbuffer),
8145 EXT(glGetFramebufferAttachmentParameteriv),
8146 EXT(glGenerateMipmap),
8147 EXT(glReleaseShaderCompiler),
8148 EXT(glShaderBinary),
8149 EXT(glGetShaderPrecisionFormat),
8150 EXT(glDepthRangef),
8151 EXT(glClearDepthf),
Nicolas Capens264f1522015-01-09 17:21:17 -05008152
Nicolas Capensa9b49372015-01-30 00:33:26 -05008153 // ARB
8154 EXT(wglGetExtensionsStringARB),
8155 EXT(glIsRenderbuffer),
8156 EXT(glBindRenderbuffer),
8157 EXT(glDeleteRenderbuffers),
8158 EXT(glGenRenderbuffers),
8159 EXT(glRenderbufferStorage),
8160 EXT(glRenderbufferStorageMultisample),
8161 EXT(glGetRenderbufferParameteriv),
8162 EXT(glIsFramebuffer),
8163 EXT(glBindFramebuffer),
8164 EXT(glDeleteFramebuffers),
8165 EXT(glGenFramebuffers),
8166 EXT(glCheckFramebufferStatus),
8167 EXT(glFramebufferTexture1D),
8168 EXT(glFramebufferTexture2D),
8169 EXT(glFramebufferTexture3D),
8170 EXT(glFramebufferTextureLayer),
8171 EXT(glFramebufferRenderbuffer),
8172 EXT(glGetFramebufferAttachmentParameteriv),
8173 EXT(glBlitFramebuffer),
8174 EXT(glGenerateMipmap),
Nicolas Capens264f1522015-01-09 17:21:17 -05008175
Nicolas Capensa9b49372015-01-30 00:33:26 -05008176 // EXT
8177 EXT(wglSwapIntervalEXT),
8178 EXT(wglGetExtensionsStringEXT),
8179 #undef EXT
Nicolas Capens264f1522015-01-09 17:21:17 -05008180 };
8181
8182 for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
8183 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05008184 if(strcmp(lpszProc, glExtensions[ext].name) == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05008185 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05008186 return (PROC)glExtensions[ext].address;
Nicolas Capens264f1522015-01-09 17:21:17 -05008187 }
8188 }
8189
Nicolas Capensa9b49372015-01-30 00:33:26 -05008190 FARPROC proc = GetProcAddress(GetModuleHandle("opengl32.dll"), lpszProc); // FIXME?
8191
8192 if(proc)
8193 {
8194 return proc;
8195 }
8196
8197 TRACE("(LPCSTR lpszProc = \"%s\") NOT FOUND!!!", lpszProc);
8198
8199 return 0;
Nicolas Capens264f1522015-01-09 17:21:17 -05008200}
8201
Nicolas Capensa9b49372015-01-30 00:33:26 -05008202BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
8203{
8204 TRACE("(*)");
8205
8206 if(hdc && hglrc)
8207 {
8208 gl::Display *display = (gl::Display*)gl::Display::getDisplay(hdc);
8209 gl::makeCurrent((gl::Context*)hglrc, display, display->getPrimarySurface());
8210 gl::setCurrentDrawSurface(display->getPrimarySurface());
8211 gl::setCurrentDisplay(display);
8212 }
8213 else
8214 {
8215 gl::makeCurrent(0, 0, 0);
8216 }
8217
8218 return TRUE;
8219}
8220
8221BOOL WINAPI wglRealizeLayerPalette(HDC, int, BOOL)
8222{
8223 UNIMPLEMENTED();
8224 return FALSE;
8225}
8226
8227int WINAPI wglSetLayerPaletteEntries(HDC, int, int, int, CONST COLORREF*)
8228{
8229 UNIMPLEMENTED();
8230 return 0;
8231}
8232
8233BOOL WINAPI wglSetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
8234{
8235 TRACE("(*)");
8236 //UNIMPLEMENTED();
8237
8238 return TRUE;
8239}
8240
8241BOOL WINAPI wglShareLists(HGLRC, HGLRC)
8242{
8243 UNIMPLEMENTED();
8244 return FALSE;
8245}
8246
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008247BOOL WINAPI wglSwapBuffers(HDC hdc)
Nicolas Capensa9b49372015-01-30 00:33:26 -05008248{
8249 TRACE("(*)");
8250
8251 gl::Display *display = gl::getDisplay();
8252
8253 if(display)
8254 {
8255 display->getPrimarySurface()->swap();
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008256 return TRUE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008257 }
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008258
8259 return FALSE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008260}
8261
8262BOOL WINAPI wglSwapLayerBuffers(HDC, UINT)
8263{
8264 UNIMPLEMENTED();
8265 return FALSE;
8266}
8267
8268DWORD WINAPI wglSwapMultipleBuffers(UINT, CONST WGLSWAP*)
8269{
8270 UNIMPLEMENTED();
8271 return 0;
8272}
8273
8274BOOL WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD)
8275{
8276 UNIMPLEMENTED();
8277 return FALSE;
8278}
8279
8280BOOL WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD)
8281{
8282 UNIMPLEMENTED();
8283 return FALSE;
8284}
8285
8286BOOL WINAPI wglUseFontOutlinesA(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
8287{
8288 UNIMPLEMENTED();
8289 return FALSE;
8290}
8291
8292BOOL WINAPI wglUseFontOutlinesW(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
8293{
8294 UNIMPLEMENTED();
8295 return FALSE;
8296}
8297
8298void APIENTRY Register(const char *licenseKey)
Nicolas Capens264f1522015-01-09 17:21:17 -05008299{
8300 RegisterLicenseKey(licenseKey);
8301}
8302
8303}