blob: 924f55d4661ad505a685d08de8bc4afb68826b88 [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
Nicolas Capens264f1522015-01-09 17:21:17 -050035#include <limits>
36
37static bool validImageSize(GLint level, GLsizei width, GLsizei height)
38{
Nicolas Capensf4486fd2015-01-22 11:10:37 -050039 if(level < 0 || level >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
Nicolas Capens264f1522015-01-09 17:21:17 -050040 {
41 return false;
42 }
43
44 return true;
45}
46
Nicolas Capensf4486fd2015-01-22 11:10:37 -050047static 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 -050048{
49 if(!texture)
50 {
51 return error(GL_INVALID_OPERATION, false);
52 }
53
54 if(compressed != texture->isCompressed(target, level))
55 {
56 return error(GL_INVALID_OPERATION, false);
57 }
58
59 if(format != GL_NONE && format != texture->getFormat(target, level))
60 {
61 return error(GL_INVALID_OPERATION, false);
62 }
63
64 if(compressed)
65 {
66 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
67 (height % 4 != 0 && height != texture->getHeight(target, 0)))
68 {
69 return error(GL_INVALID_OPERATION, false);
70 }
71 }
72
73 if(xoffset + width > texture->getWidth(target, level) ||
74 yoffset + height > texture->getHeight(target, level))
75 {
76 return error(GL_INVALID_VALUE, false);
77 }
78
79 return true;
80}
81
82// Check for combinations of format and type that are valid for ReadPixels
83static bool validReadFormatType(GLenum format, GLenum type)
84{
85 switch(format)
86 {
87 case GL_RGBA:
88 switch(type)
89 {
90 case GL_UNSIGNED_BYTE:
91 break;
92 default:
93 return false;
94 }
95 break;
96 case GL_BGRA_EXT:
97 switch(type)
98 {
99 case GL_UNSIGNED_BYTE:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500100 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
101 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
Nicolas Capens264f1522015-01-09 17:21:17 -0500102 break;
103 default:
104 return false;
105 }
106 break;
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500107 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500108 switch(type)
109 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500110 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
Nicolas Capens264f1522015-01-09 17:21:17 -0500111 break;
112 default:
113 return false;
114 }
115 break;
116 default:
117 return false;
118 }
119
120 return true;
121}
122
123extern "C"
124{
125
Nicolas Capensa9b49372015-01-30 00:33:26 -0500126void APIENTRY glActiveTexture(GLenum texture)
Nicolas Capens264f1522015-01-09 17:21:17 -0500127{
128 TRACE("(GLenum texture = 0x%X)", texture);
129
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500130 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500131
132 if(context)
133 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500134 if(context->getListIndex() != 0)
135 {
136 UNIMPLEMENTED();
137 }
138
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500139 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
Nicolas Capens264f1522015-01-09 17:21:17 -0500140 {
141 return error(GL_INVALID_ENUM);
142 }
143
144 context->setActiveSampler(texture - GL_TEXTURE0);
145 }
146}
147
Nicolas Capensa9b49372015-01-30 00:33:26 -0500148void APIENTRY glAttachShader(GLuint program, GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -0500149{
150 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
151
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500152 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500153
154 if(context)
155 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500156 gl::Program *programObject = context->getProgram(program);
157 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -0500158
159 if(!programObject)
160 {
161 if(context->getShader(program))
162 {
163 return error(GL_INVALID_OPERATION);
164 }
165 else
166 {
167 return error(GL_INVALID_VALUE);
168 }
169 }
170
171 if(!shaderObject)
172 {
173 if(context->getProgram(shader))
174 {
175 return error(GL_INVALID_OPERATION);
176 }
177 else
178 {
179 return error(GL_INVALID_VALUE);
180 }
181 }
182
183 if(!programObject->attachShader(shaderObject))
184 {
185 return error(GL_INVALID_OPERATION);
186 }
187 }
188}
189
Nicolas Capensa9b49372015-01-30 00:33:26 -0500190void APIENTRY glBeginQueryEXT(GLenum target, GLuint name)
Nicolas Capens264f1522015-01-09 17:21:17 -0500191{
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500192 TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
Nicolas Capens264f1522015-01-09 17:21:17 -0500193
194 switch(target)
195 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500196 case GL_ANY_SAMPLES_PASSED:
197 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
Nicolas Capens264f1522015-01-09 17:21:17 -0500198 break;
199 default:
200 return error(GL_INVALID_ENUM);
201 }
202
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500203 if(name == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -0500204 {
205 return error(GL_INVALID_OPERATION);
206 }
207
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500208 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500209
210 if(context)
211 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500212 if(context->getListIndex() != 0)
213 {
214 UNIMPLEMENTED();
215 }
216
Nicolas Capens7cc75e12015-01-29 14:44:24 -0500217 context->beginQuery(target, name);
Nicolas Capens264f1522015-01-09 17:21:17 -0500218 }
219}
220
Nicolas Capensa9b49372015-01-30 00:33:26 -0500221void APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -0500222{
223 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
224
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500225 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -0500226 {
227 return error(GL_INVALID_VALUE);
228 }
229
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500230 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500231
232 if(context)
233 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500234 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -0500235
236 if(!programObject)
237 {
238 if(context->getShader(program))
239 {
240 return error(GL_INVALID_OPERATION);
241 }
242 else
243 {
244 return error(GL_INVALID_VALUE);
245 }
246 }
247
248 if(strncmp(name, "gl_", 3) == 0)
249 {
250 return error(GL_INVALID_OPERATION);
251 }
252
253 programObject->bindAttributeLocation(index, name);
254 }
255}
256
Nicolas Capensa9b49372015-01-30 00:33:26 -0500257void APIENTRY glBindBuffer(GLenum target, GLuint buffer)
Nicolas Capens264f1522015-01-09 17:21:17 -0500258{
259 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
260
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500261 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500262
263 if(context)
264 {
265 switch(target)
266 {
267 case GL_ARRAY_BUFFER:
268 context->bindArrayBuffer(buffer);
269 return;
270 case GL_ELEMENT_ARRAY_BUFFER:
271 context->bindElementArrayBuffer(buffer);
272 return;
273 default:
274 return error(GL_INVALID_ENUM);
275 }
276 }
277}
278
Nicolas Capensa9b49372015-01-30 00:33:26 -0500279void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -0500280{
281 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
282
Nicolas Capensa9b49372015-01-30 00:33:26 -0500283 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500284 {
285 return error(GL_INVALID_ENUM);
286 }
287
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500288 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500289
290 if(context)
291 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500292 if(context->getListIndex() != 0)
293 {
294 UNIMPLEMENTED();
295 }
296
297 if(target == GL_READ_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
Nicolas Capens264f1522015-01-09 17:21:17 -0500298 {
299 context->bindReadFramebuffer(framebuffer);
300 }
Nicolas Capensa9b49372015-01-30 00:33:26 -0500301
302 if(target == GL_DRAW_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
Nicolas Capens264f1522015-01-09 17:21:17 -0500303 {
304 context->bindDrawFramebuffer(framebuffer);
305 }
306 }
307}
308
Nicolas Capensa9b49372015-01-30 00:33:26 -0500309void APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -0500310{
311 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
312
313 if(target != GL_RENDERBUFFER)
314 {
315 return error(GL_INVALID_ENUM);
316 }
317
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500318 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500319
320 if(context)
321 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500322 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -0500323 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500324 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -0500325 }
326
327 context->bindRenderbuffer(renderbuffer);
328 }
329}
330
Nicolas Capensa9b49372015-01-30 00:33:26 -0500331void APIENTRY glBindTexture(GLenum target, GLuint texture)
Nicolas Capens264f1522015-01-09 17:21:17 -0500332{
333 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
334
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500335 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500336
337 if(context)
338 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500339 if(context->getListIndex() != 0)
340 {
341 UNIMPLEMENTED();
342 }
343
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500344 gl::Texture *textureObject = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -0500345
346 if(textureObject && textureObject->getTarget() != target && texture != 0)
347 {
348 return error(GL_INVALID_OPERATION);
349 }
350
351 switch(target)
352 {
353 case GL_TEXTURE_2D:
354 context->bindTexture2D(texture);
355 return;
356 case GL_TEXTURE_CUBE_MAP:
357 context->bindTextureCubeMap(texture);
358 return;
Nicolas Capens264f1522015-01-09 17:21:17 -0500359 default:
360 return error(GL_INVALID_ENUM);
361 }
362 }
363}
364
Nicolas Capensa9b49372015-01-30 00:33:26 -0500365void APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500366{
367 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
Nicolas Capensa9b49372015-01-30 00:33:26 -0500368 red, green, blue, alpha);
Nicolas Capens264f1522015-01-09 17:21:17 -0500369
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500370 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500371
372 if(context)
373 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500374 if(context->getListIndex() != 0)
375 {
376 UNIMPLEMENTED();
377 }
378
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500379 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
Nicolas Capens264f1522015-01-09 17:21:17 -0500380 }
381}
382
Nicolas Capensa9b49372015-01-30 00:33:26 -0500383void APIENTRY glBlendEquation(GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -0500384{
385 glBlendEquationSeparate(mode, mode);
386}
387
Nicolas Capensa9b49372015-01-30 00:33:26 -0500388void APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500389{
390 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
391
392 switch(modeRGB)
393 {
394 case GL_FUNC_ADD:
395 case GL_FUNC_SUBTRACT:
396 case GL_FUNC_REVERSE_SUBTRACT:
397 case GL_MIN_EXT:
398 case GL_MAX_EXT:
399 break;
400 default:
401 return error(GL_INVALID_ENUM);
402 }
403
404 switch(modeAlpha)
405 {
406 case GL_FUNC_ADD:
407 case GL_FUNC_SUBTRACT:
408 case GL_FUNC_REVERSE_SUBTRACT:
409 case GL_MIN_EXT:
410 case GL_MAX_EXT:
411 break;
412 default:
413 return error(GL_INVALID_ENUM);
414 }
415
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500416 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500417
418 if(context)
419 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500420 if(context->getListIndex() != 0)
421 {
422 UNIMPLEMENTED();
423 }
424
Nicolas Capens264f1522015-01-09 17:21:17 -0500425 context->setBlendEquation(modeRGB, modeAlpha);
426 }
427}
428
Nicolas Capensa9b49372015-01-30 00:33:26 -0500429void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
Nicolas Capens264f1522015-01-09 17:21:17 -0500430{
431 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
432}
433
Nicolas Capensa9b49372015-01-30 00:33:26 -0500434void APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500435{
436 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
437 srcRGB, dstRGB, srcAlpha, dstAlpha);
438
439 switch(srcRGB)
440 {
441 case GL_ZERO:
442 case GL_ONE:
443 case GL_SRC_COLOR:
444 case GL_ONE_MINUS_SRC_COLOR:
445 case GL_DST_COLOR:
446 case GL_ONE_MINUS_DST_COLOR:
447 case GL_SRC_ALPHA:
448 case GL_ONE_MINUS_SRC_ALPHA:
449 case GL_DST_ALPHA:
450 case GL_ONE_MINUS_DST_ALPHA:
451 case GL_CONSTANT_COLOR:
452 case GL_ONE_MINUS_CONSTANT_COLOR:
453 case GL_CONSTANT_ALPHA:
454 case GL_ONE_MINUS_CONSTANT_ALPHA:
455 case GL_SRC_ALPHA_SATURATE:
456 break;
457 default:
458 return error(GL_INVALID_ENUM);
459 }
460
461 switch(dstRGB)
462 {
463 case GL_ZERO:
464 case GL_ONE:
465 case GL_SRC_COLOR:
466 case GL_ONE_MINUS_SRC_COLOR:
467 case GL_DST_COLOR:
468 case GL_ONE_MINUS_DST_COLOR:
469 case GL_SRC_ALPHA:
470 case GL_ONE_MINUS_SRC_ALPHA:
471 case GL_DST_ALPHA:
472 case GL_ONE_MINUS_DST_ALPHA:
473 case GL_CONSTANT_COLOR:
474 case GL_ONE_MINUS_CONSTANT_COLOR:
475 case GL_CONSTANT_ALPHA:
476 case GL_ONE_MINUS_CONSTANT_ALPHA:
477 break;
478 default:
479 return error(GL_INVALID_ENUM);
480 }
481
482 switch(srcAlpha)
483 {
484 case GL_ZERO:
485 case GL_ONE:
486 case GL_SRC_COLOR:
487 case GL_ONE_MINUS_SRC_COLOR:
488 case GL_DST_COLOR:
489 case GL_ONE_MINUS_DST_COLOR:
490 case GL_SRC_ALPHA:
491 case GL_ONE_MINUS_SRC_ALPHA:
492 case GL_DST_ALPHA:
493 case GL_ONE_MINUS_DST_ALPHA:
494 case GL_CONSTANT_COLOR:
495 case GL_ONE_MINUS_CONSTANT_COLOR:
496 case GL_CONSTANT_ALPHA:
497 case GL_ONE_MINUS_CONSTANT_ALPHA:
498 case GL_SRC_ALPHA_SATURATE:
499 break;
500 default:
501 return error(GL_INVALID_ENUM);
502 }
503
504 switch(dstAlpha)
505 {
506 case GL_ZERO:
507 case GL_ONE:
508 case GL_SRC_COLOR:
509 case GL_ONE_MINUS_SRC_COLOR:
510 case GL_DST_COLOR:
511 case GL_ONE_MINUS_DST_COLOR:
512 case GL_SRC_ALPHA:
513 case GL_ONE_MINUS_SRC_ALPHA:
514 case GL_DST_ALPHA:
515 case GL_ONE_MINUS_DST_ALPHA:
516 case GL_CONSTANT_COLOR:
517 case GL_ONE_MINUS_CONSTANT_COLOR:
518 case GL_CONSTANT_ALPHA:
519 case GL_ONE_MINUS_CONSTANT_ALPHA:
520 break;
521 default:
522 return error(GL_INVALID_ENUM);
523 }
524
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500525 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500526
527 if(context)
528 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500529 if(context->getListIndex() != 0)
530 {
531 UNIMPLEMENTED();
532 }
533
Nicolas Capens264f1522015-01-09 17:21:17 -0500534 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
535 }
536}
537
Nicolas Capensa9b49372015-01-30 00:33:26 -0500538void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
Nicolas Capens264f1522015-01-09 17:21:17 -0500539{
Nicolas Capens264f1522015-01-09 17:21:17 -0500540 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
541 target, size, data, usage);
542
543 if(size < 0)
544 {
545 return error(GL_INVALID_VALUE);
546 }
547
548 switch(usage)
549 {
550 case GL_STREAM_DRAW:
551 case GL_STATIC_DRAW:
552 case GL_DYNAMIC_DRAW:
553 break;
554 default:
555 return error(GL_INVALID_ENUM);
556 }
557
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500558 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500559
560 if(context)
561 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500562 gl::Buffer *buffer;
Nicolas Capens264f1522015-01-09 17:21:17 -0500563
564 switch(target)
565 {
566 case GL_ARRAY_BUFFER:
567 buffer = context->getArrayBuffer();
568 break;
569 case GL_ELEMENT_ARRAY_BUFFER:
570 buffer = context->getElementArrayBuffer();
571 break;
572 default:
573 return error(GL_INVALID_ENUM);
574 }
575
576 if(!buffer)
577 {
578 return error(GL_INVALID_OPERATION);
579 }
580
581 buffer->bufferData(data, size, usage);
582 }
583}
584
Nicolas Capensa9b49372015-01-30 00:33:26 -0500585void APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
Nicolas Capens264f1522015-01-09 17:21:17 -0500586{
Nicolas Capens264f1522015-01-09 17:21:17 -0500587 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
588 target, offset, size, data);
589
590 if(size < 0 || offset < 0)
591 {
592 return error(GL_INVALID_VALUE);
593 }
594
595 if(data == NULL)
596 {
597 return;
598 }
599
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500600 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500601
602 if(context)
603 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500604 gl::Buffer *buffer;
Nicolas Capens264f1522015-01-09 17:21:17 -0500605
606 switch(target)
607 {
608 case GL_ARRAY_BUFFER:
609 buffer = context->getArrayBuffer();
610 break;
611 case GL_ELEMENT_ARRAY_BUFFER:
612 buffer = context->getElementArrayBuffer();
613 break;
614 default:
615 return error(GL_INVALID_ENUM);
616 }
617
618 if(!buffer)
619 {
620 return error(GL_INVALID_OPERATION);
621 }
622
623 if((size_t)size + offset > buffer->size())
624 {
625 return error(GL_INVALID_VALUE);
626 }
627
628 buffer->bufferSubData(data, size, offset);
629 }
630}
631
Nicolas Capensa9b49372015-01-30 00:33:26 -0500632GLenum APIENTRY glCheckFramebufferStatus(GLenum target)
Nicolas Capens264f1522015-01-09 17:21:17 -0500633{
634 TRACE("(GLenum target = 0x%X)", target);
635
Nicolas Capensa9b49372015-01-30 00:33:26 -0500636 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500637 {
638 return error(GL_INVALID_ENUM, 0);
639 }
640
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500641 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500642
643 if(context)
644 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500645 if(context->getListIndex() != 0)
646 {
647 UNIMPLEMENTED();
648 }
649
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500650 gl::Framebuffer *framebuffer = NULL;
Nicolas Capensa9b49372015-01-30 00:33:26 -0500651 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -0500652 {
653 framebuffer = context->getReadFramebuffer();
654 }
655 else
656 {
657 framebuffer = context->getDrawFramebuffer();
658 }
659
660 return framebuffer->completeness();
661 }
662
663 return 0;
664}
665
Nicolas Capensa9b49372015-01-30 00:33:26 -0500666void APIENTRY glClear(GLbitfield mask)
Nicolas Capens264f1522015-01-09 17:21:17 -0500667{
668 TRACE("(GLbitfield mask = %X)", mask);
669
670 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
671 {
672 return error(GL_INVALID_VALUE);
673 }
674
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500675 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500676
677 if(context)
678 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500679 if(context->getListIndex() != 0)
680 {
681 return context->listCommand(gl::newCommand(glClear, mask));
682 }
683
Nicolas Capens264f1522015-01-09 17:21:17 -0500684 context->clear(mask);
685 }
686}
687
Nicolas Capensa9b49372015-01-30 00:33:26 -0500688void APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500689{
690 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
691 red, green, blue, alpha);
692
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500693 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500694
695 if(context)
696 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500697 if(context->getListIndex() != 0)
698 {
699 UNIMPLEMENTED();
700 }
701
Nicolas Capens264f1522015-01-09 17:21:17 -0500702 context->setClearColor(red, green, blue, alpha);
703 }
704}
705
Nicolas Capensa9b49372015-01-30 00:33:26 -0500706void APIENTRY glClearDepthf(GLclampf depth)
Nicolas Capens264f1522015-01-09 17:21:17 -0500707{
708 TRACE("(GLclampf depth = %f)", depth);
709
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500710 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500711
712 if(context)
713 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500714 if(context->getListIndex() != 0)
715 {
716 UNIMPLEMENTED();
717 }
718
Nicolas Capens264f1522015-01-09 17:21:17 -0500719 context->setClearDepth(depth);
720 }
721}
722
Nicolas Capensa9b49372015-01-30 00:33:26 -0500723void APIENTRY glClearStencil(GLint s)
Nicolas Capens264f1522015-01-09 17:21:17 -0500724{
725 TRACE("(GLint s = %d)", s);
726
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500727 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500728
729 if(context)
730 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500731 if(context->getListIndex() != 0)
732 {
733 UNIMPLEMENTED();
734 }
735
Nicolas Capens264f1522015-01-09 17:21:17 -0500736 context->setClearStencil(s);
737 }
738}
739
Nicolas Capensa9b49372015-01-30 00:33:26 -0500740void APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
Nicolas Capens264f1522015-01-09 17:21:17 -0500741{
742 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
743 red, green, blue, alpha);
744
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500745 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500746
747 if(context)
748 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500749 if(context->getListIndex() != 0)
750 {
751 UNIMPLEMENTED();
752 }
753
Nicolas Capens264f1522015-01-09 17:21:17 -0500754 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
755 }
756}
757
Nicolas Capensa9b49372015-01-30 00:33:26 -0500758void APIENTRY glCompileShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -0500759{
760 TRACE("(GLuint shader = %d)", shader);
761
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500762 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500763
764 if(context)
765 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500766 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -0500767
768 if(!shaderObject)
769 {
770 if(context->getProgram(shader))
771 {
772 return error(GL_INVALID_OPERATION);
773 }
774 else
775 {
776 return error(GL_INVALID_VALUE);
777 }
778 }
779
780 shaderObject->compile();
781 }
782}
783
Nicolas Capensa9b49372015-01-30 00:33:26 -0500784void APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -0500785 GLint border, GLsizei imageSize, const GLvoid* data)
786{
787 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
788 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
789 target, level, internalformat, width, height, border, imageSize, data);
790
791 if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
792 {
793 return error(GL_INVALID_VALUE);
794 }
795
796 switch(internalformat)
797 {
Nicolas Capens264f1522015-01-09 17:21:17 -0500798 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
799 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500800 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
801 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500802 if(!S3TC_SUPPORT)
803 {
804 return error(GL_INVALID_ENUM);
805 }
806 break;
807 case GL_DEPTH_COMPONENT:
808 case GL_DEPTH_COMPONENT16:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500809 case GL_DEPTH_COMPONENT32:
810 case GL_DEPTH_STENCIL_EXT:
811 case GL_DEPTH24_STENCIL8_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500812 return error(GL_INVALID_OPERATION);
813 default:
814 return error(GL_INVALID_ENUM);
815 }
816
817 if(border != 0)
818 {
819 return error(GL_INVALID_VALUE);
820 }
821
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500822 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500823
824 if(context)
825 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500826 if(context->getListIndex() != 0)
827 {
828 UNIMPLEMENTED();
829 }
830
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500831 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -0500832 {
833 return error(GL_INVALID_VALUE);
834 }
835
836 switch(target)
837 {
838 case GL_TEXTURE_2D:
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500839 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
840 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -0500841 {
842 return error(GL_INVALID_VALUE);
843 }
844 break;
845 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
846 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
847 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
848 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
849 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
850 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
851 if(width != height)
852 {
853 return error(GL_INVALID_VALUE);
854 }
855
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500856 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
857 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -0500858 {
859 return error(GL_INVALID_VALUE);
860 }
861 break;
862 default:
863 return error(GL_INVALID_ENUM);
864 }
865
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500866 if(imageSize != gl::ComputeCompressedSize(width, height, internalformat))
Nicolas Capens264f1522015-01-09 17:21:17 -0500867 {
868 return error(GL_INVALID_VALUE);
869 }
870
871 if(target == GL_TEXTURE_2D)
872 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500873 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -0500874
875 if(!texture)
876 {
877 return error(GL_INVALID_OPERATION);
878 }
879
880 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
881 }
882 else
883 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500884 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -0500885
886 if(!texture)
887 {
888 return error(GL_INVALID_OPERATION);
889 }
890
891 switch(target)
892 {
893 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
894 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
895 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
896 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
897 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
898 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
899 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
900 break;
901 default: UNREACHABLE();
902 }
903 }
904 }
905}
906
Nicolas Capensa9b49372015-01-30 00:33:26 -0500907void APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -0500908 GLenum format, GLsizei imageSize, const GLvoid* data)
909{
910 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
911 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
912 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
913 target, level, xoffset, yoffset, width, height, format, imageSize, data);
914
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500915 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -0500916 {
917 return error(GL_INVALID_ENUM);
918 }
919
920 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
921 {
922 return error(GL_INVALID_VALUE);
923 }
924
925 switch(format)
926 {
Nicolas Capens264f1522015-01-09 17:21:17 -0500927 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
928 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -0500929 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
930 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -0500931 if(!S3TC_SUPPORT)
932 {
933 return error(GL_INVALID_ENUM);
934 }
935 break;
936 default:
937 return error(GL_INVALID_ENUM);
938 }
939
940 if(width == 0 || height == 0 || data == NULL)
941 {
942 return;
943 }
944
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500945 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -0500946
947 if(context)
948 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500949 if(context->getListIndex() != 0)
950 {
951 UNIMPLEMENTED();
952 }
953
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500954 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -0500955 {
956 return error(GL_INVALID_VALUE);
957 }
958
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500959 if(imageSize != gl::ComputeCompressedSize(width, height, format))
Nicolas Capens264f1522015-01-09 17:21:17 -0500960 {
961 return error(GL_INVALID_VALUE);
962 }
963
964 if(xoffset % 4 != 0 || yoffset % 4 != 0)
965 {
966 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
967 return error(GL_INVALID_OPERATION);
968 }
969
970 if(target == GL_TEXTURE_2D)
971 {
Nicolas Capensa9b49372015-01-30 00:33:26 -0500972 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -0500973
974 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
975 {
976 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
977 }
978 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500979 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -0500980 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -0500981 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -0500982
983 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
984 {
985 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
986 }
987 }
988 else
989 {
990 UNREACHABLE();
991 }
992 }
993}
994
Nicolas Capensa9b49372015-01-30 00:33:26 -0500995void 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 -0500996{
997 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
998 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
999 target, level, internalformat, x, y, width, height, border);
1000
1001 if(!validImageSize(level, width, height))
1002 {
1003 return error(GL_INVALID_VALUE);
1004 }
1005
1006 if(border != 0)
1007 {
1008 return error(GL_INVALID_VALUE);
1009 }
1010
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001011 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001012
1013 if(context)
1014 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001015 if(context->getListIndex() != 0)
1016 {
1017 UNIMPLEMENTED();
1018 }
1019
Nicolas Capens264f1522015-01-09 17:21:17 -05001020 switch(target)
1021 {
1022 case GL_TEXTURE_2D:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001023 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
1024 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -05001025 {
1026 return error(GL_INVALID_VALUE);
1027 }
1028 break;
1029 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1030 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1031 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1032 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1033 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1034 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1035 if(width != height)
1036 {
1037 return error(GL_INVALID_VALUE);
1038 }
1039
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001040 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
1041 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
Nicolas Capens264f1522015-01-09 17:21:17 -05001042 {
1043 return error(GL_INVALID_VALUE);
1044 }
1045 break;
1046 default:
1047 return error(GL_INVALID_ENUM);
1048 }
1049
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001050 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001051
1052 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1053 {
1054 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1055 }
1056
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001057 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capens264f1522015-01-09 17:21:17 -05001058 {
1059 return error(GL_INVALID_OPERATION);
1060 }
1061
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001062 gl::Renderbuffer *source = framebuffer->getColorbuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001063 GLenum colorbufferFormat = source->getFormat();
1064
Nicolas Capens264f1522015-01-09 17:21:17 -05001065 switch(internalformat)
1066 {
1067 case GL_ALPHA:
1068 if(colorbufferFormat != GL_ALPHA &&
1069 colorbufferFormat != GL_RGBA &&
1070 colorbufferFormat != GL_RGBA4 &&
1071 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001072 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001073 {
1074 return error(GL_INVALID_OPERATION);
1075 }
1076 break;
1077 case GL_LUMINANCE:
1078 case GL_RGB:
1079 if(colorbufferFormat != GL_RGB &&
1080 colorbufferFormat != GL_RGB565 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001081 colorbufferFormat != GL_RGB8_EXT &&
Nicolas Capens264f1522015-01-09 17:21:17 -05001082 colorbufferFormat != GL_RGBA &&
1083 colorbufferFormat != GL_RGBA4 &&
1084 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001085 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001086 {
1087 return error(GL_INVALID_OPERATION);
1088 }
1089 break;
1090 case GL_LUMINANCE_ALPHA:
1091 case GL_RGBA:
1092 if(colorbufferFormat != GL_RGBA &&
1093 colorbufferFormat != GL_RGBA4 &&
1094 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001095 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001096 {
1097 return error(GL_INVALID_OPERATION);
1098 }
1099 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001100 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1101 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05001102 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1103 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05001104 if(S3TC_SUPPORT)
1105 {
1106 return error(GL_INVALID_OPERATION);
1107 }
1108 else
1109 {
1110 return error(GL_INVALID_ENUM);
1111 }
1112 default:
1113 return error(GL_INVALID_ENUM);
1114 }
1115
1116 if(target == GL_TEXTURE_2D)
1117 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001118 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05001119
1120 if(!texture)
1121 {
1122 return error(GL_INVALID_OPERATION);
1123 }
1124
1125 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
1126 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001127 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05001128 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001129 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05001130
1131 if(!texture)
1132 {
1133 return error(GL_INVALID_OPERATION);
1134 }
1135
1136 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
1137 }
1138 else UNREACHABLE();
1139 }
1140}
1141
Nicolas Capensa9b49372015-01-30 00:33:26 -05001142void 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 -05001143{
1144 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1145 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
1146 target, level, xoffset, yoffset, x, y, width, height);
1147
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001148 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05001149 {
1150 return error(GL_INVALID_ENUM);
1151 }
1152
1153 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
1154 {
1155 return error(GL_INVALID_VALUE);
1156 }
1157
1158 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1159 {
1160 return error(GL_INVALID_VALUE);
1161 }
1162
1163 if(width == 0 || height == 0)
1164 {
1165 return;
1166 }
1167
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001168 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001169
1170 if(context)
1171 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001172 if(context->getListIndex() != 0)
1173 {
1174 UNIMPLEMENTED();
1175 }
1176
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001177 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -05001178 {
1179 return error(GL_INVALID_VALUE);
1180 }
1181
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001182 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001183
1184 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1185 {
1186 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1187 }
1188
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001189 if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
Nicolas Capens264f1522015-01-09 17:21:17 -05001190 {
1191 return error(GL_INVALID_OPERATION);
1192 }
1193
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001194 gl::Renderbuffer *source = framebuffer->getColorbuffer();
Nicolas Capens264f1522015-01-09 17:21:17 -05001195 GLenum colorbufferFormat = source->getFormat();
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001196 gl::Texture *texture = NULL;
Nicolas Capens264f1522015-01-09 17:21:17 -05001197
1198 if(target == GL_TEXTURE_2D)
1199 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001200 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05001201 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001202 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05001203 {
1204 texture = context->getTextureCubeMap();
1205 }
1206 else UNREACHABLE();
1207
1208 if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))
1209 {
1210 return;
1211 }
1212
1213 GLenum textureFormat = texture->getFormat(target, level);
1214
Nicolas Capens264f1522015-01-09 17:21:17 -05001215 switch(textureFormat)
1216 {
1217 case GL_ALPHA:
1218 if(colorbufferFormat != GL_ALPHA &&
1219 colorbufferFormat != GL_RGBA &&
1220 colorbufferFormat != GL_RGBA4 &&
1221 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001222 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001223 {
1224 return error(GL_INVALID_OPERATION);
1225 }
1226 break;
1227 case GL_LUMINANCE:
1228 case GL_RGB:
1229 if(colorbufferFormat != GL_RGB &&
1230 colorbufferFormat != GL_RGB565 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001231 colorbufferFormat != GL_RGB8_EXT &&
Nicolas Capens264f1522015-01-09 17:21:17 -05001232 colorbufferFormat != GL_RGBA &&
1233 colorbufferFormat != GL_RGBA4 &&
1234 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001235 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001236 {
1237 return error(GL_INVALID_OPERATION);
1238 }
1239 break;
1240 case GL_LUMINANCE_ALPHA:
1241 case GL_RGBA:
1242 if(colorbufferFormat != GL_RGBA &&
1243 colorbufferFormat != GL_RGBA4 &&
1244 colorbufferFormat != GL_RGB5_A1 &&
Nicolas Capensa9b49372015-01-30 00:33:26 -05001245 colorbufferFormat != GL_RGBA8_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001246 {
1247 return error(GL_INVALID_OPERATION);
1248 }
1249 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001250 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1251 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05001252 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
1253 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
1254 return error(GL_INVALID_OPERATION);
1255 case GL_DEPTH_COMPONENT:
1256 case GL_DEPTH_STENCIL_EXT:
1257 return error(GL_INVALID_OPERATION);
1258 case GL_BGRA_EXT:
1259 if(colorbufferFormat != GL_RGB8)
Nicolas Capens264f1522015-01-09 17:21:17 -05001260 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001261 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05001262 return error(GL_INVALID_OPERATION);
1263 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05001264 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001265 default:
1266 return error(GL_INVALID_ENUM);
1267 }
1268
1269 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
1270 }
1271}
1272
Nicolas Capensa9b49372015-01-30 00:33:26 -05001273GLuint APIENTRY glCreateProgram(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05001274{
1275 TRACE("()");
1276
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001277 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001278
1279 if(context)
1280 {
1281 return context->createProgram();
1282 }
1283
1284 return 0;
1285}
1286
Nicolas Capensa9b49372015-01-30 00:33:26 -05001287GLuint APIENTRY glCreateShader(GLenum type)
Nicolas Capens264f1522015-01-09 17:21:17 -05001288{
1289 TRACE("(GLenum type = 0x%X)", type);
1290
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001291 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001292
1293 if(context)
1294 {
1295 switch(type)
1296 {
1297 case GL_FRAGMENT_SHADER:
1298 case GL_VERTEX_SHADER:
1299 return context->createShader(type);
1300 default:
1301 return error(GL_INVALID_ENUM, 0);
1302 }
1303 }
1304
1305 return 0;
1306}
1307
Nicolas Capensa9b49372015-01-30 00:33:26 -05001308void APIENTRY glCullFace(GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05001309{
1310 TRACE("(GLenum mode = 0x%X)", mode);
1311
1312 switch(mode)
1313 {
1314 case GL_FRONT:
1315 case GL_BACK:
1316 case GL_FRONT_AND_BACK:
1317 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001318 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001319
1320 if(context)
1321 {
1322 context->setCullMode(mode);
1323 }
1324 }
1325 break;
1326 default:
1327 return error(GL_INVALID_ENUM);
1328 }
1329}
1330
Nicolas Capensa9b49372015-01-30 00:33:26 -05001331void APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05001332{
1333 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
1334
1335 if(n < 0)
1336 {
1337 return error(GL_INVALID_VALUE);
1338 }
1339
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001340 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001341
1342 if(context)
1343 {
1344 for(int i = 0; i < n; i++)
1345 {
1346 context->deleteBuffer(buffers[i]);
1347 }
1348 }
1349}
1350
Nicolas Capensa9b49372015-01-30 00:33:26 -05001351void APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
Nicolas Capens264f1522015-01-09 17:21:17 -05001352{
1353 TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
1354
1355 if(n < 0)
1356 {
1357 return error(GL_INVALID_VALUE);
1358 }
1359
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001360 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001361
1362 if(context)
1363 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001364 if(context->getListIndex() != 0)
1365 {
1366 UNIMPLEMENTED();
1367 }
1368
Nicolas Capens264f1522015-01-09 17:21:17 -05001369 for(int i = 0; i < n; i++)
1370 {
1371 context->deleteFence(fences[i]);
1372 }
1373 }
1374}
1375
Nicolas Capensa9b49372015-01-30 00:33:26 -05001376void APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05001377{
1378 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
1379
1380 if(n < 0)
1381 {
1382 return error(GL_INVALID_VALUE);
1383 }
1384
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001385 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001386
1387 if(context)
1388 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001389 if(context->getListIndex() != 0)
1390 {
1391 UNIMPLEMENTED();
1392 }
1393
Nicolas Capens264f1522015-01-09 17:21:17 -05001394 for(int i = 0; i < n; i++)
1395 {
1396 if(framebuffers[i] != 0)
1397 {
1398 context->deleteFramebuffer(framebuffers[i]);
1399 }
1400 }
1401 }
1402}
1403
Nicolas Capensa9b49372015-01-30 00:33:26 -05001404void APIENTRY glDeleteProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05001405{
1406 TRACE("(GLuint program = %d)", program);
1407
1408 if(program == 0)
1409 {
1410 return;
1411 }
1412
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001413 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001414
1415 if(context)
1416 {
1417 if(!context->getProgram(program))
1418 {
1419 if(context->getShader(program))
1420 {
1421 return error(GL_INVALID_OPERATION);
1422 }
1423 else
1424 {
1425 return error(GL_INVALID_VALUE);
1426 }
1427 }
1428
1429 context->deleteProgram(program);
1430 }
1431}
1432
Nicolas Capensa9b49372015-01-30 00:33:26 -05001433void APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
Nicolas Capens264f1522015-01-09 17:21:17 -05001434{
1435 TRACE("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
1436
1437 if(n < 0)
1438 {
1439 return error(GL_INVALID_VALUE);
1440 }
1441
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001442 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001443
1444 if(context)
1445 {
1446 for(int i = 0; i < n; i++)
1447 {
1448 context->deleteQuery(ids[i]);
1449 }
1450 }
1451}
1452
Nicolas Capensa9b49372015-01-30 00:33:26 -05001453void APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05001454{
1455 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
1456
1457 if(n < 0)
1458 {
1459 return error(GL_INVALID_VALUE);
1460 }
1461
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001462 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001463
1464 if(context)
1465 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001466 if(context->getListIndex() != 0)
1467 {
1468 UNIMPLEMENTED();
1469 }
1470
Nicolas Capens264f1522015-01-09 17:21:17 -05001471 for(int i = 0; i < n; i++)
1472 {
1473 context->deleteRenderbuffer(renderbuffers[i]);
1474 }
1475 }
1476}
1477
Nicolas Capensa9b49372015-01-30 00:33:26 -05001478void APIENTRY glDeleteShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05001479{
1480 TRACE("(GLuint shader = %d)", shader);
1481
1482 if(shader == 0)
1483 {
1484 return;
1485 }
1486
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001487 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001488
1489 if(context)
1490 {
1491 if(!context->getShader(shader))
1492 {
1493 if(context->getProgram(shader))
1494 {
1495 return error(GL_INVALID_OPERATION);
1496 }
1497 else
1498 {
1499 return error(GL_INVALID_VALUE);
1500 }
1501 }
1502
1503 context->deleteShader(shader);
1504 }
1505}
1506
Nicolas Capensa9b49372015-01-30 00:33:26 -05001507void APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
Nicolas Capens264f1522015-01-09 17:21:17 -05001508{
1509 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
1510
1511 if(n < 0)
1512 {
1513 return error(GL_INVALID_VALUE);
1514 }
1515
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001516 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001517
1518 if(context)
1519 {
1520 for(int i = 0; i < n; i++)
1521 {
1522 if(textures[i] != 0)
1523 {
1524 context->deleteTexture(textures[i]);
1525 }
1526 }
1527 }
1528}
1529
Nicolas Capensa9b49372015-01-30 00:33:26 -05001530void APIENTRY glDepthFunc(GLenum func)
Nicolas Capens264f1522015-01-09 17:21:17 -05001531{
1532 TRACE("(GLenum func = 0x%X)", func);
1533
1534 switch(func)
1535 {
1536 case GL_NEVER:
1537 case GL_ALWAYS:
1538 case GL_LESS:
1539 case GL_LEQUAL:
1540 case GL_EQUAL:
1541 case GL_GREATER:
1542 case GL_GEQUAL:
1543 case GL_NOTEQUAL:
1544 break;
1545 default:
1546 return error(GL_INVALID_ENUM);
1547 }
1548
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001549 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001550
1551 if(context)
1552 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001553 if(context->getListIndex() != 0)
1554 {
1555 UNIMPLEMENTED();
1556 }
1557
Nicolas Capens264f1522015-01-09 17:21:17 -05001558 context->setDepthFunc(func);
1559 }
1560}
1561
Nicolas Capensa9b49372015-01-30 00:33:26 -05001562void APIENTRY glDepthMask(GLboolean flag)
Nicolas Capens264f1522015-01-09 17:21:17 -05001563{
1564 TRACE("(GLboolean flag = %d)", flag);
1565
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001566 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001567
1568 if(context)
1569 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001570 if(context->getListIndex() != 0)
1571 {
1572 UNIMPLEMENTED();
1573 }
1574
Nicolas Capens264f1522015-01-09 17:21:17 -05001575 context->setDepthMask(flag != GL_FALSE);
1576 }
1577}
1578
Nicolas Capensa9b49372015-01-30 00:33:26 -05001579void APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
Nicolas Capens264f1522015-01-09 17:21:17 -05001580{
1581 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
1582
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001583 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001584
1585 if(context)
1586 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001587 if(context->getListIndex() != 0)
1588 {
1589 UNIMPLEMENTED();
1590 }
1591
Nicolas Capens264f1522015-01-09 17:21:17 -05001592 context->setDepthRange(zNear, zFar);
1593 }
1594}
1595
Nicolas Capensa9b49372015-01-30 00:33:26 -05001596void APIENTRY glDetachShader(GLuint program, GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05001597{
1598 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
1599
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001600 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001601
1602 if(context)
1603 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001604 gl::Program *programObject = context->getProgram(program);
1605 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05001606
1607 if(!programObject)
1608 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001609 gl::Shader *shaderByProgramHandle;
Nicolas Capens264f1522015-01-09 17:21:17 -05001610 shaderByProgramHandle = context->getShader(program);
1611 if(!shaderByProgramHandle)
1612 {
1613 return error(GL_INVALID_VALUE);
1614 }
1615 else
1616 {
1617 return error(GL_INVALID_OPERATION);
1618 }
1619 }
1620
1621 if(!shaderObject)
1622 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001623 gl::Program *programByShaderHandle = context->getProgram(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05001624 if(!programByShaderHandle)
1625 {
1626 return error(GL_INVALID_VALUE);
1627 }
1628 else
1629 {
1630 return error(GL_INVALID_OPERATION);
1631 }
1632 }
1633
1634 if(!programObject->detachShader(shaderObject))
1635 {
1636 return error(GL_INVALID_OPERATION);
1637 }
1638 }
1639}
1640
Nicolas Capensa9b49372015-01-30 00:33:26 -05001641void APIENTRY glDisable(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05001642{
1643 TRACE("(GLenum cap = 0x%X)", cap);
1644
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001645 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001646
1647 if(context)
1648 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001649 if(context->getListIndex() != 0)
1650 {
1651 UNIMPLEMENTED();
1652 }
1653
Nicolas Capens264f1522015-01-09 17:21:17 -05001654 switch(cap)
1655 {
1656 case GL_CULL_FACE: context->setCullFace(false); break;
1657 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1658 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1659 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1660 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1661 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1662 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1663 case GL_BLEND: context->setBlend(false); break;
1664 case GL_DITHER: context->setDither(false); break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05001665 case GL_LIGHTING: context->setLighting(false); break;
1666 case GL_FOG: context->setFog(false); break;
1667 case GL_ALPHA_TEST: context->setAlphaTest(false); break;
1668 case GL_TEXTURE_2D: context->setTexture2D(false); break;
1669 case GL_LIGHT0: context->setLight(0, false); break;
1670 case GL_LIGHT1: context->setLight(1, false); break;
1671 case GL_LIGHT2: context->setLight(2, false); break;
1672 case GL_LIGHT3: context->setLight(3, false); break;
1673 case GL_LIGHT4: context->setLight(4, false); break;
1674 case GL_LIGHT5: context->setLight(5, false); break;
1675 case GL_LIGHT6: context->setLight(6, false); break;
1676 case GL_LIGHT7: context->setLight(7, false); break;
1677 case GL_COLOR_MATERIAL: context->setColorMaterial(false); break;
1678 case GL_RESCALE_NORMAL: context->setNormalizeNormals(false); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001679 default:
1680 return error(GL_INVALID_ENUM);
1681 }
1682 }
1683}
1684
Nicolas Capensa9b49372015-01-30 00:33:26 -05001685void APIENTRY glDisableVertexAttribArray(GLuint index)
Nicolas Capens264f1522015-01-09 17:21:17 -05001686{
1687 TRACE("(GLuint index = %d)", index);
1688
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001689 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05001690 {
1691 return error(GL_INVALID_VALUE);
1692 }
1693
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001694 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001695
1696 if(context)
1697 {
1698 context->setEnableVertexAttribArray(index, false);
1699 }
1700}
1701
Nicolas Capensa9b49372015-01-30 00:33:26 -05001702void APIENTRY glCaptureAttribs()
1703{
1704 TRACE("()");
1705
1706 gl::Context *context = gl::getContext();
1707
1708 if(context)
1709 {
1710 context->captureAttribs();
1711 }
1712}
1713
1714void APIENTRY glRestoreAttribs()
1715{
1716 TRACE("()");
1717
1718 gl::Context *context = gl::getContext();
1719
1720 if(context)
1721 {
1722 context->restoreAttribs();
1723 }
1724}
1725
1726void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
Nicolas Capens264f1522015-01-09 17:21:17 -05001727{
1728 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
1729
1730 if(count < 0 || first < 0)
1731 {
1732 return error(GL_INVALID_VALUE);
1733 }
1734
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001735 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001736
1737 if(context)
1738 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001739 if(context->getListIndex() != 0)
1740 {
1741 ASSERT(context->getListMode() != GL_COMPILE_AND_EXECUTE); // UNIMPLEMENTED!
1742
1743 context->listCommand(gl::newCommand(glCaptureAttribs));
1744 context->captureDrawArrays(mode, first, count);
1745 context->listCommand(gl::newCommand(glDrawArrays, mode, first, count));
1746 context->listCommand(gl::newCommand(glRestoreAttribs));
1747
1748 return;
1749 }
1750
Nicolas Capens264f1522015-01-09 17:21:17 -05001751 context->drawArrays(mode, first, count);
1752 }
1753}
1754
Nicolas Capensa9b49372015-01-30 00:33:26 -05001755void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
Nicolas Capens264f1522015-01-09 17:21:17 -05001756{
1757 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
1758 mode, count, type, indices);
1759
1760 if(count < 0)
1761 {
1762 return error(GL_INVALID_VALUE);
1763 }
1764
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001765 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001766
1767 if(context)
1768 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001769 if(context->getListIndex() != 0)
1770 {
1771 UNIMPLEMENTED();
1772 }
1773
Nicolas Capens264f1522015-01-09 17:21:17 -05001774 switch(type)
1775 {
1776 case GL_UNSIGNED_BYTE:
1777 case GL_UNSIGNED_SHORT:
1778 case GL_UNSIGNED_INT:
1779 break;
1780 default:
1781 return error(GL_INVALID_ENUM);
1782 }
1783
1784 context->drawElements(mode, count, type, indices);
1785 }
1786}
1787
Nicolas Capensa9b49372015-01-30 00:33:26 -05001788void APIENTRY glEnable(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05001789{
1790 TRACE("(GLenum cap = 0x%X)", cap);
1791
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001792 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001793
1794 if(context)
1795 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001796 if(context->getListIndex() != 0)
1797 {
1798 UNIMPLEMENTED();
1799 }
1800
Nicolas Capens264f1522015-01-09 17:21:17 -05001801 switch(cap)
1802 {
1803 case GL_CULL_FACE: context->setCullFace(true); break;
1804 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1805 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1806 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1807 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1808 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1809 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1810 case GL_BLEND: context->setBlend(true); break;
1811 case GL_DITHER: context->setDither(true); break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05001812 case GL_TEXTURE_2D: context->setTexture2D(true); break;
1813 case GL_ALPHA_TEST: context->setAlphaTest(true); break;
1814 case GL_COLOR_MATERIAL: context->setColorMaterial(true); break;
1815 case GL_FOG: context->setFog(true); break;
1816 case GL_LIGHTING: context->setLighting(true); break;
1817 case GL_LIGHT0: context->setLight(0, true); break;
1818 case GL_LIGHT1: context->setLight(1, true); break;
1819 case GL_LIGHT2: context->setLight(2, true); break;
1820 case GL_LIGHT3: context->setLight(3, true); break;
1821 case GL_LIGHT4: context->setLight(4, true); break;
1822 case GL_LIGHT5: context->setLight(5, true); break;
1823 case GL_LIGHT6: context->setLight(6, true); break;
1824 case GL_LIGHT7: context->setLight(7, true); break;
1825 case GL_RESCALE_NORMAL: context->setNormalizeNormals(true); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05001826 default:
1827 return error(GL_INVALID_ENUM);
1828 }
1829 }
1830}
1831
Nicolas Capensa9b49372015-01-30 00:33:26 -05001832void APIENTRY glEnableVertexAttribArray(GLuint index)
Nicolas Capens264f1522015-01-09 17:21:17 -05001833{
1834 TRACE("(GLuint index = %d)", index);
1835
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001836 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05001837 {
1838 return error(GL_INVALID_VALUE);
1839 }
1840
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001841 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001842
1843 if(context)
1844 {
1845 context->setEnableVertexAttribArray(index, true);
1846 }
1847}
1848
Nicolas Capensa9b49372015-01-30 00:33:26 -05001849void APIENTRY glEndQueryEXT(GLenum target)
Nicolas Capens264f1522015-01-09 17:21:17 -05001850{
1851 TRACE("GLenum target = 0x%X)", target);
1852
1853 switch(target)
1854 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001855 case GL_ANY_SAMPLES_PASSED:
1856 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
Nicolas Capens264f1522015-01-09 17:21:17 -05001857 break;
1858 default:
1859 return error(GL_INVALID_ENUM);
1860 }
1861
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001862 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001863
1864 if(context)
1865 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001866 if(context->getListIndex() != 0)
1867 {
1868 UNIMPLEMENTED();
1869 }
1870
Nicolas Capens264f1522015-01-09 17:21:17 -05001871 context->endQuery(target);
1872 }
1873}
1874
Nicolas Capensa9b49372015-01-30 00:33:26 -05001875void APIENTRY glFinishFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05001876{
1877 TRACE("(GLuint fence = %d)", fence);
1878
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001879 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001880
1881 if(context)
1882 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001883 if(context->getListIndex() != 0)
1884 {
1885 UNIMPLEMENTED();
1886 }
1887
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001888 gl::Fence* fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05001889
1890 if(fenceObject == NULL)
1891 {
1892 return error(GL_INVALID_OPERATION);
1893 }
1894
1895 fenceObject->finishFence();
1896 }
1897}
1898
Nicolas Capensa9b49372015-01-30 00:33:26 -05001899void APIENTRY glFinish(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05001900{
1901 TRACE("()");
1902
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001903 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001904
1905 if(context)
1906 {
1907 context->finish();
1908 }
1909}
1910
Nicolas Capensa9b49372015-01-30 00:33:26 -05001911void APIENTRY glFlush(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05001912{
1913 TRACE("()");
1914
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001915 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001916
1917 if(context)
1918 {
1919 context->flush();
1920 }
1921}
1922
Nicolas Capensa9b49372015-01-30 00:33:26 -05001923void APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05001924{
1925 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1926 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
1927
Nicolas Capensa9b49372015-01-30 00:33:26 -05001928 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT) ||
Nicolas Capens264f1522015-01-09 17:21:17 -05001929 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
1930 {
1931 return error(GL_INVALID_ENUM);
1932 }
1933
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001934 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05001935
1936 if(context)
1937 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05001938 if(context->getListIndex() != 0)
1939 {
1940 UNIMPLEMENTED();
1941 }
1942
Nicolas Capensf4486fd2015-01-22 11:10:37 -05001943 gl::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001944 GLuint framebufferName = 0;
Nicolas Capensa9b49372015-01-30 00:33:26 -05001945 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001946 {
1947 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001948 framebufferName = context->getReadFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05001949 }
1950 else
1951 {
1952 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001953 framebufferName = context->getDrawFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05001954 }
1955
Nicolas Capens7cc75e12015-01-29 14:44:24 -05001956 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
Nicolas Capens264f1522015-01-09 17:21:17 -05001957 {
1958 return error(GL_INVALID_OPERATION);
1959 }
1960
1961 switch(attachment)
1962 {
1963 case GL_COLOR_ATTACHMENT0:
1964 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1965 break;
1966 case GL_DEPTH_ATTACHMENT:
1967 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1968 break;
1969 case GL_STENCIL_ATTACHMENT:
1970 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1971 break;
1972 default:
1973 return error(GL_INVALID_ENUM);
1974 }
1975 }
1976}
1977
Nicolas Capensa9b49372015-01-30 00:33:26 -05001978void APIENTRY glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1979{
1980 UNIMPLEMENTED();
1981}
1982
1983void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
Nicolas Capens264f1522015-01-09 17:21:17 -05001984{
1985 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1986 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
1987
Nicolas Capensa9b49372015-01-30 00:33:26 -05001988 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05001989 {
1990 return error(GL_INVALID_ENUM);
1991 }
1992
1993 switch(attachment)
1994 {
1995 case GL_COLOR_ATTACHMENT0:
1996 case GL_DEPTH_ATTACHMENT:
1997 case GL_STENCIL_ATTACHMENT:
1998 break;
1999 default:
2000 return error(GL_INVALID_ENUM);
2001 }
2002
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002003 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002004
2005 if(context)
2006 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002007 if(context->getListIndex() != 0)
2008 {
2009 UNIMPLEMENTED();
2010 }
2011
Nicolas Capens264f1522015-01-09 17:21:17 -05002012 if(texture == 0)
2013 {
2014 textarget = GL_NONE;
2015 }
2016 else
2017 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002018 gl::Texture *tex = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -05002019
2020 if(tex == NULL)
2021 {
2022 return error(GL_INVALID_OPERATION);
2023 }
2024
2025 if(tex->isCompressed(textarget, level))
2026 {
2027 return error(GL_INVALID_OPERATION);
2028 }
2029
2030 switch(textarget)
2031 {
2032 case GL_TEXTURE_2D:
2033 if(tex->getTarget() != GL_TEXTURE_2D)
2034 {
2035 return error(GL_INVALID_OPERATION);
2036 }
2037 break;
2038 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2039 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2040 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2041 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2042 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2043 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2044 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2045 {
2046 return error(GL_INVALID_OPERATION);
2047 }
2048 break;
2049 default:
2050 return error(GL_INVALID_ENUM);
2051 }
2052
2053 if(level != 0)
2054 {
2055 return error(GL_INVALID_VALUE);
2056 }
2057 }
2058
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002059 gl::Framebuffer *framebuffer = NULL;
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002060 GLuint framebufferName = 0;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002061 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05002062 {
2063 framebuffer = context->getReadFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002064 framebufferName = context->getReadFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002065 }
2066 else
2067 {
2068 framebuffer = context->getDrawFramebuffer();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002069 framebufferName = context->getDrawFramebufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002070 }
2071
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002072 if(framebufferName == 0 || !framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05002073 {
2074 return error(GL_INVALID_OPERATION);
2075 }
2076
2077 switch(attachment)
2078 {
2079 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2080 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2081 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2082 }
2083 }
2084}
2085
Nicolas Capensa9b49372015-01-30 00:33:26 -05002086void APIENTRY glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
2087{
2088 UNIMPLEMENTED();
2089}
2090
2091void APIENTRY glFrontFace(GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05002092{
2093 TRACE("(GLenum mode = 0x%X)", mode);
2094
2095 switch(mode)
2096 {
2097 case GL_CW:
2098 case GL_CCW:
2099 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002100 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002101
2102 if(context)
2103 {
2104 context->setFrontFace(mode);
2105 }
2106 }
2107 break;
2108 default:
2109 return error(GL_INVALID_ENUM);
2110 }
2111}
2112
Nicolas Capensa9b49372015-01-30 00:33:26 -05002113void APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05002114{
2115 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
2116
2117 if(n < 0)
2118 {
2119 return error(GL_INVALID_VALUE);
2120 }
2121
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002122 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002123
2124 if(context)
2125 {
2126 for(int i = 0; i < n; i++)
2127 {
2128 buffers[i] = context->createBuffer();
2129 }
2130 }
2131}
2132
Nicolas Capensa9b49372015-01-30 00:33:26 -05002133void APIENTRY glGenerateMipmap(GLenum target)
Nicolas Capens264f1522015-01-09 17:21:17 -05002134{
2135 TRACE("(GLenum target = 0x%X)", target);
2136
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002137 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002138
2139 if(context)
2140 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002141 if(context->getListIndex() != 0)
2142 {
2143 UNIMPLEMENTED();
2144 }
2145
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002146 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05002147
2148 switch(target)
2149 {
2150 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05002151 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05002152 break;
2153 case GL_TEXTURE_CUBE_MAP:
2154 texture = context->getTextureCubeMap();
2155 break;
2156 default:
2157 return error(GL_INVALID_ENUM);
2158 }
2159
2160 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2161 {
2162 return error(GL_INVALID_OPERATION);
2163 }
2164
2165 texture->generateMipmaps();
2166 }
2167}
2168
Nicolas Capensa9b49372015-01-30 00:33:26 -05002169void APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
Nicolas Capens264f1522015-01-09 17:21:17 -05002170{
2171 TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
2172
2173 if(n < 0)
2174 {
2175 return error(GL_INVALID_VALUE);
2176 }
2177
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002178 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002179
2180 if(context)
2181 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002182 if(context->getListIndex() != 0)
2183 {
2184 UNIMPLEMENTED();
2185 }
2186
Nicolas Capens264f1522015-01-09 17:21:17 -05002187 for(int i = 0; i < n; i++)
2188 {
2189 fences[i] = context->createFence();
2190 }
2191 }
2192}
2193
Nicolas Capensa9b49372015-01-30 00:33:26 -05002194void APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05002195{
2196 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
2197
2198 if(n < 0)
2199 {
2200 return error(GL_INVALID_VALUE);
2201 }
2202
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002203 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002204
2205 if(context)
2206 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002207 if(context->getListIndex() != 0)
2208 {
2209 UNIMPLEMENTED();
2210 }
2211
Nicolas Capens264f1522015-01-09 17:21:17 -05002212 for(int i = 0; i < n; i++)
2213 {
2214 framebuffers[i] = context->createFramebuffer();
2215 }
2216 }
2217}
2218
Nicolas Capensa9b49372015-01-30 00:33:26 -05002219void APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
Nicolas Capens264f1522015-01-09 17:21:17 -05002220{
2221 TRACE("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
2222
2223 if(n < 0)
2224 {
2225 return error(GL_INVALID_VALUE);
2226 }
2227
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002228 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002229
2230 if(context)
2231 {
2232 for(int i = 0; i < n; i++)
2233 {
2234 ids[i] = context->createQuery();
2235 }
2236 }
2237}
2238
Nicolas Capensa9b49372015-01-30 00:33:26 -05002239void APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
Nicolas Capens264f1522015-01-09 17:21:17 -05002240{
2241 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
2242
2243 if(n < 0)
2244 {
2245 return error(GL_INVALID_VALUE);
2246 }
2247
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002248 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002249
2250 if(context)
2251 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002252 if(context->getListIndex() != 0)
2253 {
2254 UNIMPLEMENTED();
2255 }
2256
Nicolas Capens264f1522015-01-09 17:21:17 -05002257 for(int i = 0; i < n; i++)
2258 {
2259 renderbuffers[i] = context->createRenderbuffer();
2260 }
2261 }
2262}
2263
Nicolas Capensa9b49372015-01-30 00:33:26 -05002264void APIENTRY glGenTextures(GLsizei n, GLuint* textures)
Nicolas Capens264f1522015-01-09 17:21:17 -05002265{
2266 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
2267
2268 if(n < 0)
2269 {
2270 return error(GL_INVALID_VALUE);
2271 }
2272
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002273 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002274
2275 if(context)
2276 {
2277 for(int i = 0; i < n; i++)
2278 {
2279 textures[i] = context->createTexture();
2280 }
2281 }
2282}
2283
Nicolas Capensa9b49372015-01-30 00:33:26 -05002284void APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002285{
2286 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2287 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
2288 program, index, bufsize, length, size, type, name);
2289
2290 if(bufsize < 0)
2291 {
2292 return error(GL_INVALID_VALUE);
2293 }
2294
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002295 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002296
2297 if(context)
2298 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002299 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002300
2301 if(!programObject)
2302 {
2303 if(context->getShader(program))
2304 {
2305 return error(GL_INVALID_OPERATION);
2306 }
2307 else
2308 {
2309 return error(GL_INVALID_VALUE);
2310 }
2311 }
2312
2313 if(index >= (GLuint)programObject->getActiveAttributeCount())
2314 {
2315 return error(GL_INVALID_VALUE);
2316 }
2317
2318 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2319 }
2320}
2321
Nicolas Capensa9b49372015-01-30 00:33:26 -05002322void APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002323{
2324 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
2325 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = %s)",
2326 program, index, bufsize, length, size, type, name);
2327
2328 if(bufsize < 0)
2329 {
2330 return error(GL_INVALID_VALUE);
2331 }
2332
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002333 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002334
2335 if(context)
2336 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002337 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002338
2339 if(!programObject)
2340 {
2341 if(context->getShader(program))
2342 {
2343 return error(GL_INVALID_OPERATION);
2344 }
2345 else
2346 {
2347 return error(GL_INVALID_VALUE);
2348 }
2349 }
2350
2351 if(index >= (GLuint)programObject->getActiveUniformCount())
2352 {
2353 return error(GL_INVALID_VALUE);
2354 }
2355
2356 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2357 }
2358}
2359
Nicolas Capensa9b49372015-01-30 00:33:26 -05002360void APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
Nicolas Capens264f1522015-01-09 17:21:17 -05002361{
2362 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2363 program, maxcount, count, shaders);
2364
2365 if(maxcount < 0)
2366 {
2367 return error(GL_INVALID_VALUE);
2368 }
2369
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002370 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002371
2372 if(context)
2373 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002374 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002375
2376 if(!programObject)
2377 {
2378 if(context->getShader(program))
2379 {
2380 return error(GL_INVALID_OPERATION);
2381 }
2382 else
2383 {
2384 return error(GL_INVALID_VALUE);
2385 }
2386 }
2387
2388 return programObject->getAttachedShaders(maxcount, count, shaders);
2389 }
2390}
2391
Nicolas Capensa9b49372015-01-30 00:33:26 -05002392int APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002393{
2394 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
2395
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002396 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002397
2398 if(context)
2399 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002400 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002401
2402 if(!programObject)
2403 {
2404 if(context->getShader(program))
2405 {
2406 return error(GL_INVALID_OPERATION, -1);
2407 }
2408 else
2409 {
2410 return error(GL_INVALID_VALUE, -1);
2411 }
2412 }
2413
2414 if(!programObject->isLinked())
2415 {
2416 return error(GL_INVALID_OPERATION, -1);
2417 }
2418
2419 return programObject->getAttributeLocation(name);
2420 }
2421
2422 return -1;
2423}
2424
Nicolas Capensa9b49372015-01-30 00:33:26 -05002425void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002426{
2427 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
2428
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002429 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002430
2431 if(context)
2432 {
2433 if(!(context->getBooleanv(pname, params)))
2434 {
2435 GLenum nativeType;
2436 unsigned int numParams = 0;
2437 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2438 return error(GL_INVALID_ENUM);
2439
2440 if(numParams == 0)
2441 return; // it is known that the pname is valid, but there are no parameters to return
2442
2443 if(nativeType == GL_FLOAT)
2444 {
2445 GLfloat *floatParams = NULL;
2446 floatParams = new GLfloat[numParams];
2447
2448 context->getFloatv(pname, floatParams);
2449
2450 for(unsigned int i = 0; i < numParams; ++i)
2451 {
2452 if(floatParams[i] == 0.0f)
2453 params[i] = GL_FALSE;
2454 else
2455 params[i] = GL_TRUE;
2456 }
2457
2458 delete [] floatParams;
2459 }
2460 else if(nativeType == GL_INT)
2461 {
2462 GLint *intParams = NULL;
2463 intParams = new GLint[numParams];
2464
2465 context->getIntegerv(pname, intParams);
2466
2467 for(unsigned int i = 0; i < numParams; ++i)
2468 {
2469 if(intParams[i] == 0)
2470 params[i] = GL_FALSE;
2471 else
2472 params[i] = GL_TRUE;
2473 }
2474
2475 delete [] intParams;
2476 }
2477 }
2478 }
2479}
2480
Nicolas Capensa9b49372015-01-30 00:33:26 -05002481void APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002482{
2483 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
2484
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002485 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002486
2487 if(context)
2488 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002489 gl::Buffer *buffer;
Nicolas Capens264f1522015-01-09 17:21:17 -05002490
2491 switch(target)
2492 {
2493 case GL_ARRAY_BUFFER:
2494 buffer = context->getArrayBuffer();
2495 break;
2496 case GL_ELEMENT_ARRAY_BUFFER:
2497 buffer = context->getElementArrayBuffer();
2498 break;
2499 default:
2500 return error(GL_INVALID_ENUM);
2501 }
2502
2503 if(!buffer)
2504 {
2505 // A null buffer means that "0" is bound to the requested buffer target
2506 return error(GL_INVALID_OPERATION);
2507 }
2508
2509 switch(pname)
2510 {
2511 case GL_BUFFER_USAGE:
2512 *params = buffer->usage();
2513 break;
2514 case GL_BUFFER_SIZE:
2515 *params = buffer->size();
2516 break;
2517 default:
2518 return error(GL_INVALID_ENUM);
2519 }
2520 }
2521}
2522
Nicolas Capensa9b49372015-01-30 00:33:26 -05002523GLenum APIENTRY glGetError(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05002524{
2525 TRACE("()");
2526
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002527 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002528
2529 if(context)
2530 {
2531 return context->getError();
2532 }
2533
2534 return GL_NO_ERROR;
2535}
2536
Nicolas Capensa9b49372015-01-30 00:33:26 -05002537void APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002538{
2539 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
2540
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002541 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002542
2543 if(context)
2544 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002545 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05002546
2547 if(fenceObject == NULL)
2548 {
2549 return error(GL_INVALID_OPERATION);
2550 }
2551
2552 fenceObject->getFenceiv(pname, params);
2553 }
2554}
2555
Nicolas Capensa9b49372015-01-30 00:33:26 -05002556void APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002557{
2558 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
2559
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002560 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002561
2562 if(context)
2563 {
2564 if(!(context->getFloatv(pname, params)))
2565 {
2566 GLenum nativeType;
2567 unsigned int numParams = 0;
2568 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2569 return error(GL_INVALID_ENUM);
2570
2571 if(numParams == 0)
2572 return; // it is known that the pname is valid, but that there are no parameters to return.
2573
2574 if(nativeType == GL_BOOL)
2575 {
2576 GLboolean *boolParams = NULL;
2577 boolParams = new GLboolean[numParams];
2578
2579 context->getBooleanv(pname, boolParams);
2580
2581 for(unsigned int i = 0; i < numParams; ++i)
2582 {
2583 if(boolParams[i] == GL_FALSE)
2584 params[i] = 0.0f;
2585 else
2586 params[i] = 1.0f;
2587 }
2588
2589 delete [] boolParams;
2590 }
2591 else if(nativeType == GL_INT)
2592 {
2593 GLint *intParams = NULL;
2594 intParams = new GLint[numParams];
2595
2596 context->getIntegerv(pname, intParams);
2597
2598 for(unsigned int i = 0; i < numParams; ++i)
2599 {
2600 params[i] = (GLfloat)intParams[i];
2601 }
2602
2603 delete [] intParams;
2604 }
2605 }
2606 }
2607}
2608
Nicolas Capensa9b49372015-01-30 00:33:26 -05002609void APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002610{
2611 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2612 target, attachment, pname, params);
2613
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002614 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002615
2616 if(context)
2617 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002618 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05002619 {
2620 return error(GL_INVALID_ENUM);
2621 }
2622
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002623 gl::Framebuffer *framebuffer = NULL;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002624 if(target == GL_READ_FRAMEBUFFER_EXT)
Nicolas Capens264f1522015-01-09 17:21:17 -05002625 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002626 if(context->getReadFramebufferName() == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05002627 {
2628 return error(GL_INVALID_OPERATION);
2629 }
2630
2631 framebuffer = context->getReadFramebuffer();
2632 }
2633 else
2634 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002635 if(context->getDrawFramebufferName() == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05002636 {
2637 return error(GL_INVALID_OPERATION);
2638 }
2639
2640 framebuffer = context->getDrawFramebuffer();
2641 }
2642
2643 GLenum attachmentType;
2644 GLuint attachmentHandle;
2645 switch(attachment)
2646 {
2647 case GL_COLOR_ATTACHMENT0:
2648 attachmentType = framebuffer->getColorbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002649 attachmentHandle = framebuffer->getColorbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002650 break;
2651 case GL_DEPTH_ATTACHMENT:
2652 attachmentType = framebuffer->getDepthbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002653 attachmentHandle = framebuffer->getDepthbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002654 break;
2655 case GL_STENCIL_ATTACHMENT:
2656 attachmentType = framebuffer->getStencilbufferType();
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002657 attachmentHandle = framebuffer->getStencilbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05002658 break;
2659 default:
2660 return error(GL_INVALID_ENUM);
2661 }
2662
2663 GLenum attachmentObjectType; // Type category
2664 if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
2665 {
2666 attachmentObjectType = attachmentType;
2667 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002668 else if(gl::IsTextureTarget(attachmentType))
Nicolas Capens264f1522015-01-09 17:21:17 -05002669 {
2670 attachmentObjectType = GL_TEXTURE;
2671 }
2672 else UNREACHABLE();
2673
2674 switch(pname)
2675 {
2676 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2677 *params = attachmentObjectType;
2678 break;
2679 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2680 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2681 {
2682 *params = attachmentHandle;
2683 }
2684 else
2685 {
2686 return error(GL_INVALID_ENUM);
2687 }
2688 break;
2689 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2690 if(attachmentObjectType == GL_TEXTURE)
2691 {
2692 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2693 }
2694 else
2695 {
2696 return error(GL_INVALID_ENUM);
2697 }
2698 break;
2699 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2700 if(attachmentObjectType == GL_TEXTURE)
2701 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002702 if(gl::IsCubemapTextureTarget(attachmentType))
Nicolas Capens264f1522015-01-09 17:21:17 -05002703 {
2704 *params = attachmentType;
2705 }
2706 else
2707 {
2708 *params = 0;
2709 }
2710 }
2711 else
2712 {
2713 return error(GL_INVALID_ENUM);
2714 }
2715 break;
2716 default:
2717 return error(GL_INVALID_ENUM);
2718 }
2719 }
2720}
2721
Nicolas Capensa9b49372015-01-30 00:33:26 -05002722GLenum APIENTRY glGetGraphicsResetStatusEXT(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05002723{
2724 TRACE("()");
2725
2726 return GL_NO_ERROR;
2727}
2728
Nicolas Capensa9b49372015-01-30 00:33:26 -05002729void APIENTRY glGetIntegerv(GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002730{
2731 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
2732
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002733 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002734
2735 if(context)
2736 {
2737 if(!(context->getIntegerv(pname, params)))
2738 {
2739 GLenum nativeType;
2740 unsigned int numParams = 0;
2741 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2742 return error(GL_INVALID_ENUM);
2743
2744 if(numParams == 0)
2745 return; // it is known that pname is valid, but there are no parameters to return
2746
2747 if(nativeType == GL_BOOL)
2748 {
2749 GLboolean *boolParams = NULL;
2750 boolParams = new GLboolean[numParams];
2751
2752 context->getBooleanv(pname, boolParams);
2753
2754 for(unsigned int i = 0; i < numParams; ++i)
2755 {
2756 if(boolParams[i] == GL_FALSE)
2757 params[i] = 0;
2758 else
2759 params[i] = 1;
2760 }
2761
2762 delete [] boolParams;
2763 }
2764 else if(nativeType == GL_FLOAT)
2765 {
2766 GLfloat *floatParams = NULL;
2767 floatParams = new GLfloat[numParams];
2768
2769 context->getFloatv(pname, floatParams);
2770
2771 for(unsigned int i = 0; i < numParams; ++i)
2772 {
2773 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
2774 {
2775 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
2776 }
2777 else
2778 {
2779 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
2780 }
2781 }
2782
2783 delete [] floatParams;
2784 }
2785 }
2786 }
2787}
2788
Nicolas Capensa9b49372015-01-30 00:33:26 -05002789void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002790{
2791 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", program, pname, params);
2792
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002793 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002794
2795 if(context)
2796 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002797 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002798
2799 if(!programObject)
2800 {
2801 return error(GL_INVALID_VALUE);
2802 }
2803
2804 switch(pname)
2805 {
2806 case GL_DELETE_STATUS:
2807 *params = programObject->isFlaggedForDeletion();
2808 return;
2809 case GL_LINK_STATUS:
2810 *params = programObject->isLinked();
2811 return;
2812 case GL_VALIDATE_STATUS:
2813 *params = programObject->isValidated();
2814 return;
2815 case GL_INFO_LOG_LENGTH:
2816 *params = programObject->getInfoLogLength();
2817 return;
2818 case GL_ATTACHED_SHADERS:
2819 *params = programObject->getAttachedShadersCount();
2820 return;
2821 case GL_ACTIVE_ATTRIBUTES:
2822 *params = programObject->getActiveAttributeCount();
2823 return;
2824 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2825 *params = programObject->getActiveAttributeMaxLength();
2826 return;
2827 case GL_ACTIVE_UNIFORMS:
2828 *params = programObject->getActiveUniformCount();
2829 return;
2830 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2831 *params = programObject->getActiveUniformMaxLength();
2832 return;
2833 default:
2834 return error(GL_INVALID_ENUM);
2835 }
2836 }
2837}
2838
Nicolas Capensa9b49372015-01-30 00:33:26 -05002839void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
Nicolas Capens264f1522015-01-09 17:21:17 -05002840{
2841 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
2842 program, bufsize, length, infolog);
2843
2844 if(bufsize < 0)
2845 {
2846 return error(GL_INVALID_VALUE);
2847 }
2848
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002849 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002850
2851 if(context)
2852 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002853 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05002854
2855 if(!programObject)
2856 {
2857 return error(GL_INVALID_VALUE);
2858 }
2859
2860 programObject->getInfoLog(bufsize, length, infolog);
2861 }
2862}
2863
Nicolas Capensa9b49372015-01-30 00:33:26 -05002864void APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002865{
2866 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
2867
2868 switch(pname)
2869 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002870 case GL_CURRENT_QUERY:
Nicolas Capens264f1522015-01-09 17:21:17 -05002871 break;
2872 default:
2873 return error(GL_INVALID_ENUM);
2874 }
2875
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002876 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002877
2878 if(context)
2879 {
2880 params[0] = context->getActiveQuery(target);
2881 }
2882}
2883
Nicolas Capensa9b49372015-01-30 00:33:26 -05002884void APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002885{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002886 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", name, pname, params);
Nicolas Capens264f1522015-01-09 17:21:17 -05002887
2888 switch(pname)
2889 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002890 case GL_QUERY_RESULT:
2891 case GL_QUERY_RESULT_AVAILABLE:
Nicolas Capens264f1522015-01-09 17:21:17 -05002892 break;
2893 default:
2894 return error(GL_INVALID_ENUM);
2895 }
2896
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002897 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002898
2899 if(context)
2900 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002901 gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
Nicolas Capens264f1522015-01-09 17:21:17 -05002902
2903 if(!queryObject)
2904 {
2905 return error(GL_INVALID_OPERATION);
2906 }
2907
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002908 if(context->getActiveQuery(queryObject->getType()) == name)
Nicolas Capens264f1522015-01-09 17:21:17 -05002909 {
2910 return error(GL_INVALID_OPERATION);
2911 }
2912
2913 switch(pname)
2914 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05002915 case GL_QUERY_RESULT:
Nicolas Capens264f1522015-01-09 17:21:17 -05002916 params[0] = queryObject->getResult();
2917 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002918 case GL_QUERY_RESULT_AVAILABLE:
Nicolas Capens264f1522015-01-09 17:21:17 -05002919 params[0] = queryObject->isResultAvailable();
2920 break;
2921 default:
2922 ASSERT(false);
2923 }
2924 }
2925}
2926
Nicolas Capensa9b49372015-01-30 00:33:26 -05002927void APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002928{
2929 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
2930
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002931 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002932
2933 if(context)
2934 {
2935 if(target != GL_RENDERBUFFER)
2936 {
2937 return error(GL_INVALID_ENUM);
2938 }
2939
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002940 if(context->getRenderbufferName() == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05002941 {
2942 return error(GL_INVALID_OPERATION);
2943 }
2944
Nicolas Capens7cc75e12015-01-29 14:44:24 -05002945 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
Nicolas Capens264f1522015-01-09 17:21:17 -05002946
2947 switch(pname)
2948 {
2949 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
2950 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
2951 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break;
2952 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
2953 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
2954 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
2955 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
2956 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
2957 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05002958 case GL_RENDERBUFFER_SAMPLES_EXT: *params = renderbuffer->getSamples(); break;
Nicolas Capens264f1522015-01-09 17:21:17 -05002959 default:
2960 return error(GL_INVALID_ENUM);
2961 }
2962 }
2963}
2964
Nicolas Capensa9b49372015-01-30 00:33:26 -05002965void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05002966{
2967 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
2968
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002969 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05002970
2971 if(context)
2972 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05002973 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05002974
2975 if(!shaderObject)
2976 {
2977 return error(GL_INVALID_VALUE);
2978 }
2979
2980 switch(pname)
2981 {
2982 case GL_SHADER_TYPE:
2983 *params = shaderObject->getType();
2984 return;
2985 case GL_DELETE_STATUS:
2986 *params = shaderObject->isFlaggedForDeletion();
2987 return;
2988 case GL_COMPILE_STATUS:
2989 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2990 return;
2991 case GL_INFO_LOG_LENGTH:
2992 *params = shaderObject->getInfoLogLength();
2993 return;
2994 case GL_SHADER_SOURCE_LENGTH:
2995 *params = shaderObject->getSourceLength();
2996 return;
2997 default:
2998 return error(GL_INVALID_ENUM);
2999 }
3000 }
3001}
3002
Nicolas Capensa9b49372015-01-30 00:33:26 -05003003void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
Nicolas Capens264f1522015-01-09 17:21:17 -05003004{
3005 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
3006 shader, bufsize, length, infolog);
3007
3008 if(bufsize < 0)
3009 {
3010 return error(GL_INVALID_VALUE);
3011 }
3012
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003013 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003014
3015 if(context)
3016 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003017 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003018
3019 if(!shaderObject)
3020 {
3021 return error(GL_INVALID_VALUE);
3022 }
3023
3024 shaderObject->getInfoLog(bufsize, length, infolog);
3025 }
3026}
3027
Nicolas Capensa9b49372015-01-30 00:33:26 -05003028void APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
Nicolas Capens264f1522015-01-09 17:21:17 -05003029{
3030 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
3031 shadertype, precisiontype, range, precision);
3032
3033 switch(shadertype)
3034 {
3035 case GL_VERTEX_SHADER:
3036 case GL_FRAGMENT_SHADER:
3037 break;
3038 default:
3039 return error(GL_INVALID_ENUM);
3040 }
3041
3042 switch(precisiontype)
3043 {
3044 case GL_LOW_FLOAT:
3045 case GL_MEDIUM_FLOAT:
3046 case GL_HIGH_FLOAT:
3047 // IEEE 754 single-precision
3048 range[0] = 127;
3049 range[1] = 127;
3050 *precision = 23;
3051 break;
3052 case GL_LOW_INT:
3053 case GL_MEDIUM_INT:
3054 case GL_HIGH_INT:
3055 // Single-precision floating-point numbers can accurately represent integers up to +/-16777216
3056 range[0] = 24;
3057 range[1] = 24;
3058 *precision = 0;
3059 break;
3060 default:
3061 return error(GL_INVALID_ENUM);
3062 }
3063}
3064
Nicolas Capensa9b49372015-01-30 00:33:26 -05003065void APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
Nicolas Capens264f1522015-01-09 17:21:17 -05003066{
3067 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3068 shader, bufsize, length, source);
3069
3070 if(bufsize < 0)
3071 {
3072 return error(GL_INVALID_VALUE);
3073 }
3074
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003075 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003076
3077 if(context)
3078 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003079 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003080
3081 if(!shaderObject)
3082 {
3083 return error(GL_INVALID_OPERATION);
3084 }
3085
3086 shaderObject->getSource(bufsize, length, source);
3087 }
3088}
3089
Nicolas Capensa9b49372015-01-30 00:33:26 -05003090const GLubyte* APIENTRY glGetString(GLenum name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003091{
3092 TRACE("(GLenum name = 0x%X)", name);
3093
Nicolas Capens264f1522015-01-09 17:21:17 -05003094 switch(name)
3095 {
3096 case GL_VENDOR:
3097 return (GLubyte*)"TransGaming Inc.";
3098 case GL_RENDERER:
3099 return (GLubyte*)"SwiftShader";
3100 case GL_VERSION:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003101 return (GLubyte*)"2.1 SwiftShader "VERSION_STRING;
Nicolas Capens264f1522015-01-09 17:21:17 -05003102 case GL_SHADING_LANGUAGE_VERSION:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003103 return (GLubyte*)"3.30 SwiftShader "VERSION_STRING;
Nicolas Capens264f1522015-01-09 17:21:17 -05003104 case GL_EXTENSIONS:
3105 // Keep list sorted in following order:
3106 // OES extensions
3107 // EXT extensions
3108 // Vendor extensions
3109 return (GLubyte*)
Nicolas Capensa9b49372015-01-30 00:33:26 -05003110 "GL_ARB_framebuffer_object "
Nicolas Capens264f1522015-01-09 17:21:17 -05003111 "GL_EXT_blend_minmax "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003112 "GL_EXT_depth_texture "
3113 "GL_EXT_depth_texture_cube_map "
3114 "GL_EXT_element_index_uint "
3115 "GL_EXT_packed_depth_stencil "
3116 "GL_EXT_rgb8_rgba8 "
3117 "GL_EXT_standard_derivatives "
3118 "GL_EXT_texture_float "
3119 "GL_EXT_texture_float_linear "
3120 "GL_EXT_texture_half_float "
3121 "GL_EXT_texture_half_float_linear "
3122 "GL_EXT_texture_npot "
Nicolas Capens264f1522015-01-09 17:21:17 -05003123 "GL_EXT_occlusion_query_boolean "
3124 "GL_EXT_read_format_bgra "
3125 #if (S3TC_SUPPORT)
3126 "GL_EXT_texture_compression_dxt1 "
3127 #endif
Nicolas Capensa9b49372015-01-30 00:33:26 -05003128 "GL_EXT_blend_func_separate "
3129 "GL_EXT_secondary_color "
Nicolas Capens264f1522015-01-09 17:21:17 -05003130 "GL_EXT_texture_filter_anisotropic "
3131 "GL_EXT_texture_format_BGRA8888 "
Nicolas Capensa9b49372015-01-30 00:33:26 -05003132 "GL_EXT_framebuffer_blit "
3133 "GL_EXT_framebuffer_multisample "
Nicolas Capens264f1522015-01-09 17:21:17 -05003134 #if (S3TC_SUPPORT)
Nicolas Capensa9b49372015-01-30 00:33:26 -05003135 "GL_EXT_texture_compression_dxt3 "
3136 "GL_EXT_texture_compression_dxt5 "
Nicolas Capens264f1522015-01-09 17:21:17 -05003137 #endif
3138 "GL_NV_fence";
3139 default:
3140 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3141 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05003142
3143 return NULL;
Nicolas Capens264f1522015-01-09 17:21:17 -05003144}
3145
Nicolas Capensa9b49372015-01-30 00:33:26 -05003146void APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003147{
3148 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
3149
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003150 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003151
3152 if(context)
3153 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003154 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05003155
3156 switch(target)
3157 {
3158 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003159 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05003160 break;
3161 case GL_TEXTURE_CUBE_MAP:
3162 texture = context->getTextureCubeMap();
3163 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003164 default:
3165 return error(GL_INVALID_ENUM);
3166 }
3167
3168 switch(pname)
3169 {
3170 case GL_TEXTURE_MAG_FILTER:
3171 *params = (GLfloat)texture->getMagFilter();
3172 break;
3173 case GL_TEXTURE_MIN_FILTER:
3174 *params = (GLfloat)texture->getMinFilter();
3175 break;
3176 case GL_TEXTURE_WRAP_S:
3177 *params = (GLfloat)texture->getWrapS();
3178 break;
3179 case GL_TEXTURE_WRAP_T:
3180 *params = (GLfloat)texture->getWrapT();
3181 break;
3182 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3183 *params = texture->getMaxAnisotropy();
3184 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003185 default:
3186 return error(GL_INVALID_ENUM);
3187 }
3188 }
3189}
3190
Nicolas Capensa9b49372015-01-30 00:33:26 -05003191void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003192{
3193 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
3194
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003195 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003196
3197 if(context)
3198 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003199 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05003200
3201 switch(target)
3202 {
3203 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003204 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05003205 break;
3206 case GL_TEXTURE_CUBE_MAP:
3207 texture = context->getTextureCubeMap();
3208 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003209 default:
3210 return error(GL_INVALID_ENUM);
3211 }
3212
3213 switch(pname)
3214 {
3215 case GL_TEXTURE_MAG_FILTER:
3216 *params = texture->getMagFilter();
3217 break;
3218 case GL_TEXTURE_MIN_FILTER:
3219 *params = texture->getMinFilter();
3220 break;
3221 case GL_TEXTURE_WRAP_S:
3222 *params = texture->getWrapS();
3223 break;
3224 case GL_TEXTURE_WRAP_T:
3225 *params = texture->getWrapT();
3226 break;
3227 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3228 *params = (GLint)texture->getMaxAnisotropy();
3229 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05003230 default:
3231 return error(GL_INVALID_ENUM);
3232 }
3233 }
3234}
3235
Nicolas Capensa9b49372015-01-30 00:33:26 -05003236void APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003237{
3238 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
3239 program, location, bufSize, params);
3240
3241 if(bufSize < 0)
3242 {
3243 return error(GL_INVALID_VALUE);
3244 }
3245
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003246 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003247
3248 if(context)
3249 {
3250 if(program == 0)
3251 {
3252 return error(GL_INVALID_VALUE);
3253 }
3254
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003255 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003256
3257 if(!programObject || !programObject->isLinked())
3258 {
3259 return error(GL_INVALID_OPERATION);
3260 }
3261
3262 if(!programObject->getUniformfv(location, &bufSize, params))
3263 {
3264 return error(GL_INVALID_OPERATION);
3265 }
3266 }
3267}
3268
Nicolas Capensa9b49372015-01-30 00:33:26 -05003269void APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003270{
3271 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
3272
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003273 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003274
3275 if(context)
3276 {
3277 if(program == 0)
3278 {
3279 return error(GL_INVALID_VALUE);
3280 }
3281
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003282 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003283
3284 if(!programObject || !programObject->isLinked())
3285 {
3286 return error(GL_INVALID_OPERATION);
3287 }
3288
3289 if(!programObject->getUniformfv(location, NULL, params))
3290 {
3291 return error(GL_INVALID_OPERATION);
3292 }
3293 }
3294}
3295
Nicolas Capensa9b49372015-01-30 00:33:26 -05003296void APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003297{
3298 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
3299 program, location, bufSize, params);
3300
3301 if(bufSize < 0)
3302 {
3303 return error(GL_INVALID_VALUE);
3304 }
3305
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003306 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003307
3308 if(context)
3309 {
3310 if(program == 0)
3311 {
3312 return error(GL_INVALID_VALUE);
3313 }
3314
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003315 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003316
3317 if(!programObject || !programObject->isLinked())
3318 {
3319 return error(GL_INVALID_OPERATION);
3320 }
3321
3322 if(!programObject)
3323 {
3324 return error(GL_INVALID_OPERATION);
3325 }
3326
3327 if(!programObject->getUniformiv(location, &bufSize, params))
3328 {
3329 return error(GL_INVALID_OPERATION);
3330 }
3331 }
3332}
3333
Nicolas Capensa9b49372015-01-30 00:33:26 -05003334void APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003335{
3336 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
3337
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003338 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003339
3340 if(context)
3341 {
3342 if(program == 0)
3343 {
3344 return error(GL_INVALID_VALUE);
3345 }
3346
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003347 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003348
3349 if(!programObject || !programObject->isLinked())
3350 {
3351 return error(GL_INVALID_OPERATION);
3352 }
3353
3354 if(!programObject)
3355 {
3356 return error(GL_INVALID_OPERATION);
3357 }
3358
3359 if(!programObject->getUniformiv(location, NULL, params))
3360 {
3361 return error(GL_INVALID_OPERATION);
3362 }
3363 }
3364}
3365
Nicolas Capensa9b49372015-01-30 00:33:26 -05003366int APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003367{
3368 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
3369
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003370 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003371
3372 if(strstr(name, "gl_") == name)
3373 {
3374 return -1;
3375 }
3376
3377 if(context)
3378 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003379 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003380
3381 if(!programObject)
3382 {
3383 if(context->getShader(program))
3384 {
3385 return error(GL_INVALID_OPERATION, -1);
3386 }
3387 else
3388 {
3389 return error(GL_INVALID_VALUE, -1);
3390 }
3391 }
3392
3393 if(!programObject->isLinked())
3394 {
3395 return error(GL_INVALID_OPERATION, -1);
3396 }
3397
3398 return programObject->getUniformLocation(name);
3399 }
3400
3401 return -1;
3402}
3403
Nicolas Capensa9b49372015-01-30 00:33:26 -05003404void APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003405{
3406 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
3407
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003408 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003409
3410 if(context)
3411 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003412 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003413 {
3414 return error(GL_INVALID_VALUE);
3415 }
3416
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003417 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
Nicolas Capens264f1522015-01-09 17:21:17 -05003418
3419 switch(pname)
3420 {
3421 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3422 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3423 break;
3424 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3425 *params = (GLfloat)attribState.mSize;
3426 break;
3427 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3428 *params = (GLfloat)attribState.mStride;
3429 break;
3430 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3431 *params = (GLfloat)attribState.mType;
3432 break;
3433 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3434 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
3435 break;
3436 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003437 *params = (GLfloat)attribState.mBoundBuffer.name();
Nicolas Capens264f1522015-01-09 17:21:17 -05003438 break;
3439 case GL_CURRENT_VERTEX_ATTRIB:
3440 for(int i = 0; i < 4; ++i)
3441 {
3442 params[i] = attribState.mCurrentValue[i];
3443 }
3444 break;
3445 default: return error(GL_INVALID_ENUM);
3446 }
3447 }
3448}
3449
Nicolas Capensa9b49372015-01-30 00:33:26 -05003450void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05003451{
3452 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
3453
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003454 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003455
3456 if(context)
3457 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003458 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003459 {
3460 return error(GL_INVALID_VALUE);
3461 }
3462
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003463 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
Nicolas Capens264f1522015-01-09 17:21:17 -05003464
3465 switch(pname)
3466 {
3467 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3468 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3469 break;
3470 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3471 *params = attribState.mSize;
3472 break;
3473 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3474 *params = attribState.mStride;
3475 break;
3476 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3477 *params = attribState.mType;
3478 break;
3479 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3480 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
3481 break;
3482 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003483 *params = attribState.mBoundBuffer.name();
Nicolas Capens264f1522015-01-09 17:21:17 -05003484 break;
3485 case GL_CURRENT_VERTEX_ATTRIB:
3486 for(int i = 0; i < 4; ++i)
3487 {
3488 float currentValue = attribState.mCurrentValue[i];
3489 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3490 }
3491 break;
3492 default: return error(GL_INVALID_ENUM);
3493 }
3494 }
3495}
3496
Nicolas Capensa9b49372015-01-30 00:33:26 -05003497void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003498{
3499 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
3500
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003501 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003502
3503 if(context)
3504 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003505 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05003506 {
3507 return error(GL_INVALID_VALUE);
3508 }
3509
3510 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3511 {
3512 return error(GL_INVALID_ENUM);
3513 }
3514
3515 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
3516 }
3517}
3518
Nicolas Capensa9b49372015-01-30 00:33:26 -05003519void APIENTRY glHint(GLenum target, GLenum mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05003520{
3521 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
3522
3523 switch(mode)
3524 {
3525 case GL_FASTEST:
3526 case GL_NICEST:
3527 case GL_DONT_CARE:
3528 break;
3529 default:
3530 return error(GL_INVALID_ENUM);
3531 }
3532
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003533 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003534 switch(target)
3535 {
3536 case GL_GENERATE_MIPMAP_HINT:
3537 if(context) context->setGenerateMipmapHint(mode);
3538 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05003539 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
Nicolas Capens264f1522015-01-09 17:21:17 -05003540 if(context) context->setFragmentShaderDerivativeHint(mode);
3541 break;
3542 default:
3543 return error(GL_INVALID_ENUM);
3544 }
3545}
3546
Nicolas Capensa9b49372015-01-30 00:33:26 -05003547GLboolean APIENTRY glIsBuffer(GLuint buffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003548{
3549 TRACE("(GLuint buffer = %d)", buffer);
3550
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003551 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003552
3553 if(context && buffer)
3554 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003555 gl::Buffer *bufferObject = context->getBuffer(buffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003556
3557 if(bufferObject)
3558 {
3559 return GL_TRUE;
3560 }
3561 }
3562
3563 return GL_FALSE;
3564}
3565
Nicolas Capensa9b49372015-01-30 00:33:26 -05003566GLboolean APIENTRY glIsEnabled(GLenum cap)
Nicolas Capens264f1522015-01-09 17:21:17 -05003567{
3568 TRACE("(GLenum cap = 0x%X)", cap);
3569
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003570 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003571
3572 if(context)
3573 {
3574 switch(cap)
3575 {
3576 case GL_CULL_FACE: return context->isCullFaceEnabled();
3577 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3578 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3579 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3580 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3581 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3582 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3583 case GL_BLEND: return context->isBlendEnabled();
3584 case GL_DITHER: return context->isDitherEnabled();
3585 default:
3586 return error(GL_INVALID_ENUM, false);
3587 }
3588 }
3589
3590 return false;
3591}
3592
Nicolas Capensa9b49372015-01-30 00:33:26 -05003593GLboolean APIENTRY glIsFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05003594{
3595 TRACE("(GLuint fence = %d)", fence);
3596
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003597 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003598
3599 if(context)
3600 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003601 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05003602
3603 if(fenceObject == NULL)
3604 {
3605 return GL_FALSE;
3606 }
3607
3608 return fenceObject->isFence();
3609 }
3610
3611 return GL_FALSE;
3612}
3613
Nicolas Capensa9b49372015-01-30 00:33:26 -05003614GLboolean APIENTRY glIsFramebuffer(GLuint framebuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003615{
3616 TRACE("(GLuint framebuffer = %d)", framebuffer);
3617
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003618 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003619
3620 if(context && framebuffer)
3621 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003622 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003623
3624 if(framebufferObject)
3625 {
3626 return GL_TRUE;
3627 }
3628 }
3629
3630 return GL_FALSE;
3631}
3632
Nicolas Capensa9b49372015-01-30 00:33:26 -05003633GLboolean APIENTRY glIsProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05003634{
3635 TRACE("(GLuint program = %d)", program);
3636
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003637 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003638
3639 if(context && program)
3640 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003641 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003642
3643 if(programObject)
3644 {
3645 return GL_TRUE;
3646 }
3647 }
3648
3649 return GL_FALSE;
3650}
3651
Nicolas Capensa9b49372015-01-30 00:33:26 -05003652GLboolean APIENTRY glIsQueryEXT(GLuint name)
Nicolas Capens264f1522015-01-09 17:21:17 -05003653{
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003654 TRACE("(GLuint name = %d)", name);
Nicolas Capens264f1522015-01-09 17:21:17 -05003655
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003656 if(name == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05003657 {
3658 return GL_FALSE;
3659 }
3660
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003661 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003662
3663 if(context)
3664 {
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003665 gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
Nicolas Capens264f1522015-01-09 17:21:17 -05003666
3667 if(queryObject)
3668 {
3669 return GL_TRUE;
3670 }
3671 }
3672
3673 return GL_FALSE;
3674}
3675
Nicolas Capensa9b49372015-01-30 00:33:26 -05003676GLboolean APIENTRY glIsRenderbuffer(GLuint renderbuffer)
Nicolas Capens264f1522015-01-09 17:21:17 -05003677{
3678 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
3679
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003680 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003681
3682 if(context && renderbuffer)
3683 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003684 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
Nicolas Capens264f1522015-01-09 17:21:17 -05003685
3686 if(renderbufferObject)
3687 {
3688 return GL_TRUE;
3689 }
3690 }
3691
3692 return GL_FALSE;
3693}
3694
Nicolas Capensa9b49372015-01-30 00:33:26 -05003695GLboolean APIENTRY glIsShader(GLuint shader)
Nicolas Capens264f1522015-01-09 17:21:17 -05003696{
3697 TRACE("(GLuint shader = %d)", shader);
3698
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003699 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003700
3701 if(context && shader)
3702 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003703 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05003704
3705 if(shaderObject)
3706 {
3707 return GL_TRUE;
3708 }
3709 }
3710
3711 return GL_FALSE;
3712}
3713
Nicolas Capensa9b49372015-01-30 00:33:26 -05003714GLboolean APIENTRY glIsTexture(GLuint texture)
Nicolas Capens264f1522015-01-09 17:21:17 -05003715{
3716 TRACE("(GLuint texture = %d)", texture);
3717
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003718 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003719
3720 if(context && texture)
3721 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003722 gl::Texture *textureObject = context->getTexture(texture);
Nicolas Capens264f1522015-01-09 17:21:17 -05003723
3724 if(textureObject)
3725 {
3726 return GL_TRUE;
3727 }
3728 }
3729
3730 return GL_FALSE;
3731}
3732
Nicolas Capensa9b49372015-01-30 00:33:26 -05003733void APIENTRY glLineWidth(GLfloat width)
Nicolas Capens264f1522015-01-09 17:21:17 -05003734{
3735 TRACE("(GLfloat width = %f)", width);
3736
3737 if(width <= 0.0f)
3738 {
3739 return error(GL_INVALID_VALUE);
3740 }
3741
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003742 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003743
3744 if(context)
3745 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003746 if(context->getListIndex() != 0)
3747 {
3748 UNIMPLEMENTED();
3749 }
3750
Nicolas Capens264f1522015-01-09 17:21:17 -05003751 context->setLineWidth(width);
3752 }
3753}
3754
Nicolas Capensa9b49372015-01-30 00:33:26 -05003755void APIENTRY glLinkProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05003756{
3757 TRACE("(GLuint program = %d)", program);
3758
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003759 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003760
3761 if(context)
3762 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003763 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05003764
3765 if(!programObject)
3766 {
3767 if(context->getShader(program))
3768 {
3769 return error(GL_INVALID_OPERATION);
3770 }
3771 else
3772 {
3773 return error(GL_INVALID_VALUE);
3774 }
3775 }
3776
3777 programObject->link();
3778 }
3779}
3780
Nicolas Capensa9b49372015-01-30 00:33:26 -05003781void APIENTRY glPixelStorei(GLenum pname, GLint param)
Nicolas Capens264f1522015-01-09 17:21:17 -05003782{
3783 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
3784
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003785 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003786
3787 if(context)
3788 {
3789 switch(pname)
3790 {
3791 case GL_UNPACK_ALIGNMENT:
3792 if(param != 1 && param != 2 && param != 4 && param != 8)
3793 {
3794 return error(GL_INVALID_VALUE);
3795 }
3796 context->setUnpackAlignment(param);
3797 break;
3798 case GL_PACK_ALIGNMENT:
3799 if(param != 1 && param != 2 && param != 4 && param != 8)
3800 {
3801 return error(GL_INVALID_VALUE);
3802 }
3803 context->setPackAlignment(param);
3804 break;
3805 default:
3806 return error(GL_INVALID_ENUM);
3807 }
3808 }
3809}
3810
Nicolas Capensa9b49372015-01-30 00:33:26 -05003811void APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
Nicolas Capens264f1522015-01-09 17:21:17 -05003812{
3813 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
3814
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003815 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003816
3817 if(context)
3818 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003819 if(context->getListIndex() != 0)
3820 {
3821 UNIMPLEMENTED();
3822 }
3823
Nicolas Capens264f1522015-01-09 17:21:17 -05003824 context->setPolygonOffsetParams(factor, units);
3825 }
3826}
3827
Nicolas Capensa9b49372015-01-30 00:33:26 -05003828void APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -05003829 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
3830{
3831 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
3832 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
3833 x, y, width, height, format, type, bufSize, data);
3834
3835 if(width < 0 || height < 0 || bufSize < 0)
3836 {
3837 return error(GL_INVALID_VALUE);
3838 }
3839
3840 if(!validReadFormatType(format, type))
3841 {
3842 return error(GL_INVALID_OPERATION);
3843 }
3844
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003845 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003846
3847 if(context)
3848 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003849 if(context->getListIndex() != 0)
3850 {
3851 UNIMPLEMENTED();
3852 }
3853
Nicolas Capens264f1522015-01-09 17:21:17 -05003854 context->readPixels(x, y, width, height, format, type, &bufSize, data);
3855 }
3856}
3857
Nicolas Capensa9b49372015-01-30 00:33:26 -05003858void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
Nicolas Capens264f1522015-01-09 17:21:17 -05003859{
3860 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
3861 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
3862 x, y, width, height, format, type, pixels);
3863
3864 if(width < 0 || height < 0)
3865 {
3866 return error(GL_INVALID_VALUE);
3867 }
3868
3869 if(!validReadFormatType(format, type))
3870 {
3871 return error(GL_INVALID_OPERATION);
3872 }
3873
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003874 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003875
3876 if(context)
3877 {
3878 context->readPixels(x, y, width, height, format, type, NULL, pixels);
3879 }
3880}
3881
Nicolas Capensa9b49372015-01-30 00:33:26 -05003882void APIENTRY glReleaseShaderCompiler(void)
Nicolas Capens264f1522015-01-09 17:21:17 -05003883{
3884 TRACE("()");
3885
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003886 gl::Shader::releaseCompiler();
Nicolas Capens264f1522015-01-09 17:21:17 -05003887}
3888
Nicolas Capensa9b49372015-01-30 00:33:26 -05003889void APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05003890{
3891 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3892 target, samples, internalformat, width, height);
3893
3894 switch(target)
3895 {
3896 case GL_RENDERBUFFER:
3897 break;
3898 default:
3899 return error(GL_INVALID_ENUM);
3900 }
3901
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003902 if(!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
Nicolas Capens264f1522015-01-09 17:21:17 -05003903 {
3904 return error(GL_INVALID_ENUM);
3905 }
3906
3907 if(width < 0 || height < 0 || samples < 0)
3908 {
3909 return error(GL_INVALID_VALUE);
3910 }
3911
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003912 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003913
3914 if(context)
3915 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003916 if(context->getListIndex() != 0)
3917 {
3918 UNIMPLEMENTED();
3919 }
3920
3921 if(width > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003922 height > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
3923 samples > gl::IMPLEMENTATION_MAX_SAMPLES)
Nicolas Capens264f1522015-01-09 17:21:17 -05003924 {
3925 return error(GL_INVALID_VALUE);
3926 }
3927
Nicolas Capens7cc75e12015-01-29 14:44:24 -05003928 GLuint handle = context->getRenderbufferName();
Nicolas Capens264f1522015-01-09 17:21:17 -05003929 if(handle == 0)
3930 {
3931 return error(GL_INVALID_OPERATION);
3932 }
3933
3934 switch(internalformat)
3935 {
3936 case GL_DEPTH_COMPONENT16:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003937 case GL_DEPTH_COMPONENT24:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003938 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003939 break;
3940 case GL_RGBA4:
3941 case GL_RGB5_A1:
3942 case GL_RGB565:
Nicolas Capensa9b49372015-01-30 00:33:26 -05003943 case GL_RGB8_EXT:
3944 case GL_RGBA8_EXT:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003945 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003946 break;
3947 case GL_STENCIL_INDEX8:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003948 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003949 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05003950 case GL_DEPTH24_STENCIL8_EXT:
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003951 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
Nicolas Capens264f1522015-01-09 17:21:17 -05003952 break;
3953 default:
3954 return error(GL_INVALID_ENUM);
3955 }
3956 }
3957}
3958
Nicolas Capensa9b49372015-01-30 00:33:26 -05003959void APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05003960{
3961 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
3962}
3963
Nicolas Capensa9b49372015-01-30 00:33:26 -05003964void APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
Nicolas Capens264f1522015-01-09 17:21:17 -05003965{
3966 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
3967
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003968 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003969
3970 if(context)
3971 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003972 if(context->getListIndex() != 0)
3973 {
3974 UNIMPLEMENTED();
3975 }
3976
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003977 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
Nicolas Capens264f1522015-01-09 17:21:17 -05003978 }
3979}
3980
Nicolas Capensa9b49372015-01-30 00:33:26 -05003981void APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
Nicolas Capens264f1522015-01-09 17:21:17 -05003982{
3983 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
3984
3985 if(condition != GL_ALL_COMPLETED_NV)
3986 {
3987 return error(GL_INVALID_ENUM);
3988 }
3989
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003990 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05003991
3992 if(context)
3993 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05003994 if(context->getListIndex() != 0)
3995 {
3996 UNIMPLEMENTED();
3997 }
3998
Nicolas Capensf4486fd2015-01-22 11:10:37 -05003999 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05004000
4001 if(fenceObject == NULL)
4002 {
4003 return error(GL_INVALID_OPERATION);
4004 }
4005
4006 fenceObject->setFence(condition);
4007 }
4008}
4009
Nicolas Capensa9b49372015-01-30 00:33:26 -05004010void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05004011{
4012 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4013
4014 if(width < 0 || height < 0)
4015 {
4016 return error(GL_INVALID_VALUE);
4017 }
4018
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004019 gl::Context* context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004020
4021 if(context)
4022 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004023 if(context->getListIndex() != 0)
4024 {
4025 UNIMPLEMENTED();
4026 }
4027
Nicolas Capens264f1522015-01-09 17:21:17 -05004028 context->setScissorParams(x, y, width, height);
4029 }
4030}
4031
Nicolas Capensa9b49372015-01-30 00:33:26 -05004032void APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
Nicolas Capens264f1522015-01-09 17:21:17 -05004033{
4034 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
4035 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
4036 n, shaders, binaryformat, binary, length);
4037
4038 // No binary shader formats are supported.
4039 return error(GL_INVALID_ENUM);
4040}
4041
Nicolas Capensa9b49372015-01-30 00:33:26 -05004042void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
Nicolas Capens264f1522015-01-09 17:21:17 -05004043{
4044 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
4045 shader, count, string, length);
4046
4047 if(count < 0)
4048 {
4049 return error(GL_INVALID_VALUE);
4050 }
4051
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004052 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004053
4054 if(context)
4055 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004056 if(context->getListIndex() != 0)
4057 {
4058 UNIMPLEMENTED();
4059 }
4060
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004061 gl::Shader *shaderObject = context->getShader(shader);
Nicolas Capens264f1522015-01-09 17:21:17 -05004062
4063 if(!shaderObject)
4064 {
4065 if(context->getProgram(shader))
4066 {
4067 return error(GL_INVALID_OPERATION);
4068 }
4069 else
4070 {
4071 return error(GL_INVALID_VALUE);
4072 }
4073 }
4074
4075 shaderObject->setSource(count, string, length);
4076 }
4077}
4078
Nicolas Capensa9b49372015-01-30 00:33:26 -05004079void APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004080{
4081 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4082}
4083
Nicolas Capensa9b49372015-01-30 00:33:26 -05004084void APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004085{
4086 TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
4087
4088 switch(face)
4089 {
4090 case GL_FRONT:
4091 case GL_BACK:
4092 case GL_FRONT_AND_BACK:
4093 break;
4094 default:
4095 return error(GL_INVALID_ENUM);
4096 }
4097
4098 switch(func)
4099 {
4100 case GL_NEVER:
4101 case GL_ALWAYS:
4102 case GL_LESS:
4103 case GL_LEQUAL:
4104 case GL_EQUAL:
4105 case GL_GEQUAL:
4106 case GL_GREATER:
4107 case GL_NOTEQUAL:
4108 break;
4109 default:
4110 return error(GL_INVALID_ENUM);
4111 }
4112
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004113 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004114
4115 if(context)
4116 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004117 if(context->getListIndex() != 0)
4118 {
4119 UNIMPLEMENTED();
4120 }
4121
Nicolas Capens264f1522015-01-09 17:21:17 -05004122 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4123 {
4124 context->setStencilParams(func, ref, mask);
4125 }
4126
4127 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4128 {
4129 context->setStencilBackParams(func, ref, mask);
4130 }
4131 }
4132}
4133
Nicolas Capensa9b49372015-01-30 00:33:26 -05004134void APIENTRY glStencilMask(GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004135{
4136 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4137}
4138
Nicolas Capensa9b49372015-01-30 00:33:26 -05004139void APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
Nicolas Capens264f1522015-01-09 17:21:17 -05004140{
4141 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
4142
4143 switch(face)
4144 {
4145 case GL_FRONT:
4146 case GL_BACK:
4147 case GL_FRONT_AND_BACK:
4148 break;
4149 default:
4150 return error(GL_INVALID_ENUM);
4151 }
4152
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004153 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004154
4155 if(context)
4156 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004157 if(context->getListIndex() != 0)
4158 {
4159 UNIMPLEMENTED();
4160 }
4161
Nicolas Capens264f1522015-01-09 17:21:17 -05004162 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4163 {
4164 context->setStencilWritemask(mask);
4165 }
4166
4167 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4168 {
4169 context->setStencilBackWritemask(mask);
4170 }
4171 }
4172}
4173
Nicolas Capensa9b49372015-01-30 00:33:26 -05004174void APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
Nicolas Capens264f1522015-01-09 17:21:17 -05004175{
4176 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4177}
4178
Nicolas Capensa9b49372015-01-30 00:33:26 -05004179void APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
Nicolas Capens264f1522015-01-09 17:21:17 -05004180{
4181 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4182 face, fail, zfail, zpass);
4183
4184 switch(face)
4185 {
4186 case GL_FRONT:
4187 case GL_BACK:
4188 case GL_FRONT_AND_BACK:
4189 break;
4190 default:
4191 return error(GL_INVALID_ENUM);
4192 }
4193
4194 switch(fail)
4195 {
4196 case GL_ZERO:
4197 case GL_KEEP:
4198 case GL_REPLACE:
4199 case GL_INCR:
4200 case GL_DECR:
4201 case GL_INVERT:
4202 case GL_INCR_WRAP:
4203 case GL_DECR_WRAP:
4204 break;
4205 default:
4206 return error(GL_INVALID_ENUM);
4207 }
4208
4209 switch(zfail)
4210 {
4211 case GL_ZERO:
4212 case GL_KEEP:
4213 case GL_REPLACE:
4214 case GL_INCR:
4215 case GL_DECR:
4216 case GL_INVERT:
4217 case GL_INCR_WRAP:
4218 case GL_DECR_WRAP:
4219 break;
4220 default:
4221 return error(GL_INVALID_ENUM);
4222 }
4223
4224 switch(zpass)
4225 {
4226 case GL_ZERO:
4227 case GL_KEEP:
4228 case GL_REPLACE:
4229 case GL_INCR:
4230 case GL_DECR:
4231 case GL_INVERT:
4232 case GL_INCR_WRAP:
4233 case GL_DECR_WRAP:
4234 break;
4235 default:
4236 return error(GL_INVALID_ENUM);
4237 }
4238
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004239 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004240
4241 if(context)
4242 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004243 if(context->getListIndex() != 0)
4244 {
4245 UNIMPLEMENTED();
4246 }
4247
Nicolas Capens264f1522015-01-09 17:21:17 -05004248 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4249 {
4250 context->setStencilOperations(fail, zfail, zpass);
4251 }
4252
4253 if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4254 {
4255 context->setStencilBackOperations(fail, zfail, zpass);
4256 }
4257 }
4258}
4259
Nicolas Capensa9b49372015-01-30 00:33:26 -05004260GLboolean APIENTRY glTestFenceNV(GLuint fence)
Nicolas Capens264f1522015-01-09 17:21:17 -05004261{
4262 TRACE("(GLuint fence = %d)", fence);
4263
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004264 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004265
4266 if(context)
4267 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004268 if(context->getListIndex() != 0)
4269 {
4270 UNIMPLEMENTED();
4271 }
4272
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004273 gl::Fence *fenceObject = context->getFence(fence);
Nicolas Capens264f1522015-01-09 17:21:17 -05004274
4275 if(fenceObject == NULL)
4276 {
4277 return error(GL_INVALID_OPERATION, GL_TRUE);
4278 }
4279
4280 return fenceObject->testFence();
4281 }
4282
4283 return GL_TRUE;
4284}
4285
Nicolas Capensa9b49372015-01-30 00:33:26 -05004286void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
Nicolas Capens264f1522015-01-09 17:21:17 -05004287 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4288{
4289 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
4290 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
4291 target, level, internalformat, width, height, border, format, type, pixels);
4292
4293 if(!validImageSize(level, width, height))
4294 {
4295 return error(GL_INVALID_VALUE);
4296 }
4297
4298 if(internalformat != format)
4299 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004300 //TRACE("UNIMPLEMENTED!!");
4301 //return error(GL_INVALID_OPERATION);
Nicolas Capens264f1522015-01-09 17:21:17 -05004302 }
4303
4304 switch(format)
4305 {
4306 case GL_ALPHA:
4307 case GL_LUMINANCE:
4308 case GL_LUMINANCE_ALPHA:
4309 switch(type)
4310 {
4311 case GL_UNSIGNED_BYTE:
4312 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004313 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004314 break;
4315 default:
4316 return error(GL_INVALID_ENUM);
4317 }
4318 break;
4319 case GL_RGB:
4320 switch(type)
4321 {
4322 case GL_UNSIGNED_BYTE:
4323 case GL_UNSIGNED_SHORT_5_6_5:
4324 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004325 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004326 break;
4327 default:
4328 return error(GL_INVALID_ENUM);
4329 }
4330 break;
4331 case GL_RGBA:
4332 switch(type)
4333 {
4334 case GL_UNSIGNED_BYTE:
4335 case GL_UNSIGNED_SHORT_4_4_4_4:
4336 case GL_UNSIGNED_SHORT_5_5_5_1:
4337 case GL_FLOAT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004338 case GL_HALF_FLOAT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004339 break;
4340 default:
4341 return error(GL_INVALID_ENUM);
4342 }
4343 break;
4344 case GL_BGRA_EXT:
4345 switch(type)
4346 {
4347 case GL_UNSIGNED_BYTE:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004348 case GL_UNSIGNED_SHORT_5_6_5:
4349 case GL_UNSIGNED_INT_8_8_8_8_REV:
Nicolas Capens264f1522015-01-09 17:21:17 -05004350 break;
4351 default:
4352 return error(GL_INVALID_ENUM);
4353 }
4354 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004355 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
Nicolas Capens264f1522015-01-09 17:21:17 -05004356 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004357 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
4358 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
4359 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004360 case GL_DEPTH_COMPONENT:
4361 switch(type)
4362 {
4363 case GL_UNSIGNED_SHORT:
4364 case GL_UNSIGNED_INT:
4365 break;
4366 default:
4367 return error(GL_INVALID_ENUM);
4368 }
4369 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004370 case GL_DEPTH_STENCIL_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004371 switch(type)
4372 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004373 case GL_UNSIGNED_INT_24_8_EXT:
Nicolas Capens264f1522015-01-09 17:21:17 -05004374 break;
4375 default:
4376 return error(GL_INVALID_ENUM);
4377 }
4378 break;
4379 default:
4380 return error(GL_INVALID_VALUE);
4381 }
4382
4383 if(border != 0)
4384 {
4385 return error(GL_INVALID_VALUE);
4386 }
4387
Nicolas Capensa9b49372015-01-30 00:33:26 -05004388 switch(target)
4389 {
4390 case GL_TEXTURE_2D:
4391 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4392 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4393 {
4394 return error(GL_INVALID_VALUE);
4395 }
4396 break;
4397 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4398 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4399 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4400 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4401 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4402 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4403 if(width != height)
4404 {
4405 return error(GL_INVALID_VALUE);
4406 }
4407
4408 if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
4409 height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
4410 {
4411 return error(GL_INVALID_VALUE);
4412 }
4413 break;
4414 case GL_PROXY_TEXTURE_2D:
4415 pixels = 0;
4416
4417 if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4418 height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4419 {
4420 //UNIMPLEMENTED();
4421 width = 0;
4422 height = 0;
4423 internalformat = GL_NONE;
4424 format = GL_NONE;
4425 type = GL_NONE;
4426
4427 //return;// error(GL_INVALID_VALUE);
4428 }
4429 break;
4430 default:
4431 return error(GL_INVALID_ENUM);
4432 }
4433
4434 if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4435 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
4436 format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
4437 format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
4438 {
4439 if(S3TC_SUPPORT)
4440 {
4441 return error(GL_INVALID_OPERATION);
4442 }
4443 else
4444 {
4445 return error(GL_INVALID_ENUM);
4446 }
4447 }
4448
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004449 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004450
4451 if(context)
4452 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004453 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05004454 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004455 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05004456 }
4457
Nicolas Capensa9b49372015-01-30 00:33:26 -05004458 if(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D)
Nicolas Capens264f1522015-01-09 17:21:17 -05004459 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004460 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004461
4462 if(!texture)
4463 {
4464 return error(GL_INVALID_OPERATION);
4465 }
4466
4467 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
4468 }
4469 else
4470 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004471 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05004472
4473 if(!texture)
4474 {
4475 return error(GL_INVALID_OPERATION);
4476 }
4477
4478 texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
4479 }
4480 }
4481}
4482
Nicolas Capensa9b49372015-01-30 00:33:26 -05004483void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
Nicolas Capens264f1522015-01-09 17:21:17 -05004484{
4485 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
4486
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004487 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004488
4489 if(context)
4490 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004491 if(context->getListIndex() != 0)
4492 {
4493 UNIMPLEMENTED();
4494 }
4495
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004496 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05004497
4498 switch(target)
4499 {
4500 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004501 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004502 break;
4503 case GL_TEXTURE_CUBE_MAP:
4504 texture = context->getTextureCubeMap();
4505 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004506 default:
4507 return error(GL_INVALID_ENUM);
4508 }
4509
4510 switch(pname)
4511 {
4512 case GL_TEXTURE_WRAP_S:
4513 if(!texture->setWrapS((GLenum)param))
4514 {
4515 return error(GL_INVALID_ENUM);
4516 }
4517 break;
4518 case GL_TEXTURE_WRAP_T:
4519 if(!texture->setWrapT((GLenum)param))
4520 {
4521 return error(GL_INVALID_ENUM);
4522 }
4523 break;
4524 case GL_TEXTURE_MIN_FILTER:
4525 if(!texture->setMinFilter((GLenum)param))
4526 {
4527 return error(GL_INVALID_ENUM);
4528 }
4529 break;
4530 case GL_TEXTURE_MAG_FILTER:
4531 if(!texture->setMagFilter((GLenum)param))
4532 {
4533 return error(GL_INVALID_ENUM);
4534 }
4535 break;
4536 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4537 if(!texture->setMaxAnisotropy(param))
4538 {
4539 return error(GL_INVALID_VALUE);
4540 }
4541 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004542 case GL_TEXTURE_MIN_LOD:
4543 //TRACE("() UNIMPLEMENTED!!"); // FIXME
4544 //UNIMPLEMENTED();
4545 break;
4546 case GL_TEXTURE_MAX_LOD:
4547 //TRACE("() UNIMPLEMENTED!!"); // FIXME
4548 //UNIMPLEMENTED();
4549 break;
4550 case GL_TEXTURE_LOD_BIAS:
4551 if(param != 0.0f)
4552 {
4553 UNIMPLEMENTED();
4554 }
4555 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004556 default:
4557 return error(GL_INVALID_ENUM);
4558 }
4559 }
4560}
4561
Nicolas Capensa9b49372015-01-30 00:33:26 -05004562void APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05004563{
4564 glTexParameterf(target, pname, *params);
4565}
4566
Nicolas Capensa9b49372015-01-30 00:33:26 -05004567void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
Nicolas Capens264f1522015-01-09 17:21:17 -05004568{
4569 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
4570
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004571 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004572
4573 if(context)
4574 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004575 if(context->getListIndex() != 0)
4576 {
4577 UNIMPLEMENTED();
4578 }
4579
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004580 gl::Texture *texture;
Nicolas Capens264f1522015-01-09 17:21:17 -05004581
4582 switch(target)
4583 {
4584 case GL_TEXTURE_2D:
Nicolas Capensa9b49372015-01-30 00:33:26 -05004585 texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004586 break;
4587 case GL_TEXTURE_CUBE_MAP:
4588 texture = context->getTextureCubeMap();
4589 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004590 default:
4591 return error(GL_INVALID_ENUM);
4592 }
4593
4594 switch(pname)
4595 {
4596 case GL_TEXTURE_WRAP_S:
4597 if(!texture->setWrapS((GLenum)param))
4598 {
4599 return error(GL_INVALID_ENUM);
4600 }
4601 break;
4602 case GL_TEXTURE_WRAP_T:
4603 if(!texture->setWrapT((GLenum)param))
4604 {
4605 return error(GL_INVALID_ENUM);
4606 }
4607 break;
4608 case GL_TEXTURE_MIN_FILTER:
4609 if(!texture->setMinFilter((GLenum)param))
4610 {
4611 return error(GL_INVALID_ENUM);
4612 }
4613 break;
4614 case GL_TEXTURE_MAG_FILTER:
4615 if(!texture->setMagFilter((GLenum)param))
4616 {
4617 return error(GL_INVALID_ENUM);
4618 }
4619 break;
4620 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4621 if(!texture->setMaxAnisotropy((GLfloat)param))
4622 {
4623 return error(GL_INVALID_VALUE);
4624 }
4625 break;
Nicolas Capensa9b49372015-01-30 00:33:26 -05004626 case GL_TEXTURE_MAX_LEVEL:
4627 if(!texture->setMaxLevel(param))
4628 {
4629 return error(GL_INVALID_ENUM);
4630 }
4631 break;
Nicolas Capens264f1522015-01-09 17:21:17 -05004632 default:
4633 return error(GL_INVALID_ENUM);
4634 }
4635 }
4636}
4637
Nicolas Capensa9b49372015-01-30 00:33:26 -05004638void APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
Nicolas Capens264f1522015-01-09 17:21:17 -05004639{
4640 glTexParameteri(target, pname, *params);
4641}
4642
Nicolas Capensa9b49372015-01-30 00:33:26 -05004643void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4644 GLenum format, GLenum type, const GLvoid* pixels)
Nicolas Capens264f1522015-01-09 17:21:17 -05004645{
4646 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4647 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
4648 "const GLvoid* pixels = 0x%0.8p)",
4649 target, level, xoffset, yoffset, width, height, format, type, pixels);
4650
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004651 if(!gl::IsTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05004652 {
4653 return error(GL_INVALID_ENUM);
4654 }
4655
4656 if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
4657 {
4658 return error(GL_INVALID_VALUE);
4659 }
4660
4661 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4662 {
4663 return error(GL_INVALID_VALUE);
4664 }
4665
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004666 if(!gl::CheckTextureFormatType(format, type))
Nicolas Capens264f1522015-01-09 17:21:17 -05004667 {
4668 return error(GL_INVALID_ENUM);
4669 }
4670
4671 if(width == 0 || height == 0 || pixels == NULL)
4672 {
4673 return;
4674 }
4675
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004676 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004677
4678 if(context)
4679 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004680 if(context->getListIndex() != 0)
4681 {
4682 UNIMPLEMENTED();
4683 }
4684
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004685 if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
Nicolas Capens264f1522015-01-09 17:21:17 -05004686 {
4687 return error(GL_INVALID_VALUE);
4688 }
4689
4690 if(target == GL_TEXTURE_2D)
4691 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004692 gl::Texture2D *texture = context->getTexture2D(target);
Nicolas Capens264f1522015-01-09 17:21:17 -05004693
4694 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
4695 {
4696 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4697 }
4698 }
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004699 else if(gl::IsCubemapTextureTarget(target))
Nicolas Capens264f1522015-01-09 17:21:17 -05004700 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004701 gl::TextureCubeMap *texture = context->getTextureCubeMap();
Nicolas Capens264f1522015-01-09 17:21:17 -05004702
4703 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
4704 {
4705 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4706 }
4707 }
4708 else
4709 {
4710 UNREACHABLE();
4711 }
4712 }
4713}
4714
Nicolas Capensa9b49372015-01-30 00:33:26 -05004715void APIENTRY glUniform1f(GLint location, GLfloat x)
Nicolas Capens264f1522015-01-09 17:21:17 -05004716{
4717 glUniform1fv(location, 1, &x);
4718}
4719
Nicolas Capensa9b49372015-01-30 00:33:26 -05004720void APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004721{
4722 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
4723
4724 if(count < 0)
4725 {
4726 return error(GL_INVALID_VALUE);
4727 }
4728
4729 if(location == -1)
4730 {
4731 return;
4732 }
4733
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004734 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004735
4736 if(context)
4737 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004738 if(context->getListIndex() != 0)
4739 {
4740 UNIMPLEMENTED();
4741 }
4742
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004743 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004744
4745 if(!program)
4746 {
4747 return error(GL_INVALID_OPERATION);
4748 }
4749
4750 if(!program->setUniform1fv(location, count, v))
4751 {
4752 return error(GL_INVALID_OPERATION);
4753 }
4754 }
4755}
4756
Nicolas Capensa9b49372015-01-30 00:33:26 -05004757void APIENTRY glUniform1i(GLint location, GLint x)
Nicolas Capens264f1522015-01-09 17:21:17 -05004758{
4759 glUniform1iv(location, 1, &x);
4760}
4761
Nicolas Capensa9b49372015-01-30 00:33:26 -05004762void APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004763{
4764 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
4765
4766 if(count < 0)
4767 {
4768 return error(GL_INVALID_VALUE);
4769 }
4770
4771 if(location == -1)
4772 {
4773 return;
4774 }
4775
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004776 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004777
4778 if(context)
4779 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004780 if(context->getListIndex() != 0)
4781 {
4782 UNIMPLEMENTED();
4783 }
4784
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004785 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004786
4787 if(!program)
4788 {
4789 return error(GL_INVALID_OPERATION);
4790 }
4791
4792 if(!program->setUniform1iv(location, count, v))
4793 {
4794 return error(GL_INVALID_OPERATION);
4795 }
4796 }
4797}
4798
Nicolas Capensa9b49372015-01-30 00:33:26 -05004799void APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
Nicolas Capens264f1522015-01-09 17:21:17 -05004800{
4801 GLfloat xy[2] = {x, y};
4802
4803 glUniform2fv(location, 1, (GLfloat*)&xy);
4804}
4805
Nicolas Capensa9b49372015-01-30 00:33:26 -05004806void APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004807{
4808 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
4809
4810 if(count < 0)
4811 {
4812 return error(GL_INVALID_VALUE);
4813 }
4814
4815 if(location == -1)
4816 {
4817 return;
4818 }
4819
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004820 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004821
4822 if(context)
4823 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004824 if(context->getListIndex() != 0)
4825 {
4826 UNIMPLEMENTED();
4827 }
4828
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004829 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004830
4831 if(!program)
4832 {
4833 return error(GL_INVALID_OPERATION);
4834 }
4835
4836 if(!program->setUniform2fv(location, count, v))
4837 {
4838 return error(GL_INVALID_OPERATION);
4839 }
4840 }
4841}
4842
Nicolas Capensa9b49372015-01-30 00:33:26 -05004843void APIENTRY glUniform2i(GLint location, GLint x, GLint y)
Nicolas Capens264f1522015-01-09 17:21:17 -05004844{
4845 GLint xy[4] = {x, y};
4846
4847 glUniform2iv(location, 1, (GLint*)&xy);
4848}
4849
Nicolas Capensa9b49372015-01-30 00:33:26 -05004850void APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004851{
4852 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
4853
4854 if(count < 0)
4855 {
4856 return error(GL_INVALID_VALUE);
4857 }
4858
4859 if(location == -1)
4860 {
4861 return;
4862 }
4863
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004864 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004865
4866 if(context)
4867 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004868 if(context->getListIndex() != 0)
4869 {
4870 UNIMPLEMENTED();
4871 }
4872
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004873 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004874
4875 if(!program)
4876 {
4877 return error(GL_INVALID_OPERATION);
4878 }
4879
4880 if(!program->setUniform2iv(location, count, v))
4881 {
4882 return error(GL_INVALID_OPERATION);
4883 }
4884 }
4885}
4886
Nicolas Capensa9b49372015-01-30 00:33:26 -05004887void APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
Nicolas Capens264f1522015-01-09 17:21:17 -05004888{
4889 GLfloat xyz[3] = {x, y, z};
4890
4891 glUniform3fv(location, 1, (GLfloat*)&xyz);
4892}
4893
Nicolas Capensa9b49372015-01-30 00:33:26 -05004894void APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004895{
4896 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
4897
4898 if(count < 0)
4899 {
4900 return error(GL_INVALID_VALUE);
4901 }
4902
4903 if(location == -1)
4904 {
4905 return;
4906 }
4907
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004908 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004909
4910 if(context)
4911 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004912 if(context->getListIndex() != 0)
4913 {
4914 UNIMPLEMENTED();
4915 }
4916
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004917 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004918
4919 if(!program)
4920 {
4921 return error(GL_INVALID_OPERATION);
4922 }
4923
4924 if(!program->setUniform3fv(location, count, v))
4925 {
4926 return error(GL_INVALID_OPERATION);
4927 }
4928 }
4929}
4930
Nicolas Capensa9b49372015-01-30 00:33:26 -05004931void APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
Nicolas Capens264f1522015-01-09 17:21:17 -05004932{
4933 GLint xyz[3] = {x, y, z};
4934
4935 glUniform3iv(location, 1, (GLint*)&xyz);
4936}
4937
Nicolas Capensa9b49372015-01-30 00:33:26 -05004938void APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004939{
4940 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
4941
4942 if(count < 0)
4943 {
4944 return error(GL_INVALID_VALUE);
4945 }
4946
4947 if(location == -1)
4948 {
4949 return;
4950 }
4951
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004952 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004953
4954 if(context)
4955 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05004956 if(context->getListIndex() != 0)
4957 {
4958 UNIMPLEMENTED();
4959 }
4960
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004961 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05004962
4963 if(!program)
4964 {
4965 return error(GL_INVALID_OPERATION);
4966 }
4967
4968 if(!program->setUniform3iv(location, count, v))
4969 {
4970 return error(GL_INVALID_OPERATION);
4971 }
4972 }
4973}
4974
Nicolas Capensa9b49372015-01-30 00:33:26 -05004975void APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Nicolas Capens264f1522015-01-09 17:21:17 -05004976{
4977 GLfloat xyzw[4] = {x, y, z, w};
4978
4979 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4980}
4981
Nicolas Capensa9b49372015-01-30 00:33:26 -05004982void APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05004983{
4984 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
4985
4986 if(count < 0)
4987 {
4988 return error(GL_INVALID_VALUE);
4989 }
4990
4991 if(location == -1)
4992 {
4993 return;
4994 }
4995
Nicolas Capensf4486fd2015-01-22 11:10:37 -05004996 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05004997
4998 if(context)
4999 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005000 if(context->getListIndex() != 0)
5001 {
5002 UNIMPLEMENTED();
5003 }
5004
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005005 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005006
5007 if(!program)
5008 {
5009 return error(GL_INVALID_OPERATION);
5010 }
5011
5012 if(!program->setUniform4fv(location, count, v))
5013 {
5014 return error(GL_INVALID_OPERATION);
5015 }
5016 }
5017}
5018
Nicolas Capensa9b49372015-01-30 00:33:26 -05005019void APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
Nicolas Capens264f1522015-01-09 17:21:17 -05005020{
5021 GLint xyzw[4] = {x, y, z, w};
5022
5023 glUniform4iv(location, 1, (GLint*)&xyzw);
5024}
5025
Nicolas Capensa9b49372015-01-30 00:33:26 -05005026void APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
Nicolas Capens264f1522015-01-09 17:21:17 -05005027{
5028 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
5029
5030 if(count < 0)
5031 {
5032 return error(GL_INVALID_VALUE);
5033 }
5034
5035 if(location == -1)
5036 {
5037 return;
5038 }
5039
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005040 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005041
5042 if(context)
5043 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005044 if(context->getListIndex() != 0)
5045 {
5046 UNIMPLEMENTED();
5047 }
5048
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005049 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005050
5051 if(!program)
5052 {
5053 return error(GL_INVALID_OPERATION);
5054 }
5055
5056 if(!program->setUniform4iv(location, count, v))
5057 {
5058 return error(GL_INVALID_OPERATION);
5059 }
5060 }
5061}
5062
Nicolas Capensa9b49372015-01-30 00:33:26 -05005063void APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005064{
5065 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5066 location, count, transpose, value);
5067
5068 if(count < 0 || transpose != GL_FALSE)
5069 {
5070 return error(GL_INVALID_VALUE);
5071 }
5072
5073 if(location == -1)
5074 {
5075 return;
5076 }
5077
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005078 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005079
5080 if(context)
5081 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005082 if(context->getListIndex() != 0)
5083 {
5084 UNIMPLEMENTED();
5085 }
5086
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005087 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005088
5089 if(!program)
5090 {
5091 return error(GL_INVALID_OPERATION);
5092 }
5093
5094 if(!program->setUniformMatrix2fv(location, count, value))
5095 {
5096 return error(GL_INVALID_OPERATION);
5097 }
5098 }
5099}
5100
Nicolas Capensa9b49372015-01-30 00:33:26 -05005101void APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005102{
5103 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5104 location, count, transpose, value);
5105
5106 if(count < 0 || transpose != GL_FALSE)
5107 {
5108 return error(GL_INVALID_VALUE);
5109 }
5110
5111 if(location == -1)
5112 {
5113 return;
5114 }
5115
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005116 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005117
5118 if(context)
5119 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005120 if(context->getListIndex() != 0)
5121 {
5122 UNIMPLEMENTED();
5123 }
5124
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005125 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005126
5127 if(!program)
5128 {
5129 return error(GL_INVALID_OPERATION);
5130 }
5131
5132 if(!program->setUniformMatrix3fv(location, count, value))
5133 {
5134 return error(GL_INVALID_OPERATION);
5135 }
5136 }
5137}
5138
Nicolas Capensa9b49372015-01-30 00:33:26 -05005139void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
Nicolas Capens264f1522015-01-09 17:21:17 -05005140{
5141 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5142 location, count, transpose, value);
5143
5144 if(count < 0 || transpose != GL_FALSE)
5145 {
5146 return error(GL_INVALID_VALUE);
5147 }
5148
5149 if(location == -1)
5150 {
5151 return;
5152 }
5153
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005154 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005155
5156 if(context)
5157 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005158 if(context->getListIndex() != 0)
5159 {
5160 UNIMPLEMENTED();
5161 }
5162
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005163 gl::Program *program = context->getCurrentProgram();
Nicolas Capens264f1522015-01-09 17:21:17 -05005164
5165 if(!program)
5166 {
5167 return error(GL_INVALID_OPERATION);
5168 }
5169
5170 if(!program->setUniformMatrix4fv(location, count, value))
5171 {
5172 return error(GL_INVALID_OPERATION);
5173 }
5174 }
5175}
5176
Nicolas Capensa9b49372015-01-30 00:33:26 -05005177void APIENTRY glUseProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05005178{
5179 TRACE("(GLuint program = %d)", program);
5180
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005181 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005182
5183 if(context)
5184 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005185 if(context->getListIndex() != 0)
5186 {
5187 UNIMPLEMENTED();
5188 }
5189
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005190 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05005191
5192 if(!programObject && program != 0)
5193 {
5194 if(context->getShader(program))
5195 {
5196 return error(GL_INVALID_OPERATION);
5197 }
5198 else
5199 {
5200 return error(GL_INVALID_VALUE);
5201 }
5202 }
5203
5204 if(program != 0 && !programObject->isLinked())
5205 {
5206 return error(GL_INVALID_OPERATION);
5207 }
5208
5209 context->useProgram(program);
5210 }
5211}
5212
Nicolas Capensa9b49372015-01-30 00:33:26 -05005213void APIENTRY glValidateProgram(GLuint program)
Nicolas Capens264f1522015-01-09 17:21:17 -05005214{
5215 TRACE("(GLuint program = %d)", program);
5216
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005217 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005218
5219 if(context)
5220 {
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005221 gl::Program *programObject = context->getProgram(program);
Nicolas Capens264f1522015-01-09 17:21:17 -05005222
5223 if(!programObject)
5224 {
5225 if(context->getShader(program))
5226 {
5227 return error(GL_INVALID_OPERATION);
5228 }
5229 else
5230 {
5231 return error(GL_INVALID_VALUE);
5232 }
5233 }
5234
5235 programObject->validate();
5236 }
5237}
5238
Nicolas Capensa9b49372015-01-30 00:33:26 -05005239void APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
Nicolas Capens264f1522015-01-09 17:21:17 -05005240{
5241 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
5242
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005243 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005244 {
5245 return error(GL_INVALID_VALUE);
5246 }
5247
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005248 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005249
5250 if(context)
5251 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005252 if(context->getListIndex() != 0)
5253 {
5254 UNIMPLEMENTED();
5255 }
5256
5257 //GLfloat vals[4] = { x, 0, 0, 1 };
5258 context->setVertexAttrib(index, x, 0, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005259 }
5260}
5261
Nicolas Capensa9b49372015-01-30 00:33:26 -05005262void APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005263{
5264 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
5265
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005266 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005267 {
5268 return error(GL_INVALID_VALUE);
5269 }
5270
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005271 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005272
5273 if(context)
5274 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005275 if(context->getListIndex() != 0)
5276 {
5277 UNIMPLEMENTED();
5278 }
5279
5280 //GLfloat vals[4] = { values[0], 0, 0, 1 };
5281 context->setVertexAttrib(index, values[0], 0, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005282 }
5283}
5284
Nicolas Capensa9b49372015-01-30 00:33:26 -05005285void APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
Nicolas Capens264f1522015-01-09 17:21:17 -05005286{
5287 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
5288
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005289 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005290 {
5291 return error(GL_INVALID_VALUE);
5292 }
5293
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005294 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005295
5296 if(context)
5297 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005298 if(context->getListIndex() != 0)
5299 {
5300 UNIMPLEMENTED();
5301 }
5302
5303 //GLfloat vals[4] = { x, y, 0, 1 };
5304 context->setVertexAttrib(index, x, y, 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005305 }
5306}
5307
Nicolas Capensa9b49372015-01-30 00:33:26 -05005308void APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005309{
5310 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
5311
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005312 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005313 {
5314 return error(GL_INVALID_VALUE);
5315 }
5316
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005317 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005318
5319 if(context)
5320 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005321 if(context->getListIndex() != 0)
5322 {
5323 UNIMPLEMENTED();
5324 }
5325
5326 //GLfloat vals[4] = { };
5327 context->setVertexAttrib(index, values[0], values[1], 0, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005328 }
5329}
5330
Nicolas Capensa9b49372015-01-30 00:33:26 -05005331void APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
Nicolas Capens264f1522015-01-09 17:21:17 -05005332{
5333 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
5334
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005335 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005336 {
5337 return error(GL_INVALID_VALUE);
5338 }
5339
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005340 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005341
5342 if(context)
5343 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005344 if(context->getListIndex() != 0)
5345 {
5346 UNIMPLEMENTED();
5347 }
5348
5349 //GLfloat vals[4] = { x, y, z, 1 };
5350 context->setVertexAttrib(index, x, y, z, 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005351 }
5352}
5353
Nicolas Capensa9b49372015-01-30 00:33:26 -05005354void APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005355{
5356 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
5357
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005358 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005359 {
5360 return error(GL_INVALID_VALUE);
5361 }
5362
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005363 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005364
5365 if(context)
5366 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005367 if(context->getListIndex() != 0)
5368 {
5369 UNIMPLEMENTED();
5370 }
5371
5372 //GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5373 context->setVertexAttrib(index, values[0], values[1], values[2], 1);
Nicolas Capens264f1522015-01-09 17:21:17 -05005374 }
5375}
5376
Nicolas Capensa9b49372015-01-30 00:33:26 -05005377void APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Nicolas Capens264f1522015-01-09 17:21:17 -05005378{
5379 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
5380
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005381 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005382 {
5383 return error(GL_INVALID_VALUE);
5384 }
5385
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005386 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005387
5388 if(context)
5389 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005390 if(context->getListIndex() != 0)
5391 {
5392 UNIMPLEMENTED();
5393 }
5394
5395 //GLfloat vals[4] = { x, y, z, w };
5396 context->setVertexAttrib(index, x, y, z, w);
Nicolas Capens264f1522015-01-09 17:21:17 -05005397 }
5398}
5399
Nicolas Capensa9b49372015-01-30 00:33:26 -05005400void APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
Nicolas Capens264f1522015-01-09 17:21:17 -05005401{
5402 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
5403
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005404 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005405 {
5406 return error(GL_INVALID_VALUE);
5407 }
5408
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005409 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005410
5411 if(context)
5412 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005413 if(context->getListIndex() != 0)
5414 {
5415 UNIMPLEMENTED();
5416 }
5417
5418 context->setVertexAttrib(index, values[0], values[1], values[2], values[3]);
Nicolas Capens264f1522015-01-09 17:21:17 -05005419 }
5420}
5421
Nicolas Capensa9b49372015-01-30 00:33:26 -05005422void APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
Nicolas Capens264f1522015-01-09 17:21:17 -05005423{
5424 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
5425 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
5426 index, size, type, normalized, stride, ptr);
5427
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005428 if(index >= gl::MAX_VERTEX_ATTRIBS)
Nicolas Capens264f1522015-01-09 17:21:17 -05005429 {
5430 return error(GL_INVALID_VALUE);
5431 }
5432
5433 if(size < 1 || size > 4)
5434 {
5435 return error(GL_INVALID_VALUE);
5436 }
5437
5438 switch(type)
5439 {
5440 case GL_BYTE:
5441 case GL_UNSIGNED_BYTE:
5442 case GL_SHORT:
5443 case GL_UNSIGNED_SHORT:
5444 case GL_FIXED:
5445 case GL_FLOAT:
5446 break;
5447 default:
5448 return error(GL_INVALID_ENUM);
5449 }
5450
5451 if(stride < 0)
5452 {
5453 return error(GL_INVALID_VALUE);
5454 }
5455
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005456 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005457
5458 if(context)
5459 {
5460 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
5461 }
5462}
5463
Nicolas Capensa9b49372015-01-30 00:33:26 -05005464void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
Nicolas Capens264f1522015-01-09 17:21:17 -05005465{
5466 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
5467
5468 if(width < 0 || height < 0)
5469 {
5470 return error(GL_INVALID_VALUE);
5471 }
5472
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005473 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005474
5475 if(context)
5476 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005477 if(context->getListIndex() != 0)
5478 {
5479 UNIMPLEMENTED();
5480 }
5481
Nicolas Capens264f1522015-01-09 17:21:17 -05005482 context->setViewportParams(x, y, width, height);
5483 }
5484}
5485
Nicolas Capensa9b49372015-01-30 00:33:26 -05005486void 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 -05005487 GLbitfield mask, GLenum filter)
5488{
5489 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5490 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5491 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5492 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5493
5494 switch(filter)
5495 {
5496 case GL_NEAREST:
5497 break;
5498 default:
5499 return error(GL_INVALID_ENUM);
5500 }
5501
5502 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5503 {
5504 return error(GL_INVALID_VALUE);
5505 }
5506
5507 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5508 {
5509 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5510 return error(GL_INVALID_OPERATION);
5511 }
5512
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005513 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005514
5515 if(context)
5516 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005517 if(context->getListIndex() != 0)
5518 {
5519 UNIMPLEMENTED();
5520 }
5521
Nicolas Capens7cc75e12015-01-29 14:44:24 -05005522 if(context->getReadFramebufferName() == context->getDrawFramebufferName())
Nicolas Capens264f1522015-01-09 17:21:17 -05005523 {
5524 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5525 return error(GL_INVALID_OPERATION);
5526 }
5527
5528 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5529 }
5530}
5531
Nicolas Capensa9b49372015-01-30 00:33:26 -05005532void APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
Nicolas Capens264f1522015-01-09 17:21:17 -05005533 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
5534{
5535 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5536 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
5537 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
5538 target, level, internalformat, width, height, depth, border, format, type, pixels);
5539
5540 UNIMPLEMENTED(); // FIXME
5541}
5542
Nicolas Capensa9b49372015-01-30 00:33:26 -05005543void WINAPI GlmfBeginGlsBlock()
Nicolas Capens264f1522015-01-09 17:21:17 -05005544{
Nicolas Capensa9b49372015-01-30 00:33:26 -05005545 UNIMPLEMENTED();
5546}
5547
5548void WINAPI GlmfCloseMetaFile()
5549{
5550 UNIMPLEMENTED();
5551}
5552
5553void WINAPI GlmfEndGlsBlock()
5554{
5555 UNIMPLEMENTED();
5556}
5557
5558void WINAPI GlmfEndPlayback()
5559{
5560 UNIMPLEMENTED();
5561}
5562
5563void WINAPI GlmfInitPlayback()
5564{
5565 UNIMPLEMENTED();
5566}
5567
5568void WINAPI GlmfPlayGlsRecord()
5569{
5570 UNIMPLEMENTED();
5571}
5572
5573void APIENTRY glAccum(GLenum op, GLfloat value)
5574{
5575 UNIMPLEMENTED();
5576}
5577
5578void APIENTRY glAlphaFunc(GLenum func, GLclampf ref)
5579{
5580 TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);
5581
5582 gl::Context *context = gl::getContext();
5583
5584 if(context)
Nicolas Capens264f1522015-01-09 17:21:17 -05005585 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005586 if(context->getListIndex() != 0)
5587 {
5588 UNIMPLEMENTED();
5589 }
5590
5591 context->alphaFunc(func, ref);
Nicolas Capens264f1522015-01-09 17:21:17 -05005592 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05005593}
Nicolas Capens264f1522015-01-09 17:21:17 -05005594
Nicolas Capensa9b49372015-01-30 00:33:26 -05005595GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
5596{
5597 UNIMPLEMENTED();
5598 return GL_FALSE;
5599}
Nicolas Capens264f1522015-01-09 17:21:17 -05005600
Nicolas Capensa9b49372015-01-30 00:33:26 -05005601void APIENTRY glArrayElement(GLint i)
5602{
5603 UNIMPLEMENTED();
5604}
5605
5606void APIENTRY glBegin(GLenum mode)
5607{
5608 TRACE("(GLenum mode = 0x%X)", mode);
5609
5610 switch(mode)
Nicolas Capens264f1522015-01-09 17:21:17 -05005611 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005612 case GL_POINTS:
5613 case GL_LINES:
5614 case GL_LINE_STRIP:
5615 case GL_LINE_LOOP:
5616 case GL_TRIANGLES:
5617 case GL_TRIANGLE_STRIP:
5618 case GL_TRIANGLE_FAN:
5619 case GL_QUADS:
5620 case GL_QUAD_STRIP:
5621 case GL_POLYGON:
Nicolas Capens264f1522015-01-09 17:21:17 -05005622 break;
5623 default:
5624 return error(GL_INVALID_ENUM);
5625 }
5626
Nicolas Capensf4486fd2015-01-22 11:10:37 -05005627 gl::Context *context = gl::getContext();
Nicolas Capens264f1522015-01-09 17:21:17 -05005628
5629 if(context)
5630 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005631 if(context->getListIndex() != 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05005632 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05005633 UNIMPLEMENTED();
Nicolas Capens264f1522015-01-09 17:21:17 -05005634 }
5635
Nicolas Capensa9b49372015-01-30 00:33:26 -05005636 context->begin(mode);
Nicolas Capens264f1522015-01-09 17:21:17 -05005637 }
5638}
5639
Nicolas Capensa9b49372015-01-30 00:33:26 -05005640void APIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
Nicolas Capens264f1522015-01-09 17:21:17 -05005641{
Nicolas Capens264f1522015-01-09 17:21:17 -05005642 UNIMPLEMENTED();
5643}
5644
Nicolas Capensa9b49372015-01-30 00:33:26 -05005645void APIENTRY glCallList(GLuint list)
Nicolas Capens264f1522015-01-09 17:21:17 -05005646{
Nicolas Capensa9b49372015-01-30 00:33:26 -05005647 TRACE("(GLuint list = %d)", list);
5648
5649 if(list == 0)
5650 {
5651 return error(GL_INVALID_VALUE);
5652 }
5653
5654 gl::Context *context = gl::getContext();
5655
5656 if(context)
5657 {
5658 if(context->getListIndex() != 0)
5659 {
5660 UNIMPLEMENTED();
5661 }
5662
5663 context->callList(list);
5664 }
5665}
5666
5667void APIENTRY glCallLists(GLsizei n, GLenum type, const GLvoid *lists)
5668{
5669 TRACE("(GLsizei n = %d, GLenum type = 0x%X, const GLvoid *lists)", n, type);
5670
5671 gl::Context *context = gl::getContext();
5672
5673 if(context)
5674 {
5675 if(context->getListIndex() != 0)
5676 {
5677 UNIMPLEMENTED();
5678 }
5679
5680 for(int i = 0; i < n; i++)
5681 {
5682 switch(type)
5683 {
5684 case GL_UNSIGNED_INT: context->callList(((unsigned int*)lists)[i]); break;
5685 default:
5686 UNIMPLEMENTED();
5687 UNREACHABLE();
5688 }
5689 }
5690 }
5691}
5692
5693void APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
5694{
5695 UNIMPLEMENTED();
5696}
5697
5698void APIENTRY glClearDepth(GLclampd depth)
5699{
5700 TRACE("(GLclampd depth = %d)", depth);
5701
5702 glClearDepthf((float)depth); // FIXME
5703}
5704
5705void APIENTRY glClearIndex(GLfloat c)
5706{
5707 UNIMPLEMENTED();
5708}
5709
5710void APIENTRY glClipPlane(GLenum plane, const GLdouble *equation)
5711{
5712 UNIMPLEMENTED();
5713}
5714
5715void APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue)
5716{
5717 UNIMPLEMENTED();
5718}
5719
5720void APIENTRY glColor3bv(const GLbyte *v)
5721{
5722 UNIMPLEMENTED();
5723}
5724
5725void APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue)
5726{
5727 UNIMPLEMENTED();
5728}
5729
5730void APIENTRY glColor3dv(const GLdouble *v)
5731{
5732 UNIMPLEMENTED();
5733}
5734
5735void APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue)
5736{
5737 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f)", red, green, blue);
5738
5739 gl::Context *context = gl::getContext();
5740
5741 if(context)
5742 {
5743 if(context->getListIndex() != 0)
5744 {
5745 UNIMPLEMENTED();
5746 }
5747
5748 //context->color(red, green, blue, 1.0f);
5749 //GLfloat vals[4] = {};
5750 context->setVertexAttrib(sw::Color0, red, green, blue, 1);
5751 }
5752}
5753
5754void APIENTRY glColor3fv(const GLfloat *v)
5755{
5756 UNIMPLEMENTED();
5757}
5758
5759void APIENTRY glColor3i(GLint red, GLint green, GLint blue)
5760{
5761 UNIMPLEMENTED();
5762}
5763
5764void APIENTRY glColor3iv(const GLint *v)
5765{
5766 UNIMPLEMENTED();
5767}
5768
5769void APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue)
5770{
5771 UNIMPLEMENTED();
5772}
5773
5774void APIENTRY glColor3sv(const GLshort *v)
5775{
5776 UNIMPLEMENTED();
5777}
5778
5779void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue)
5780{
5781 UNIMPLEMENTED();
5782}
5783
5784void APIENTRY glColor3ubv(const GLubyte *v)
5785{
5786 UNIMPLEMENTED();
5787}
5788
5789void APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue)
5790{
5791 UNIMPLEMENTED();
5792}
5793
5794void APIENTRY glColor3uiv(const GLuint *v)
5795{
5796 UNIMPLEMENTED();
5797}
5798
5799void APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue)
5800{
5801 UNIMPLEMENTED();
5802}
5803
5804void APIENTRY glColor3usv(const GLushort *v)
5805{
5806 UNIMPLEMENTED();
5807}
5808
5809void APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
5810{
5811 UNIMPLEMENTED();
5812}
5813
5814void APIENTRY glColor4bv(const GLbyte *v)
5815{
5816 UNIMPLEMENTED();
5817}
5818
5819void APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
5820{
5821 UNIMPLEMENTED();
5822}
5823
5824void APIENTRY glColor4dv(const GLdouble *v)
5825{
5826 UNIMPLEMENTED();
5827}
5828
5829void APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
5830{
5831 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);
5832
5833 gl::Context *context = gl::getContext();
5834
5835 if(context)
5836 {
5837 if(context->getListIndex() != 0)
5838 {
5839 UNIMPLEMENTED();
5840 }
5841
5842 //context->color(red, green, blue, alpha);
5843 //GLfloat vals[4] = {red, green, blue, alpha};
5844 context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
5845 }
5846}
5847
5848void APIENTRY glColor4fv(const GLfloat *v)
5849{
5850 UNIMPLEMENTED();
5851}
5852
5853void APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha)
5854{
5855 UNIMPLEMENTED();
5856}
5857
5858void APIENTRY glColor4iv(const GLint *v)
5859{
5860 UNIMPLEMENTED();
5861}
5862
5863void APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
5864{
5865 UNIMPLEMENTED();
5866}
5867
5868void APIENTRY glColor4sv(const GLshort *v)
5869{
5870 UNIMPLEMENTED();
5871}
5872
5873void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
5874{
5875 UNIMPLEMENTED();
5876}
5877
5878void APIENTRY glColor4ubv(const GLubyte *v)
5879{
5880 UNIMPLEMENTED();
5881}
5882
5883void APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
5884{
5885 UNIMPLEMENTED();
5886}
5887
5888void APIENTRY glColor4uiv(const GLuint *v)
5889{
5890 UNIMPLEMENTED();
5891}
5892
5893void APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
5894{
5895 UNIMPLEMENTED();
5896}
5897
5898void APIENTRY glColor4usv(const GLushort *v)
5899{
5900 UNIMPLEMENTED();
5901}
5902
5903void APIENTRY glColorMaterial(GLenum face, GLenum mode)
5904{
5905 TRACE("(GLenum face = 0x%X, GLenum mode = 0x%X)", face, mode);
5906
5907 // FIXME: Validate enums
5908
5909 gl::Context *context = gl::getContext();
5910
5911 if(context)
5912 {
5913 if(context->getListIndex() != 0)
5914 {
5915 UNIMPLEMENTED();
5916 }
5917
5918 switch(face)
5919 {
5920 case GL_FRONT:
5921 context->setColorMaterialMode(mode); // FIXME: Front only
5922 break;
5923 case GL_FRONT_AND_BACK:
5924 context->setColorMaterialMode(mode);
5925 break;
5926 default:
5927 UNIMPLEMENTED();
5928 return error(GL_INVALID_ENUM);
5929 }
5930 }
5931}
5932
5933void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
5934{
5935 TRACE("(*)");
5936
5937 glVertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
5938}
5939
5940void APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
5941{
5942 UNIMPLEMENTED();
5943}
5944
5945void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)
5946{
5947 UNIMPLEMENTED();
5948}
5949
5950void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
5951{
5952 UNIMPLEMENTED();
5953}
5954
5955void APIENTRY glDebugEntry()
5956{
5957 UNIMPLEMENTED();
5958}
5959
5960void APIENTRY glDeleteLists(GLuint list, GLsizei range)
5961{
5962 TRACE("(GLuint list = %d, GLsizei range = %d)", list, range);
5963
5964 if(range < 0)
5965 {
5966 return error(GL_INVALID_VALUE);
5967 }
5968
5969 gl::Context *context = gl::getContext();
5970
5971 if(context)
5972 {
Alexis Hetuf7be67f2015-02-11 16:11:07 -05005973 for(GLuint i = list; i < list + range; i++)
Nicolas Capensa9b49372015-01-30 00:33:26 -05005974 {
5975 context->deleteList(i);
5976 }
5977 }
5978}
5979
5980void APIENTRY glDepthRange(GLclampd zNear, GLclampd zFar)
5981{
5982 UNIMPLEMENTED();
5983}
5984
5985void APIENTRY glDisableClientState(GLenum array)
5986{
5987 TRACE("(GLenum array = 0x%X)", array);
5988
5989 gl::Context *context = gl::getContext();
5990
5991 if(context)
5992 {
5993 GLenum texture = context->getClientActiveTexture();
5994
5995 switch(array)
5996 {
5997 case GL_VERTEX_ARRAY: context->setEnableVertexAttribArray(sw::Position, false); break;
5998 case GL_COLOR_ARRAY: context->setEnableVertexAttribArray(sw::Color0, false); break;
5999 case GL_TEXTURE_COORD_ARRAY: context->setEnableVertexAttribArray(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
6000 case GL_NORMAL_ARRAY: context->setEnableVertexAttribArray(sw::Normal, false); break;
6001 default: UNIMPLEMENTED();
6002 }
6003 }
6004}
6005
6006void APIENTRY glDrawBuffer(GLenum mode)
6007{
6008 UNIMPLEMENTED();
6009}
6010
6011void APIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
6012{
6013 UNIMPLEMENTED();
6014}
6015
6016void APIENTRY glEdgeFlag(GLboolean flag)
6017{
6018 UNIMPLEMENTED();
6019}
6020
6021void APIENTRY glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)
6022{
6023 UNIMPLEMENTED();
6024}
6025
6026void APIENTRY glEdgeFlagv(const GLboolean *flag)
6027{
6028 UNIMPLEMENTED();
6029}
6030
6031void APIENTRY glEnableClientState(GLenum array)
6032{
6033 TRACE("(GLenum array = 0x%X)", array);
6034
6035 gl::Context *context = gl::getContext();
6036
6037 if(context)
6038 {
6039 GLenum texture = context->getClientActiveTexture();
6040
6041 switch(array)
6042 {
6043 case GL_VERTEX_ARRAY: context->setEnableVertexAttribArray(sw::Position, true); break;
6044 case GL_COLOR_ARRAY: context->setEnableVertexAttribArray(sw::Color0, true); break;
6045 case GL_TEXTURE_COORD_ARRAY: context->setEnableVertexAttribArray(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
6046 case GL_NORMAL_ARRAY: context->setEnableVertexAttribArray(sw::Normal, true); break;
6047 default: UNIMPLEMENTED();
6048 }
6049 }
6050}
6051
6052void APIENTRY glEnd()
6053{
6054 TRACE("()");
6055
6056 gl::Context *context = gl::getContext();
6057
6058 if(context)
6059 {
6060 if(context->getListIndex() != 0)
6061 {
6062 UNIMPLEMENTED();
6063 }
6064
6065 context->end();
6066 }
6067}
6068
6069void APIENTRY glEndList()
6070{
6071 TRACE("()");
6072
6073 gl::Context *context = gl::getContext();
6074
6075 if(context)
6076 {
6077 context->endList();
6078 }
6079}
6080
6081void APIENTRY glEvalCoord1d(GLdouble u)
6082{
6083 UNIMPLEMENTED();
6084}
6085
6086void APIENTRY glEvalCoord1dv(const GLdouble *u)
6087{
6088 UNIMPLEMENTED();
6089}
6090
6091void APIENTRY glEvalCoord1f(GLfloat u)
6092{
6093 UNIMPLEMENTED();
6094}
6095
6096void APIENTRY glEvalCoord1fv(const GLfloat *u)
6097{
6098 UNIMPLEMENTED();
6099}
6100
6101void APIENTRY glEvalCoord2d(GLdouble u, GLdouble v)
6102{
6103 UNIMPLEMENTED();
6104}
6105
6106void APIENTRY glEvalCoord2dv(const GLdouble *u)
6107{
6108 UNIMPLEMENTED();
6109}
6110
6111void APIENTRY glEvalCoord2f(GLfloat u, GLfloat v)
6112{
6113 UNIMPLEMENTED();
6114}
6115
6116void APIENTRY glEvalCoord2fv(const GLfloat *u)
6117{
6118 UNIMPLEMENTED();
6119}
6120
6121void APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2)
6122{
6123 UNIMPLEMENTED();
6124}
6125
6126void APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
6127{
6128 UNIMPLEMENTED();
6129}
6130
6131void APIENTRY glEvalPoint1(GLint i)
6132{
6133 UNIMPLEMENTED();
6134}
6135
6136void APIENTRY glEvalPoint2(GLint i, GLint j)
6137{
6138 UNIMPLEMENTED();
6139}
6140
6141void APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
6142{
6143 UNIMPLEMENTED();
6144}
6145
6146void APIENTRY glFogf(GLenum pname, GLfloat param)
6147{
6148 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
6149
6150 gl::Context *context = gl::getContext();
6151
6152 if(context)
6153 {
6154 if(context->getListIndex() != 0)
6155 {
6156 UNIMPLEMENTED();
6157 }
6158
6159 gl::Device *device = gl::getDevice(); // FIXME
6160
6161 switch(pname)
6162 {
6163 case GL_FOG_START: device->setFogStart(param); break;
6164 case GL_FOG_END: device->setFogEnd(param); break;
6165 default:
6166 UNIMPLEMENTED();
6167 return error(GL_INVALID_ENUM);
6168 }
6169 }
6170}
6171
6172void APIENTRY glFogfv(GLenum pname, const GLfloat *params)
6173{
6174 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
6175
6176 gl::Context *context = gl::getContext();
6177
6178 if(context)
6179 {
6180 if(context->getListIndex() != 0)
6181 {
6182 UNIMPLEMENTED();
6183 }
6184
6185 switch(pname)
6186 {
6187 case GL_FOG_COLOR:
6188 {
6189 gl::Device *device = gl::getDevice(); // FIXME
6190 device->setFogColor(sw::Color<float>(params[0], params[1], params[2], params[3]));
6191 }
6192 break;
6193 default:
6194 UNIMPLEMENTED();
6195 return error(GL_INVALID_ENUM);
6196 }
6197 }
6198}
6199
6200void APIENTRY glFogi(GLenum pname, GLint param)
6201{
6202 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
6203
6204 gl::Context *context = gl::getContext();
6205
6206 if(context)
6207 {
6208 if(context->getListIndex() != 0)
6209 {
6210 UNIMPLEMENTED();
6211 }
6212
6213 switch(pname)
6214 {
6215 case GL_FOG_MODE:
6216 {
6217 gl::Device *device = gl::getDevice(); // FIXME
6218 switch(param)
6219 {
6220 case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
6221 default:
6222 UNIMPLEMENTED();
6223 return error(GL_INVALID_ENUM);
6224 }
6225 }
6226 break;
6227 default:
6228 UNIMPLEMENTED();
6229 return error(GL_INVALID_ENUM);
6230 }
6231 }
6232}
6233
6234void APIENTRY glFogiv(GLenum pname, const GLint *params)
6235{
6236 UNIMPLEMENTED();
6237}
6238
6239void APIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
6240{
Nicolas Capens74626012015-03-11 21:49:44 -04006241 TRACE("(GLdouble left = %f, GLdouble right = %f, GLdouble bottom = %f, GLdouble top = %f, GLdouble zNear = %f, GLdouble zFar = %f)", left, right, bottom, top, zNear, zFar);
Maxime Gregoirefec81292015-03-04 14:44:36 -05006242
6243 gl::Context *context = gl::getContext();
6244
6245 if(context)
6246 {
6247 if(context->getListIndex() != 0)
6248 {
6249 UNIMPLEMENTED();
6250 }
6251
6252 context->frustum(left, right, bottom, top, zNear, zFar);
6253 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05006254}
6255
6256GLuint APIENTRY glGenLists(GLsizei range)
6257{
6258 TRACE("(GLsizei range = %d)", range);
6259
6260 if(range < 0)
6261 {
6262 return error(GL_INVALID_VALUE, 0);
6263 }
6264
6265 gl::Context *context = gl::getContext();
6266
6267 if(context)
6268 {
6269 return context->genLists(range);
6270 }
6271
6272 return 0;
6273}
6274
6275void APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation)
6276{
6277 UNIMPLEMENTED();
6278}
6279
6280void APIENTRY glGetDoublev(GLenum pname, GLdouble *params)
6281{
6282 UNIMPLEMENTED();
6283}
6284
6285void APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
6286{
6287 UNIMPLEMENTED();
6288}
6289
6290void APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params)
6291{
6292 UNIMPLEMENTED();
6293}
6294
6295void APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v)
6296{
6297 UNIMPLEMENTED();
6298}
6299
6300void APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v)
6301{
6302 UNIMPLEMENTED();
6303}
6304
6305void APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v)
6306{
6307 UNIMPLEMENTED();
6308}
6309
6310void APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
6311{
6312 UNIMPLEMENTED();
6313}
6314
6315void APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params)
6316{
6317 UNIMPLEMENTED();
6318}
6319
6320void APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values)
6321{
6322 UNIMPLEMENTED();
6323}
6324
6325void APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values)
6326{
6327 UNIMPLEMENTED();
6328}
6329
6330void APIENTRY glGetPixelMapusv(GLenum map, GLushort *values)
6331{
6332 UNIMPLEMENTED();
6333}
6334
6335void APIENTRY glGetPointerv(GLenum pname, GLvoid* *params)
6336{
6337 UNIMPLEMENTED();
6338}
6339
6340void APIENTRY glGetPolygonStipple(GLubyte *mask)
6341{
6342 UNIMPLEMENTED();
6343}
6344
6345void APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
6346{
6347 UNIMPLEMENTED();
6348}
6349
6350void APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params)
6351{
6352 UNIMPLEMENTED();
6353}
6354
6355void APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
6356{
6357 UNIMPLEMENTED();
6358}
6359
6360void APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
6361{
6362 UNIMPLEMENTED();
6363}
6364
6365void APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
6366{
6367 UNIMPLEMENTED();
6368}
6369
6370void APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
6371{
6372 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);
6373
6374 gl::Context *context = gl::getContext();
6375
6376 if(context)
6377 {
6378 gl::Texture *texture;
6379
6380 switch(target)
6381 {
6382 case GL_TEXTURE_2D:
6383 texture = context->getTexture2D(target);
6384 break;
6385 case GL_TEXTURE_CUBE_MAP:
6386 texture = context->getTextureCubeMap();
6387 break;
6388 default:
6389 UNIMPLEMENTED();
6390 return error(GL_INVALID_ENUM);
6391 }
6392
6393 if(format == texture->getFormat(target, level) && type == texture->getType(target, level))
6394 {
6395 gl::Image *image = texture->getRenderTarget(target, level);
6396 void *source = image->lock(0, 0, sw::LOCK_READONLY);
6397 memcpy(pixels, source, image->getPitch() * image->getHeight());
6398 image->unlock();
6399 }
6400 else
6401 {
6402 UNIMPLEMENTED();
6403 }
6404 }
6405}
6406
6407void APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
6408{
6409 UNIMPLEMENTED();
6410}
6411
6412void APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
6413{
6414 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, level, pname, params);
6415
6416 gl::Context *context = gl::getContext();
6417
6418 if(context)
6419 {
6420 gl::Texture *texture;
6421
6422 switch(target)
6423 {
6424 case GL_TEXTURE_2D:
6425 case GL_PROXY_TEXTURE_2D:
6426 texture = context->getTexture2D(target);
6427 break;
6428 case GL_TEXTURE_CUBE_MAP:
6429 texture = context->getTextureCubeMap();
6430 break;
6431 default:
6432 UNIMPLEMENTED();
6433 return error(GL_INVALID_ENUM);
6434 }
6435
6436 switch(pname)
6437 {
6438 case GL_TEXTURE_MAG_FILTER:
6439 *params = texture->getMagFilter();
6440 break;
6441 case GL_TEXTURE_MIN_FILTER:
6442 *params = texture->getMinFilter();
6443 break;
6444 case GL_TEXTURE_WRAP_S:
6445 *params = texture->getWrapS();
6446 break;
6447 case GL_TEXTURE_WRAP_T:
6448 *params = texture->getWrapT();
6449 break;
6450 case GL_TEXTURE_WIDTH:
6451 *params = texture->getWidth(target, level);
6452 break;
6453 case GL_TEXTURE_HEIGHT:
6454 *params = texture->getHeight(target, level);
6455 break;
6456 case GL_TEXTURE_INTERNAL_FORMAT:
6457 *params = texture->getInternalFormat(target, level);
6458 break;
6459 case GL_TEXTURE_BORDER_COLOR:
6460 UNIMPLEMENTED();
6461 break;
6462 case GL_TEXTURE_BORDER:
6463 UNIMPLEMENTED();
6464 break;
6465 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6466 *params = (GLint)texture->getMaxAnisotropy();
6467 break;
6468 default:
6469 return error(GL_INVALID_ENUM);
6470 }
6471 }
6472}
6473
6474void APIENTRY glIndexMask(GLuint mask)
6475{
6476 UNIMPLEMENTED();
6477}
6478
6479void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
6480{
6481 UNIMPLEMENTED();
6482}
6483
6484void APIENTRY glIndexd(GLdouble c)
6485{
6486 UNIMPLEMENTED();
6487}
6488
6489void APIENTRY glIndexdv(const GLdouble *c)
6490{
6491 UNIMPLEMENTED();
6492}
6493
6494void APIENTRY glIndexf(GLfloat c)
6495{
6496 UNIMPLEMENTED();
6497}
6498
6499void APIENTRY glIndexfv(const GLfloat *c)
6500{
6501 UNIMPLEMENTED();
6502}
6503
6504void APIENTRY glIndexi(GLint c)
6505{
6506 UNIMPLEMENTED();
6507}
6508
6509void APIENTRY glIndexiv(const GLint *c)
6510{
6511 UNIMPLEMENTED();
6512}
6513
6514void APIENTRY glIndexs(GLshort c)
6515{
6516 UNIMPLEMENTED();
6517}
6518
6519void APIENTRY glIndexsv(const GLshort *c)
6520{
6521 UNIMPLEMENTED();
6522}
6523
6524void APIENTRY glIndexub(GLubyte c)
6525{
6526 UNIMPLEMENTED();
6527}
6528
6529void APIENTRY glIndexubv(const GLubyte *c)
6530{
6531 UNIMPLEMENTED();
6532}
6533
6534void APIENTRY glInitNames(void)
6535{
6536 UNIMPLEMENTED();
6537}
6538
6539void APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
6540{
6541 UNIMPLEMENTED();
6542}
6543
6544GLboolean APIENTRY glIsList(GLuint list)
6545{
6546 UNIMPLEMENTED();
6547 return GL_FALSE;
6548}
6549
6550void APIENTRY glLightModelf(GLenum pname, GLfloat param)
6551{
6552 UNIMPLEMENTED();
6553}
6554
6555void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
6556{
6557 TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
6558
6559 gl::Context *context = gl::getContext();
6560
6561 if(context)
6562 {
6563 if(context->getListIndex() != 0)
6564 {
6565 UNIMPLEMENTED();
6566 }
6567
6568 gl::Device *device = gl::getDevice(); // FIXME
6569
6570 switch(pname)
6571 {
6572 case GL_LIGHT_MODEL_AMBIENT:
6573 device->setGlobalAmbient(sw::Color<float>(params[0], params[1], params[2], params[3]));
6574 break;
6575 default:
6576 UNIMPLEMENTED();
6577 return error(GL_INVALID_ENUM);
6578 }
6579 }
6580}
6581
6582void APIENTRY glLightModeli(GLenum pname, GLint param)
6583{
6584 UNIMPLEMENTED();
6585}
6586
6587void APIENTRY glLightModeliv(GLenum pname, const GLint *params)
6588{
6589 TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
6590 UNIMPLEMENTED();
6591}
6592
6593void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
6594{
6595 UNIMPLEMENTED();
6596}
6597
6598void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
6599{
6600 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
6601
6602 gl::Context *context = gl::getContext();
6603
6604 if(context)
6605 {
6606 if(context->getListIndex() != 0)
6607 {
6608 UNIMPLEMENTED();
6609 }
6610
6611 gl::Device *device = gl::getDevice(); // FIXME
6612
6613 switch(pname)
6614 {
6615 case GL_AMBIENT: device->setLightAmbient(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6616 case GL_DIFFUSE: device->setLightDiffuse(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6617 case GL_SPECULAR: device->setLightSpecular(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
6618 case GL_POSITION:
6619 if(params[3] == 0.0f) // Directional light
6620 {
6621 // Create a very far out point light
6622 float max = std::max(std::max(abs(params[0]), abs(params[1])), abs(params[2]));
6623 device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / max * 1e10f, params[1] / max * 1e10f, params[2] / max * 1e10f));
6624 }
6625 else
6626 {
6627 device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / params[3], params[1] / params[3], params[2] / params[3]));
6628 }
6629 break;
6630 default:
6631 UNIMPLEMENTED();
6632 return error(GL_INVALID_ENUM);
6633 }
6634 }
6635}
6636
6637void APIENTRY glLighti(GLenum light, GLenum pname, GLint param)
6638{
6639 UNIMPLEMENTED();
6640}
6641
6642void APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params)
6643{
6644 UNIMPLEMENTED();
6645}
6646
6647void APIENTRY glLineStipple(GLint factor, GLushort pattern)
6648{
6649 UNIMPLEMENTED();
6650}
6651
6652void APIENTRY glListBase(GLuint base)
6653{
6654 UNIMPLEMENTED();
6655}
6656
6657void APIENTRY glLoadIdentity()
6658{
6659 TRACE("()");
6660
6661 gl::Context *context = gl::getContext();
6662
6663 if(context)
6664 {
6665 if(context->getListIndex() != 0)
6666 {
6667 UNIMPLEMENTED();
6668 }
6669
6670 context->loadIdentity();
6671 }
6672}
6673
6674void APIENTRY glLoadMatrixd(const GLdouble *m)
6675{
6676 UNIMPLEMENTED();
6677}
6678
6679void APIENTRY glLoadMatrixf(const GLfloat *m)
6680{
6681 UNIMPLEMENTED();
6682}
6683
6684void APIENTRY glLoadName(GLuint name)
6685{
6686 UNIMPLEMENTED();
6687}
6688
6689void APIENTRY glLogicOp(GLenum opcode)
6690{
6691 UNIMPLEMENTED();
6692}
6693
6694void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
6695{
6696 UNIMPLEMENTED();
6697}
6698
6699void APIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
6700{
6701 UNIMPLEMENTED();
6702}
6703
6704void APIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)
6705{
6706 UNIMPLEMENTED();
6707}
6708
6709void APIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)
6710{
6711 UNIMPLEMENTED();
6712}
6713
6714void APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
6715{
6716 UNIMPLEMENTED();
6717}
6718
6719void APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
6720{
6721 UNIMPLEMENTED();
6722}
6723
6724void APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
6725{
6726 UNIMPLEMENTED();
6727}
6728
6729void APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
6730{
6731 UNIMPLEMENTED();
6732}
6733
6734void APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
6735{
6736 UNIMPLEMENTED();
6737}
6738
6739void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
6740{
6741 UNIMPLEMENTED();
6742}
6743
6744void APIENTRY glMateriali(GLenum face, GLenum pname, GLint param)
6745{
6746 UNIMPLEMENTED();
6747}
6748
6749void APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params)
6750{
6751 UNIMPLEMENTED();
6752}
6753
6754void APIENTRY glMatrixMode(GLenum mode)
6755{
6756 TRACE("(*)");
6757
6758 gl::Context *context = gl::getContext();
6759
6760 if(context)
6761 {
6762 if(context->getListIndex() != 0)
6763 {
6764 UNIMPLEMENTED();
6765 }
6766
6767 context->setMatrixMode(mode);
6768 }
6769}
6770
6771void APIENTRY glMultMatrixd(const GLdouble *m)
6772{
Maxime Gregoire53ff8d82015-03-04 14:51:58 -05006773 TRACE("(*)");
6774
6775 gl::Context *context = gl::getContext();
6776
6777 if(context)
6778 {
6779 if(context->getListIndex() != 0)
6780 {
6781 UNIMPLEMENTED();
6782 }
6783
6784 context->multiply(m);
6785 }
Nicolas Capensa9b49372015-01-30 00:33:26 -05006786}
6787
6788void APIENTRY glMultMatrixm(sw::Matrix m)
6789{
6790 gl::Context *context = gl::getContext();
6791
6792 if(context)
6793 {
6794 context->multiply((GLfloat*)m.m);
6795 }
6796}
6797
6798void APIENTRY glMultMatrixf(const GLfloat *m)
6799{
6800 TRACE("(*)");
6801
6802 gl::Context *context = gl::getContext();
6803
6804 if(context)
6805 {
6806 if(context->getListIndex() != 0)
6807 {
6808 return context->listCommand(gl::newCommand(glMultMatrixm, sw::Matrix(m)));
6809 }
6810
6811 context->multiply(m);
6812 }
6813}
6814
6815void APIENTRY glNewList(GLuint list, GLenum mode)
6816{
6817 TRACE("(GLuint list = %d, GLenum mode = 0x%X)", list, mode);
6818
6819 if(list == 0)
6820 {
6821 return error(GL_INVALID_VALUE);
6822 }
6823
6824 switch(mode)
6825 {
6826 case GL_COMPILE:
6827 case GL_COMPILE_AND_EXECUTE:
6828 break;
6829 default:
6830 return error(GL_INVALID_ENUM);
6831 }
6832
6833 gl::Context *context = gl::getContext();
6834
6835 if(context)
6836 {
6837 if(context->getListIndex() != 0)
6838 {
6839 UNIMPLEMENTED();
6840 }
6841
6842 context->newList(list, mode);
6843 }
6844}
6845
6846void APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
6847{
6848 UNIMPLEMENTED();
6849}
6850
6851void APIENTRY glNormal3bv(const GLbyte *v)
6852{
6853 UNIMPLEMENTED();
6854}
6855
6856void APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
6857{
6858 UNIMPLEMENTED();
6859}
6860
6861void APIENTRY glNormal3dv(const GLdouble *v)
6862{
6863 UNIMPLEMENTED();
6864}
6865
6866void APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
6867{
6868 TRACE("(GLfloat nx = %f, GLfloat ny = %f, GLfloat nz = %f)", nx, ny, nz);
6869
6870 gl::Context *context = gl::getContext();
6871
6872 if(context)
6873 {
6874 if(context->getListIndex() != 0)
6875 {
6876 UNIMPLEMENTED();
6877 }
6878
6879 //context->normal(nx, ny, nz);
6880 context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
6881 }
6882}
6883
6884void APIENTRY glNormal3fv(const GLfloat *v)
6885{
6886 UNIMPLEMENTED();
6887}
6888
6889void APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz)
6890{
6891 UNIMPLEMENTED();
6892}
6893
6894void APIENTRY glNormal3iv(const GLint *v)
6895{
6896 UNIMPLEMENTED();
6897}
6898
6899void APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz)
6900{
6901 UNIMPLEMENTED();
6902}
6903
6904void APIENTRY glNormal3sv(const GLshort *v)
6905{
6906 UNIMPLEMENTED();
6907}
6908
6909void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
6910{
6911 TRACE("(*)");
6912
6913 glVertexAttribPointer(sw::Normal, 3, type, false, stride, pointer);
6914}
6915
6916void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
6917{
6918 TRACE("(*)");
6919
6920 gl::Context *context = gl::getContext();
6921
6922 if(context)
6923 {
6924 if(context->getListIndex() != 0)
6925 {
6926 UNIMPLEMENTED();
6927 }
6928
6929 context->ortho(left, right, bottom, top, zNear, zFar);
6930 }
6931}
6932
6933void APIENTRY glPassThrough(GLfloat token)
6934{
6935 UNIMPLEMENTED();
6936}
6937
6938void APIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)
6939{
6940 UNIMPLEMENTED();
6941}
6942
6943void APIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)
6944{
6945 UNIMPLEMENTED();
6946}
6947
6948void APIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)
6949{
6950 UNIMPLEMENTED();
6951}
6952
6953void APIENTRY glPixelStoref(GLenum pname, GLfloat param)
6954{
6955 UNIMPLEMENTED();
6956}
6957
6958void APIENTRY glPixelTransferf(GLenum pname, GLfloat param)
6959{
6960 UNIMPLEMENTED();
6961}
6962
6963void APIENTRY glPixelTransferi(GLenum pname, GLint param)
6964{
6965 UNIMPLEMENTED();
6966}
6967
6968void APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
6969{
6970 UNIMPLEMENTED();
6971}
6972
6973void APIENTRY glPointSize(GLfloat size)
6974{
6975 UNIMPLEMENTED();
6976}
6977
6978void APIENTRY glPolygonMode(GLenum face, GLenum mode)
6979{
6980 UNIMPLEMENTED();
6981}
6982
6983void APIENTRY glPolygonStipple(const GLubyte *mask)
6984{
6985 UNIMPLEMENTED();
6986}
6987
6988void APIENTRY glPopAttrib(void)
6989{
6990 UNIMPLEMENTED();
6991}
6992
6993void APIENTRY glPopClientAttrib(void)
6994{
6995 UNIMPLEMENTED();
6996}
6997
6998void APIENTRY glPopMatrix(void)
6999{
7000 TRACE("()");
7001
7002 gl::Context *context = gl::getContext();
7003
7004 if(context)
7005 {
7006 if(context->getListIndex() != 0)
7007 {
7008 return context->listCommand(gl::newCommand(glPopMatrix));
7009 }
7010
7011 context->popMatrix();
7012 }
7013}
7014
7015void APIENTRY glPopName(void)
7016{
7017 UNIMPLEMENTED();
7018}
7019
7020void APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities)
7021{
7022 UNIMPLEMENTED();
7023}
7024
7025void APIENTRY glPushAttrib(GLbitfield mask)
7026{
7027 UNIMPLEMENTED();
7028}
7029
7030void APIENTRY glPushClientAttrib(GLbitfield mask)
7031{
7032 UNIMPLEMENTED();
7033}
7034
7035void APIENTRY glPushMatrix(void)
7036{
7037 TRACE("()");
7038
7039 gl::Context *context = gl::getContext();
7040
7041 if(context)
7042 {
7043 if(context->getListIndex() != 0)
7044 {
7045 return context->listCommand(gl::newCommand(glPushMatrix));
7046 }
7047
7048 context->pushMatrix();
7049 }
7050}
7051
7052void APIENTRY glPushName(GLuint name)
7053{
7054 UNIMPLEMENTED();
7055}
7056
7057void APIENTRY glRasterPos2d(GLdouble x, GLdouble y)
7058{
7059 UNIMPLEMENTED();
7060}
7061
7062void APIENTRY glRasterPos2dv(const GLdouble *v)
7063{
7064 UNIMPLEMENTED();
7065}
7066
7067void APIENTRY glRasterPos2f(GLfloat x, GLfloat y)
7068{
7069 UNIMPLEMENTED();
7070}
7071
7072void APIENTRY glRasterPos2fv(const GLfloat *v)
7073{
7074 UNIMPLEMENTED();
7075}
7076
7077void APIENTRY glRasterPos2i(GLint x, GLint y)
7078{
7079 UNIMPLEMENTED();
7080}
7081
7082void APIENTRY glRasterPos2iv(const GLint *v)
7083{
7084 UNIMPLEMENTED();
7085}
7086
7087void APIENTRY glRasterPos2s(GLshort x, GLshort y)
7088{
7089 UNIMPLEMENTED();
7090}
7091
7092void APIENTRY glRasterPos2sv(const GLshort *v)
7093{
7094 UNIMPLEMENTED();
7095}
7096
7097void APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
7098{
7099 UNIMPLEMENTED();
7100}
7101
7102void APIENTRY glRasterPos3dv(const GLdouble *v)
7103{
7104 UNIMPLEMENTED();
7105}
7106
7107void APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
7108{
7109 UNIMPLEMENTED();
7110}
7111
7112void APIENTRY glRasterPos3fv(const GLfloat *v)
7113{
7114 UNIMPLEMENTED();
7115}
7116
7117void APIENTRY glRasterPos3i(GLint x, GLint y, GLint z)
7118{
7119 UNIMPLEMENTED();
7120}
7121
7122void APIENTRY glRasterPos3iv(const GLint *v)
7123{
7124 UNIMPLEMENTED();
7125}
7126
7127void APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z)
7128{
7129 UNIMPLEMENTED();
7130}
7131
7132void APIENTRY glRasterPos3sv(const GLshort *v)
7133{
7134 UNIMPLEMENTED();
7135}
7136
7137void APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
7138{
7139 UNIMPLEMENTED();
7140}
7141
7142void APIENTRY glRasterPos4dv(const GLdouble *v)
7143{
7144 UNIMPLEMENTED();
7145}
7146
7147void APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
7148{
7149 UNIMPLEMENTED();
7150}
7151
7152void APIENTRY glRasterPos4fv(const GLfloat *v)
7153{
7154 UNIMPLEMENTED();
7155}
7156
7157void APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w)
7158{
7159 UNIMPLEMENTED();
7160}
7161
7162void APIENTRY glRasterPos4iv(const GLint *v)
7163{
7164 UNIMPLEMENTED();
7165}
7166
7167void APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
7168{
7169 UNIMPLEMENTED();
7170}
7171
7172void APIENTRY glRasterPos4sv(const GLshort *v)
7173{
7174 UNIMPLEMENTED();
7175}
7176
7177void APIENTRY glReadBuffer(GLenum mode)
7178{
7179 UNIMPLEMENTED();
7180}
7181
7182void APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
7183{
7184 UNIMPLEMENTED();
7185}
7186
7187void APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2)
7188{
7189 UNIMPLEMENTED();
7190}
7191
7192void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
7193{
7194 UNIMPLEMENTED();
7195}
7196
7197void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2)
7198{
7199 UNIMPLEMENTED();
7200}
7201
7202void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2)
7203{
7204 UNIMPLEMENTED();
7205}
7206
7207void APIENTRY glRectiv(const GLint *v1, const GLint *v2)
7208{
7209 UNIMPLEMENTED();
7210}
7211
7212void APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
7213{
7214 UNIMPLEMENTED();
7215}
7216
7217void APIENTRY glRectsv(const GLshort *v1, const GLshort *v2)
7218{
7219 UNIMPLEMENTED();
7220}
7221
7222GLint APIENTRY glRenderMode(GLenum mode)
7223{
7224 UNIMPLEMENTED();
7225 return 0;
7226}
7227
7228void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
7229{
7230 UNIMPLEMENTED();
7231}
7232
7233void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
7234{
7235 TRACE("(*)");
7236
7237 gl::Context *context = gl::getContext();
7238
7239 if(context)
7240 {
7241 if(context->getListIndex() != 0)
7242 {
7243 UNIMPLEMENTED();
7244 }
7245
7246 context->rotate(angle, x, y, z);
7247 }
7248}
7249
7250void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)
7251{
7252 UNIMPLEMENTED();
7253}
7254
7255void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
7256{
7257 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7258
7259 gl::Context *context = gl::getContext();
7260
7261 if(context)
7262 {
7263 if(context->getListIndex() != 0)
7264 {
7265 return context->listCommand(gl::newCommand(glScalef, x, y, z));
7266 }
7267
7268 context->scale(x, y, z);
7269 }
7270}
7271
7272void APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer)
7273{
7274 UNIMPLEMENTED();
7275}
7276
7277void APIENTRY glShadeModel(GLenum mode)
7278{
7279 TRACE("(*)");
7280
7281 gl::Context *context = gl::getContext();
7282
7283 if(context)
7284 {
7285 if(context->getListIndex() != 0)
7286 {
7287 UNIMPLEMENTED();
7288 }
7289
7290 context->setShadeModel(mode);
7291 }
7292}
7293
7294void APIENTRY glTexCoord1d(GLdouble s)
7295{
7296 UNIMPLEMENTED();
7297}
7298
7299void APIENTRY glTexCoord1dv(const GLdouble *v)
7300{
7301 UNIMPLEMENTED();
7302}
7303
7304void APIENTRY glTexCoord1f(GLfloat s)
7305{
7306 UNIMPLEMENTED();
7307}
7308
7309void APIENTRY glTexCoord1fv(const GLfloat *v)
7310{
7311 UNIMPLEMENTED();
7312}
7313
7314void APIENTRY glTexCoord1i(GLint s)
7315{
7316 UNIMPLEMENTED();
7317}
7318
7319void APIENTRY glTexCoord1iv(const GLint *v)
7320{
7321 UNIMPLEMENTED();
7322}
7323
7324void APIENTRY glTexCoord1s(GLshort s)
7325{
7326 UNIMPLEMENTED();
7327}
7328
7329void APIENTRY glTexCoord1sv(const GLshort *v)
7330{
7331 UNIMPLEMENTED();
7332}
7333
7334void APIENTRY glTexCoord2d(GLdouble s, GLdouble t)
7335{
7336 UNIMPLEMENTED();
7337}
7338
7339void APIENTRY glTexCoord2dv(const GLdouble *v)
7340{
7341 UNIMPLEMENTED();
7342}
7343
7344void APIENTRY glTexCoord2f(GLfloat s, GLfloat t)
7345{
7346 TRACE("(GLfloat s = %f, GLfloat t = %f)", s, t);
7347
7348 gl::Context *context = gl::getContext();
7349
7350 if(context)
7351 {
7352 if(context->getListIndex() != 0)
7353 {
7354 UNIMPLEMENTED();
7355 }
7356
7357 //context->texCoord(s, t, 0.0f, 1.0f);
7358 unsigned int texture = context->getActiveTexture();
7359 context->setVertexAttrib(sw::TexCoord0/* + texture*/, s, t, 0.0f, 1.0f);
7360 }
7361}
7362
7363void APIENTRY glTexCoord2fv(const GLfloat *v)
7364{
7365 UNIMPLEMENTED();
7366}
7367
7368void APIENTRY glTexCoord2i(GLint s, GLint t)
7369{
7370 UNIMPLEMENTED();
7371}
7372
7373void APIENTRY glTexCoord2iv(const GLint *v)
7374{
7375 UNIMPLEMENTED();
7376}
7377
7378void APIENTRY glTexCoord2s(GLshort s, GLshort t)
7379{
7380 UNIMPLEMENTED();
7381}
7382
7383void APIENTRY glTexCoord2sv(const GLshort *v)
7384{
7385 UNIMPLEMENTED();
7386}
7387
7388void APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
7389{
7390 UNIMPLEMENTED();
7391}
7392
7393void APIENTRY glTexCoord3dv(const GLdouble *v)
7394{
7395 UNIMPLEMENTED();
7396}
7397
7398void APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
7399{
7400 UNIMPLEMENTED();
7401}
7402
7403void APIENTRY glTexCoord3fv(const GLfloat *v)
7404{
7405 UNIMPLEMENTED();
7406}
7407
7408void APIENTRY glTexCoord3i(GLint s, GLint t, GLint r)
7409{
7410 UNIMPLEMENTED();
7411}
7412
7413void APIENTRY glTexCoord3iv(const GLint *v)
7414{
7415 UNIMPLEMENTED();
7416}
7417
7418void APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r)
7419{
7420 UNIMPLEMENTED();
7421}
7422
7423void APIENTRY glTexCoord3sv(const GLshort *v)
7424{
7425 UNIMPLEMENTED();
7426}
7427
7428void APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
7429{
7430 UNIMPLEMENTED();
7431}
7432
7433void APIENTRY glTexCoord4dv(const GLdouble *v)
7434{
7435 UNIMPLEMENTED();
7436}
7437
7438void APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
7439{
7440 UNIMPLEMENTED();
7441}
7442
7443void APIENTRY glTexCoord4fv(const GLfloat *v)
7444{
7445 UNIMPLEMENTED();
7446}
7447
7448void APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q)
7449{
7450 UNIMPLEMENTED();
7451}
7452
7453void APIENTRY glTexCoord4iv(const GLint *v)
7454{
7455 UNIMPLEMENTED();
7456}
7457
7458void APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
7459{
7460 UNIMPLEMENTED();
7461}
7462
7463void APIENTRY glTexCoord4sv(const GLshort *v)
7464{
7465 UNIMPLEMENTED();
7466}
7467
7468void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
7469{
7470 TRACE("(*)");
7471
7472 gl::Context *context = gl::getContext();
7473
7474 if(context)
7475 {
7476 GLenum texture = context->getClientActiveTexture();
7477
7478 glVertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
7479 }
7480}
7481
7482void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
7483{
7484 UNIMPLEMENTED();
7485}
7486
7487void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
7488{
7489 UNIMPLEMENTED();
7490}
7491
7492void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
7493{
7494 UNIMPLEMENTED();
7495}
7496
7497void APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
7498{
7499 UNIMPLEMENTED();
7500}
7501
7502void APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param)
7503{
7504 UNIMPLEMENTED();
7505}
7506
7507void APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
7508{
7509 UNIMPLEMENTED();
7510}
7511
7512void APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param)
7513{
7514 UNIMPLEMENTED();
7515}
7516
7517void APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
7518{
7519 UNIMPLEMENTED();
7520}
7521
7522void APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param)
7523{
7524 UNIMPLEMENTED();
7525}
7526
7527void APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params)
7528{
7529 UNIMPLEMENTED();
7530}
7531
7532void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
7533{
7534 UNIMPLEMENTED();
7535}
7536
7537void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
7538{
7539 UNIMPLEMENTED();
7540}
7541
7542void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)
7543{
7544 TRACE("(*)");
7545
7546 gl::Context *context = gl::getContext();
7547
7548 if(context)
7549 {
7550 if(context->getListIndex() != 0)
7551 {
7552 return context->listCommand(gl::newCommand(glTranslated, x, y, z));
7553 }
7554
7555 context->translate(x, y, z); // FIXME
7556 }
7557}
7558
7559void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
7560{
7561 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7562
7563 gl::Context *context = gl::getContext();
7564
7565 if(context)
7566 {
7567 if(context->getListIndex() != 0)
7568 {
7569 return context->listCommand(gl::newCommand(glTranslatef, x, y, z));
7570 }
7571
7572 context->translate(x, y, z);
7573 }
7574}
7575
7576void APIENTRY glVertex2d(GLdouble x, GLdouble y)
7577{
7578 UNIMPLEMENTED();
7579}
7580
7581void APIENTRY glVertex2dv(const GLdouble *v)
7582{
7583 UNIMPLEMENTED();
7584}
7585
7586void APIENTRY glVertex2f(GLfloat x, GLfloat y)
7587{
7588 UNIMPLEMENTED();
7589}
7590
7591void APIENTRY glVertex2fv(const GLfloat *v)
7592{
7593 UNIMPLEMENTED();
7594}
7595
7596void APIENTRY glVertex2i(GLint x, GLint y)
7597{
7598 UNIMPLEMENTED();
7599}
7600
7601void APIENTRY glVertex2iv(const GLint *v)
7602{
7603 UNIMPLEMENTED();
7604}
7605
7606void APIENTRY glVertex2s(GLshort x, GLshort y)
7607{
7608 UNIMPLEMENTED();
7609}
7610
7611void APIENTRY glVertex2sv(const GLshort *v)
7612{
7613 UNIMPLEMENTED();
7614}
7615
7616void APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
7617{
7618 UNIMPLEMENTED();
7619}
7620
7621void APIENTRY glVertex3dv(const GLdouble *v)
7622{
7623 UNIMPLEMENTED();
7624}
7625
7626void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
7627{
7628 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
7629
7630 gl::Context *context = gl::getContext();
7631
7632 if(context)
7633 {
7634 if(context->getListIndex() != 0)
7635 {
7636 UNIMPLEMENTED();
7637 }
7638
7639 context->position(x, y, z, 1.0f);
7640 }
7641}
7642
7643void APIENTRY glVertex3fv(const GLfloat *v)
7644{
7645 UNIMPLEMENTED();
7646}
7647
7648void APIENTRY glVertex3i(GLint x, GLint y, GLint z)
7649{
7650 UNIMPLEMENTED();
7651}
7652
7653void APIENTRY glVertex3iv(const GLint *v)
7654{
7655 UNIMPLEMENTED();
7656}
7657
7658void APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z)
7659{
7660 UNIMPLEMENTED();
7661}
7662
7663void APIENTRY glVertex3sv(const GLshort *v)
7664{
7665 UNIMPLEMENTED();
7666}
7667
7668void APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
7669{
7670 UNIMPLEMENTED();
7671}
7672
7673void APIENTRY glVertex4dv(const GLdouble *v)
7674{
7675 UNIMPLEMENTED();
7676}
7677
7678void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
7679{
7680 UNIMPLEMENTED();
7681}
7682
7683void APIENTRY glVertex4fv(const GLfloat *v)
7684{
7685 UNIMPLEMENTED();
7686}
7687
7688void APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w)
7689{
7690 UNIMPLEMENTED();
7691}
7692
7693void APIENTRY glVertex4iv(const GLint *v)
7694{
7695 UNIMPLEMENTED();
7696}
7697
7698void APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
7699{
7700 UNIMPLEMENTED();
7701}
7702
7703void APIENTRY glVertex4sv(const GLshort *v)
7704{
7705 UNIMPLEMENTED();
7706}
7707
7708void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
7709{
7710 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = 0x%0.8p)", size, type, stride, pointer);
7711
7712 glVertexAttribPointer(sw::Position, size, type, false, stride, pointer);
7713}
7714
7715void APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) {UNIMPLEMENTED();}
7716void APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}
7717void 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();}
7718void APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
7719
7720void APIENTRY glClientActiveTexture(GLenum texture)
7721{
7722 TRACE("(GLenum texture = 0x%X)", texture);
7723
7724 switch(texture)
7725 {
7726 case GL_TEXTURE0:
7727 case GL_TEXTURE1:
7728 break;
7729 default:
7730 UNIMPLEMENTED();
7731 UNREACHABLE();
7732 }
7733
7734 gl::Context *context = gl::getContext();
7735
7736 if(context)
7737 {
7738 context->clientActiveTexture(texture);
7739 }
7740}
7741
7742void APIENTRY glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7743void APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7744void APIENTRY glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
7745void 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();}
7746void APIENTRY glGetCompressedTexImage(GLenum target, GLint level, void *img) {UNIMPLEMENTED();}
7747void APIENTRY glMultiTexCoord1f(GLenum target, GLfloat s) {UNIMPLEMENTED();}
7748void APIENTRY glMultiTexCoord1d(GLenum target, GLdouble s) {UNIMPLEMENTED();}
7749
7750void APIENTRY glMultiTexCoord2f(GLenum texture, GLfloat s, GLfloat t)
7751{
7752 TRACE("(GLenum texture = 0x%X, GLfloat s = %f, GLfloat t = %f)", texture, s, t);
7753
7754 gl::Context *context = gl::getContext();
7755
7756 if(context)
7757 {
7758 if(context->getListIndex() != 0)
7759 {
7760 UNIMPLEMENTED();
7761 }
7762
7763 //context->texCoord(s, t, 0.0f, 1.0f);
7764 context->setVertexAttrib(sw::TexCoord0 + (texture - GL_TEXTURE0), s, t, 0.0f, 1.0f);
7765 }
7766}
7767
7768void APIENTRY glMultiTexCoord2d(GLenum target, GLdouble s, GLdouble t) {UNIMPLEMENTED();}
7769void APIENTRY glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {UNIMPLEMENTED();}
7770void APIENTRY glMultiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r) {UNIMPLEMENTED();}
7771void APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {UNIMPLEMENTED();}
7772void APIENTRY glMultiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) {UNIMPLEMENTED();}
7773void APIENTRY glLoadTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
7774void APIENTRY glLoadTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
7775void APIENTRY glMultTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
7776void APIENTRY glMultTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
7777void APIENTRY glFogCoordf(GLfloat coord) {UNIMPLEMENTED();}
7778void APIENTRY glFogCoordd(GLdouble coord) {UNIMPLEMENTED();}
7779void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
7780void APIENTRY glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) {UNIMPLEMENTED();}
7781void APIENTRY glPointParameteri(GLenum pname, GLint param) {UNIMPLEMENTED();}
7782void APIENTRY glPointParameterf(GLenum pname, GLfloat param) {UNIMPLEMENTED();}
7783void APIENTRY glPointParameteriv(GLenum pname, const GLint *params) {UNIMPLEMENTED();}
7784void APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params) {UNIMPLEMENTED();}
7785void APIENTRY glSecondaryColor3b(GLbyte red, GLbyte green, GLbyte blue) {UNIMPLEMENTED();}
7786void APIENTRY glSecondaryColor3f(GLfloat red, GLfloat green, GLfloat blue) {UNIMPLEMENTED();}
7787void APIENTRY glSecondaryColor3d(GLdouble red, GLdouble green, GLdouble blue) {UNIMPLEMENTED();}
7788void APIENTRY glSecondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue) {UNIMPLEMENTED();}
7789void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
7790void APIENTRY glWindowPos2f(GLfloat x, GLfloat y) {UNIMPLEMENTED();}
7791void APIENTRY glWindowPos2d(GLdouble x, GLdouble y) {UNIMPLEMENTED();}
7792void APIENTRY glWindowPos2i(GLint x, GLint y) {UNIMPLEMENTED();}
7793void APIENTRY glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) {UNIMPLEMENTED();}
7794void APIENTRY glWindowPos3d(GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
7795void APIENTRY glWindowPos3i(GLint x, GLint y, GLint z) {UNIMPLEMENTED();}
7796void APIENTRY glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data) {UNIMPLEMENTED();}
7797void *APIENTRY glMapBuffer(GLenum target, GLenum access) {UNIMPLEMENTED(); return 0;}
7798GLboolean APIENTRY glUnmapBuffer(GLenum target) {UNIMPLEMENTED(); return GL_FALSE;}
7799void APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params) {UNIMPLEMENTED();}
7800void APIENTRY glGenQueries(GLsizei n, GLuint *ids) {UNIMPLEMENTED();}
7801void APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids) {UNIMPLEMENTED();}
7802GLboolean APIENTRY glIsQuery(GLuint id) {UNIMPLEMENTED(); return 0;}
7803void APIENTRY glBeginQuery(GLenum target, GLuint id) {UNIMPLEMENTED();}
7804void APIENTRY glEndQuery(GLenum target) {UNIMPLEMENTED();}
7805void APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params) {UNIMPLEMENTED();}
7806void APIENTRY glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) {UNIMPLEMENTED();}
7807void APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) {UNIMPLEMENTED();}
7808void APIENTRY glVertexAttrib1s(GLuint index, GLshort x) {UNIMPLEMENTED();}
7809void APIENTRY glVertexAttrib1d(GLuint index, GLdouble x) {UNIMPLEMENTED();}
7810void APIENTRY glVertexAttrib2s(GLuint index, GLshort x, GLshort y) {UNIMPLEMENTED();}
7811void APIENTRY glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y) {UNIMPLEMENTED();}
7812void APIENTRY glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z) {UNIMPLEMENTED();}
7813void APIENTRY glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
7814void APIENTRY glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) {UNIMPLEMENTED();}
7815void APIENTRY glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {UNIMPLEMENTED();}
7816void APIENTRY glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {UNIMPLEMENTED();}
7817void APIENTRY glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {UNIMPLEMENTED();}
7818void APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs) {UNIMPLEMENTED();}
7819void APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7820void APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7821void APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7822void APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7823void APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7824void APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
7825
7826void APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {UNIMPLEMENTED();}
7827void APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
7828void APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {UNIMPLEMENTED();}
7829
7830BOOL WINAPI wglSwapIntervalEXT(int interval)
7831{
7832 gl::Surface *drawSurface = static_cast<gl::Surface*>(gl::getCurrentDrawSurface());
7833
7834 if(drawSurface)
7835 {
7836 drawSurface->setSwapInterval(interval);
7837 return TRUE;
7838 }
7839
7840 SetLastError(ERROR_DC_NOT_FOUND);
7841 return FALSE;
7842}
7843
7844int WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)
7845{
7846 TRACE("(*)");
7847
7848 return 1;
7849}
7850
7851BOOL WINAPI wglCopyContext(HGLRC, HGLRC, UINT)
7852{
7853 UNIMPLEMENTED();
7854 return FALSE;
7855}
7856
7857HGLRC WINAPI wglCreateContext(HDC hdc)
7858{
7859 TRACE("(*)");
7860
7861 gl::Display *display = gl::Display::getDisplay(hdc);
7862 display->initialize();
7863
7864 gl::Context *context = display->createContext(nullptr);
7865
7866 return (HGLRC)context;
7867}
7868
7869HGLRC WINAPI wglCreateLayerContext(HDC, int)
7870{
7871 UNIMPLEMENTED();
7872 return 0;
7873}
7874
7875BOOL WINAPI wglDeleteContext(HGLRC context)
7876{
7877 gl::Display *display = gl::getDisplay();
7878
7879 if(display && context)
7880 {
7881 display->destroyContext(reinterpret_cast<gl::Context*>(context));
7882
7883 return TRUE;
7884 }
7885
7886 return FALSE;
7887}
7888
7889BOOL WINAPI wglDescribeLayerPlane(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR)
7890{
7891 UNIMPLEMENTED();
7892 return FALSE;
7893}
7894
7895int WINAPI wglDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
7896{
7897 TRACE("(*)");
7898
7899 ASSERT(nBytes == sizeof(PIXELFORMATDESCRIPTOR)); // FIXME
7900
7901 ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
7902 ppfd->nVersion = 1;
7903 ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
7904 ppfd->iPixelType = PFD_TYPE_RGBA;
7905 ppfd->cColorBits = 32;
7906 ppfd->cRedBits = 8;
7907 ppfd->cRedShift = 16;
7908 ppfd->cGreenBits = 8;
7909 ppfd->cGreenShift = 8;
7910 ppfd->cBlueBits = 8;
7911 ppfd->cBlueShift = 0;
7912 ppfd->cAlphaBits = 0;
7913 ppfd->cAlphaShift = 24;
7914 ppfd->cAccumBits = 0;
7915 ppfd->cAccumRedBits = 0;
7916 ppfd->cAccumGreenBits = 0;
7917 ppfd->cAccumBlueBits = 0;
7918 ppfd->cAccumAlphaBits = 0;
7919 ppfd->cDepthBits = 24;
7920 ppfd->cStencilBits = 0;
7921 ppfd->cAuxBuffers = 0;
7922 ppfd->iLayerType = 0;
7923 ppfd->bReserved = 0;
7924 ppfd->dwLayerMask = 0;
7925 ppfd->dwVisibleMask = 0;
7926 ppfd->dwDamageMask = 0;
7927
7928 return 1;
7929}
7930
7931HGLRC WINAPI wglGetCurrentContext(VOID)
7932{
7933 TRACE("(*)");
7934 return (HGLRC)gl::getContext();
7935}
7936
7937HDC WINAPI wglGetCurrentDC(VOID)
7938{
7939 TRACE("(*)");
7940 gl::Display *display = gl::getDisplay();
7941 return display ? display->getNativeDisplay() : 0;
7942}
7943
7944void WINAPI wglGetDefaultProcAddress()
7945{
7946 UNIMPLEMENTED();
7947}
7948
7949int WINAPI wglGetLayerPaletteEntries(HDC, int, int, int, COLORREF*)
7950{
7951 UNIMPLEMENTED();
7952 return 0;
7953}
7954
7955void WINAPI wglGetPixelFormat()
7956{
7957 UNIMPLEMENTED();
7958}
7959
7960const char *WINAPI wglGetExtensionsStringARB(HDC hdc)
7961{
7962 TRACE("(*)");
7963
7964 return "GL_ARB_framebuffer_object "
7965 "WGL_EXT_extensions_string "
7966 "WGL_EXT_swap_control";
7967}
7968
7969const char *WINAPI wglGetExtensionsStringEXT()
7970{
7971 TRACE("(*)");
7972 return wglGetExtensionsStringARB(0);
7973}
7974
7975PROC WINAPI wglGetProcAddress(LPCSTR lpszProc)
7976{
7977 TRACE("(LPCSTR lpszProc = \"%s\")", lpszProc);
7978
Nicolas Capens264f1522015-01-09 17:21:17 -05007979 struct Extension
7980 {
7981 const char *name;
Nicolas Capensa9b49372015-01-30 00:33:26 -05007982 PROC address;
Nicolas Capens264f1522015-01-09 17:21:17 -05007983 };
7984
7985 static const Extension glExtensions[] =
7986 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05007987 #define EXT(function) {#function, (PROC)function}
7988
7989 // Core 2.1
7990 EXT(glDrawRangeElements),
7991 EXT(glTexImage3D),
7992 EXT(glTexSubImage3D),
7993 EXT(glCopyTexSubImage3D),
7994 EXT(glActiveTexture),
7995 EXT(glClientActiveTexture),
7996 EXT(glCompressedTexImage1D),
7997 EXT(glCompressedTexImage2D),
7998 EXT(glCompressedTexImage3D),
7999 EXT(glCompressedTexSubImage1D),
8000 EXT(glCompressedTexSubImage2D),
8001 EXT(glCompressedTexSubImage3D),
8002 EXT(glGetCompressedTexImage),
8003 EXT(glMultiTexCoord1f),
8004 EXT(glMultiTexCoord1d),
8005 EXT(glMultiTexCoord2f),
8006 EXT(glMultiTexCoord2d),
8007 EXT(glMultiTexCoord3f),
8008 EXT(glMultiTexCoord3d),
8009 EXT(glMultiTexCoord4f),
8010 EXT(glMultiTexCoord4d),
8011 EXT(glLoadTransposeMatrixf),
8012 EXT(glLoadTransposeMatrixd),
8013 EXT(glMultTransposeMatrixf),
8014 EXT(glMultTransposeMatrixd),
8015 EXT(glSampleCoverage),
8016 EXT(glBlendEquation),
8017 EXT(glBlendColor),
8018 EXT(glFogCoordf),
8019 EXT(glFogCoordd),
8020 EXT(glFogCoordPointer),
8021 EXT(glMultiDrawArrays),
8022 EXT(glPointParameteri),
8023 EXT(glPointParameterf),
8024 EXT(glPointParameteriv),
8025 EXT(glPointParameterfv),
8026 EXT(glSecondaryColor3b),
8027 EXT(glSecondaryColor3f),
8028 EXT(glSecondaryColor3d),
8029 EXT(glSecondaryColor3ub),
8030 EXT(glSecondaryColorPointer),
8031 EXT(glBlendFuncSeparate),
8032 EXT(glWindowPos2f),
8033 EXT(glWindowPos2d),
8034 EXT(glWindowPos2i),
8035 EXT(glWindowPos3f),
8036 EXT(glWindowPos3d),
8037 EXT(glWindowPos3i),
8038 EXT(glBindBuffer),
8039 EXT(glDeleteBuffers),
8040 EXT(glGenBuffers),
8041 EXT(glIsBuffer),
8042 EXT(glBufferData),
8043 EXT(glBufferSubData),
8044 EXT(glGetBufferSubData),
8045 EXT(glMapBuffer),
8046 EXT(glUnmapBuffer),
8047 EXT(glGetBufferParameteriv),
8048 EXT(glGetBufferPointerv),
8049 EXT(glGenQueries),
8050 EXT(glDeleteQueries),
8051 EXT(glIsQuery),
8052 EXT(glBeginQuery),
8053 EXT(glEndQuery),
8054 EXT(glGetQueryiv),
8055 EXT(glGetQueryObjectiv),
8056 EXT(glGetQueryObjectuiv),
8057 EXT(glShaderSource),
8058 EXT(glCreateShader),
8059 EXT(glIsShader),
8060 EXT(glCompileShader),
8061 EXT(glDeleteShader),
8062 EXT(glCreateProgram),
8063 EXT(glIsProgram),
8064 EXT(glAttachShader),
8065 EXT(glDetachShader),
8066 EXT(glLinkProgram),
8067 EXT(glUseProgram),
8068 EXT(glValidateProgram),
8069 EXT(glDeleteProgram),
8070 EXT(glUniform1f),
8071 EXT(glUniform2f),
8072 EXT(glUniform3f),
8073 EXT(glUniform4f),
8074 EXT(glUniform1i),
8075 EXT(glUniform2i),
8076 EXT(glUniform3i),
8077 EXT(glUniform4i),
8078 EXT(glUniform1fv),
8079 EXT(glUniform2fv),
8080 EXT(glUniform3fv),
8081 EXT(glUniform4fv),
8082 EXT(glUniform1iv),
8083 EXT(glUniform2iv),
8084 EXT(glUniform3iv),
8085 EXT(glUniform4iv),
8086 EXT(glUniformMatrix2fv),
8087 EXT(glUniformMatrix3fv),
8088 EXT(glUniformMatrix4fv),
8089 EXT(glGetShaderiv),
8090 EXT(glGetProgramiv),
8091 EXT(glGetShaderInfoLog),
8092 EXT(glGetProgramInfoLog),
8093 EXT(glGetAttachedShaders),
8094 EXT(glGetUniformLocation),
8095 EXT(glGetActiveUniform),
8096 EXT(glGetUniformfv),
8097 EXT(glGetUniformiv),
8098 EXT(glGetShaderSource),
8099 EXT(glVertexAttrib1s),
8100 EXT(glVertexAttrib1f),
8101 EXT(glVertexAttrib1d),
8102 EXT(glVertexAttrib2s),
8103 EXT(glVertexAttrib2f),
8104 EXT(glVertexAttrib2d),
8105 EXT(glVertexAttrib3s),
8106 EXT(glVertexAttrib3f),
8107 EXT(glVertexAttrib3d),
8108 EXT(glVertexAttrib4s),
8109 EXT(glVertexAttrib4f),
8110 EXT(glVertexAttrib4d),
8111 EXT(glVertexAttrib4Nub),
8112 EXT(glVertexAttribPointer),
8113 EXT(glEnableVertexAttribArray),
8114 EXT(glDisableVertexAttribArray),
8115 EXT(glGetVertexAttribfv),
8116 EXT(glGetVertexAttribdv),
8117 EXT(glGetVertexAttribiv),
8118 EXT(glGetVertexAttribPointerv),
8119 EXT(glBindAttribLocation),
8120 EXT(glGetActiveAttrib),
8121 EXT(glGetAttribLocation),
8122 EXT(glDrawBuffers),
8123 EXT(glStencilOpSeparate),
8124 EXT(glStencilFuncSeparate),
8125 EXT(glStencilMaskSeparate),
8126 EXT(glBlendEquationSeparate),
8127 EXT(glUniformMatrix2x3fv),
8128 EXT(glUniformMatrix3x2fv),
8129 EXT(glUniformMatrix2x4fv),
8130 EXT(glUniformMatrix4x2fv),
8131 EXT(glUniformMatrix3x4fv),
8132 EXT(glUniformMatrix4x3fv),
8133 EXT(glGenFencesNV),
8134 EXT(glDeleteFencesNV),
8135 EXT(glSetFenceNV),
8136 EXT(glTestFenceNV),
8137 EXT(glFinishFenceNV),
8138 EXT(glIsFenceNV),
8139 EXT(glGetFenceivNV),
8140
8141 EXT(glIsRenderbuffer),
8142 EXT(glBindRenderbuffer),
8143 EXT(glDeleteRenderbuffers),
8144 EXT(glGenRenderbuffers),
8145 EXT(glRenderbufferStorage),
8146 EXT(glGetRenderbufferParameteriv),
8147 EXT(glIsFramebuffer),
8148 EXT(glBindFramebuffer),
8149 EXT(glDeleteFramebuffers),
8150 EXT(glGenFramebuffers),
8151 EXT(glCheckFramebufferStatus),
8152 EXT(glFramebufferTexture1D),
8153 EXT(glFramebufferTexture2D),
8154 EXT(glFramebufferTexture3D),
8155 EXT(glFramebufferRenderbuffer),
8156 EXT(glGetFramebufferAttachmentParameteriv),
8157 EXT(glGenerateMipmap),
8158 EXT(glReleaseShaderCompiler),
8159 EXT(glShaderBinary),
8160 EXT(glGetShaderPrecisionFormat),
8161 EXT(glDepthRangef),
8162 EXT(glClearDepthf),
Nicolas Capens264f1522015-01-09 17:21:17 -05008163
Nicolas Capensa9b49372015-01-30 00:33:26 -05008164 // ARB
8165 EXT(wglGetExtensionsStringARB),
8166 EXT(glIsRenderbuffer),
8167 EXT(glBindRenderbuffer),
8168 EXT(glDeleteRenderbuffers),
8169 EXT(glGenRenderbuffers),
8170 EXT(glRenderbufferStorage),
8171 EXT(glRenderbufferStorageMultisample),
8172 EXT(glGetRenderbufferParameteriv),
8173 EXT(glIsFramebuffer),
8174 EXT(glBindFramebuffer),
8175 EXT(glDeleteFramebuffers),
8176 EXT(glGenFramebuffers),
8177 EXT(glCheckFramebufferStatus),
8178 EXT(glFramebufferTexture1D),
8179 EXT(glFramebufferTexture2D),
8180 EXT(glFramebufferTexture3D),
8181 EXT(glFramebufferTextureLayer),
8182 EXT(glFramebufferRenderbuffer),
8183 EXT(glGetFramebufferAttachmentParameteriv),
8184 EXT(glBlitFramebuffer),
8185 EXT(glGenerateMipmap),
Nicolas Capens264f1522015-01-09 17:21:17 -05008186
Nicolas Capensa9b49372015-01-30 00:33:26 -05008187 // EXT
8188 EXT(wglSwapIntervalEXT),
8189 EXT(wglGetExtensionsStringEXT),
8190 #undef EXT
Nicolas Capens264f1522015-01-09 17:21:17 -05008191 };
8192
8193 for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
8194 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05008195 if(strcmp(lpszProc, glExtensions[ext].name) == 0)
Nicolas Capens264f1522015-01-09 17:21:17 -05008196 {
Nicolas Capensa9b49372015-01-30 00:33:26 -05008197 return (PROC)glExtensions[ext].address;
Nicolas Capens264f1522015-01-09 17:21:17 -05008198 }
8199 }
8200
Nicolas Capensa9b49372015-01-30 00:33:26 -05008201 FARPROC proc = GetProcAddress(GetModuleHandle("opengl32.dll"), lpszProc); // FIXME?
8202
8203 if(proc)
8204 {
8205 return proc;
8206 }
8207
8208 TRACE("(LPCSTR lpszProc = \"%s\") NOT FOUND!!!", lpszProc);
8209
8210 return 0;
Nicolas Capens264f1522015-01-09 17:21:17 -05008211}
8212
Nicolas Capensa9b49372015-01-30 00:33:26 -05008213BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
8214{
8215 TRACE("(*)");
8216
8217 if(hdc && hglrc)
8218 {
8219 gl::Display *display = (gl::Display*)gl::Display::getDisplay(hdc);
8220 gl::makeCurrent((gl::Context*)hglrc, display, display->getPrimarySurface());
8221 gl::setCurrentDrawSurface(display->getPrimarySurface());
8222 gl::setCurrentDisplay(display);
8223 }
8224 else
8225 {
8226 gl::makeCurrent(0, 0, 0);
8227 }
8228
8229 return TRUE;
8230}
8231
8232BOOL WINAPI wglRealizeLayerPalette(HDC, int, BOOL)
8233{
8234 UNIMPLEMENTED();
8235 return FALSE;
8236}
8237
8238int WINAPI wglSetLayerPaletteEntries(HDC, int, int, int, CONST COLORREF*)
8239{
8240 UNIMPLEMENTED();
8241 return 0;
8242}
8243
8244BOOL WINAPI wglSetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
8245{
8246 TRACE("(*)");
8247 //UNIMPLEMENTED();
8248
8249 return TRUE;
8250}
8251
8252BOOL WINAPI wglShareLists(HGLRC, HGLRC)
8253{
8254 UNIMPLEMENTED();
8255 return FALSE;
8256}
8257
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008258BOOL WINAPI wglSwapBuffers(HDC hdc)
Nicolas Capensa9b49372015-01-30 00:33:26 -05008259{
8260 TRACE("(*)");
8261
8262 gl::Display *display = gl::getDisplay();
8263
8264 if(display)
8265 {
8266 display->getPrimarySurface()->swap();
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008267 return TRUE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008268 }
Maxime Gregoirea5fbca02015-02-12 16:52:54 -05008269
8270 return FALSE;
Nicolas Capensa9b49372015-01-30 00:33:26 -05008271}
8272
8273BOOL WINAPI wglSwapLayerBuffers(HDC, UINT)
8274{
8275 UNIMPLEMENTED();
8276 return FALSE;
8277}
8278
8279DWORD WINAPI wglSwapMultipleBuffers(UINT, CONST WGLSWAP*)
8280{
8281 UNIMPLEMENTED();
8282 return 0;
8283}
8284
8285BOOL WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD)
8286{
8287 UNIMPLEMENTED();
8288 return FALSE;
8289}
8290
8291BOOL WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD)
8292{
8293 UNIMPLEMENTED();
8294 return FALSE;
8295}
8296
8297BOOL WINAPI wglUseFontOutlinesA(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
8298{
8299 UNIMPLEMENTED();
8300 return FALSE;
8301}
8302
8303BOOL WINAPI wglUseFontOutlinesW(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
8304{
8305 UNIMPLEMENTED();
8306 return FALSE;
8307}
8308
8309void APIENTRY Register(const char *licenseKey)
Nicolas Capens264f1522015-01-09 17:21:17 -05008310{
8311 RegisterLicenseKey(licenseKey);
8312}
8313
8314}