1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // libGLES_CM.cpp: Implements the exported OpenGL ES 1.1 functions.
16
17 #include "main.h"
18 #include "mathutil.h"
19 #include "utilities.h"
20 #include "Buffer.h"
21 #include "Context.h"
22 #include "Framebuffer.h"
23 #include "Renderbuffer.h"
24 #include "Texture.h"
25 #include "common/debug.h"
26 #include "Common/SharedLibrary.hpp"
27 #include "Common/Version.h"
28
29 #include <EGL/egl.h>
30 #include <EGL/eglext.h>
31
32 #include <GLES/gl.h>
33 #include <GLES/glext.h>
34
35 #include <limits>
36
37 namespace es1
38 {
39
validImageSize(GLint level,GLsizei width,GLsizei height)40 static bool validImageSize(GLint level, GLsizei width, GLsizei height)
41 {
42 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
43 {
44 return false;
45 }
46
47 return true;
48 }
49
validateSubImageParams(bool compressed,GLsizei width,GLsizei height,GLint xoffset,GLint yoffset,GLenum target,GLint level,GLenum format,es1::Texture * texture)50 static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, es1::Texture *texture)
51 {
52 if(!texture)
53 {
54 return error(GL_INVALID_OPERATION, false);
55 }
56
57 if(compressed != texture->isCompressed(target, level))
58 {
59 return error(GL_INVALID_OPERATION, false);
60 }
61
62 if(format != GL_NONE_OES && format != texture->getFormat(target, level))
63 {
64 return error(GL_INVALID_OPERATION, false);
65 }
66
67 if(compressed)
68 {
69 if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
70 (height % 4 != 0 && height != texture->getHeight(target, 0)))
71 {
72 return error(GL_INVALID_OPERATION, false);
73 }
74 }
75
76 if(xoffset + width > texture->getWidth(target, level) ||
77 yoffset + height > texture->getHeight(target, level))
78 {
79 return error(GL_INVALID_VALUE, false);
80 }
81
82 return true;
83 }
84
ActiveTexture(GLenum texture)85 void ActiveTexture(GLenum texture)
86 {
87 TRACE("(GLenum texture = 0x%X)", texture);
88
89 es1::Context *context = es1::getContext();
90
91 if(context)
92 {
93 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es1::MAX_TEXTURE_UNITS - 1)
94 {
95 return error(GL_INVALID_ENUM);
96 }
97
98 context->setActiveSampler(texture - GL_TEXTURE0);
99 }
100 }
101
AlphaFunc(GLenum func,GLclampf ref)102 void AlphaFunc(GLenum func, GLclampf ref)
103 {
104 TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);
105
106 switch(func)
107 {
108 case GL_NEVER:
109 case GL_ALWAYS:
110 case GL_LESS:
111 case GL_LEQUAL:
112 case GL_EQUAL:
113 case GL_GEQUAL:
114 case GL_GREATER:
115 case GL_NOTEQUAL:
116 break;
117 default:
118 return error(GL_INVALID_ENUM);
119 }
120
121 es1::Context *context = es1::getContext();
122
123 if(context)
124 {
125 context->setAlphaFunc(func, clamp01(ref));
126 }
127 }
128
AlphaFuncx(GLenum func,GLclampx ref)129 void AlphaFuncx(GLenum func, GLclampx ref)
130 {
131 AlphaFunc(func, (float)ref / 0x10000);
132 }
133
BindBuffer(GLenum target,GLuint buffer)134 void BindBuffer(GLenum target, GLuint buffer)
135 {
136 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
137
138 es1::Context *context = es1::getContext();
139
140 if(context)
141 {
142 switch(target)
143 {
144 case GL_ARRAY_BUFFER:
145 context->bindArrayBuffer(buffer);
146 return;
147 case GL_ELEMENT_ARRAY_BUFFER:
148 context->bindElementArrayBuffer(buffer);
149 return;
150 default:
151 return error(GL_INVALID_ENUM);
152 }
153 }
154 }
155
BindFramebuffer(GLenum target,GLuint framebuffer)156 void BindFramebuffer(GLenum target, GLuint framebuffer)
157 {
158 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
159
160 if(target != GL_FRAMEBUFFER_OES)
161 {
162 return error(GL_INVALID_ENUM);
163 }
164
165 es1::Context *context = es1::getContext();
166
167 if(context)
168 {
169 context->bindFramebuffer(framebuffer);
170 }
171 }
172
BindFramebufferOES(GLenum target,GLuint framebuffer)173 void BindFramebufferOES(GLenum target, GLuint framebuffer)
174 {
175 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
176
177 if(target != GL_FRAMEBUFFER_OES)
178 {
179 return error(GL_INVALID_ENUM);
180 }
181
182 es1::Context *context = es1::getContext();
183
184 if(context)
185 {
186 context->bindFramebuffer(framebuffer);
187 }
188 }
189
BindRenderbufferOES(GLenum target,GLuint renderbuffer)190 void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
191 {
192 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
193
194 if(target != GL_RENDERBUFFER_OES)
195 {
196 return error(GL_INVALID_ENUM);
197 }
198
199 es1::Context *context = es1::getContext();
200
201 if(context)
202 {
203 if(renderbuffer != 0 && !context->getRenderbuffer(renderbuffer))
204 {
205 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
206 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
207 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
208 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
209 return error(GL_INVALID_OPERATION);
210 }
211
212 context->bindRenderbuffer(renderbuffer);
213 }
214 }
215
BindTexture(GLenum target,GLuint texture)216 void BindTexture(GLenum target, GLuint texture)
217 {
218 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
219
220 es1::Context *context = es1::getContext();
221
222 if(context)
223 {
224 es1::Texture *textureObject = context->getTexture(texture);
225
226 if(textureObject && textureObject->getTarget() != target && texture != 0)
227 {
228 return error(GL_INVALID_OPERATION);
229 }
230
231 switch(target)
232 {
233 case GL_TEXTURE_2D:
234 context->bindTexture2D(texture);
235 return;
236 case GL_TEXTURE_EXTERNAL_OES:
237 context->bindTextureExternal(texture);
238 return;
239 default:
240 return error(GL_INVALID_ENUM);
241 }
242 }
243 }
244
245 void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);
246
BlendEquationOES(GLenum mode)247 void BlendEquationOES(GLenum mode)
248 {
249 BlendEquationSeparateOES(mode, mode);
250 }
251
BlendEquationSeparateOES(GLenum modeRGB,GLenum modeAlpha)252 void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)
253 {
254 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
255
256 switch(modeRGB)
257 {
258 case GL_FUNC_ADD_OES:
259 case GL_FUNC_SUBTRACT_OES:
260 case GL_FUNC_REVERSE_SUBTRACT_OES:
261 case GL_MIN_EXT:
262 case GL_MAX_EXT:
263 break;
264 default:
265 return error(GL_INVALID_ENUM);
266 }
267
268 switch(modeAlpha)
269 {
270 case GL_FUNC_ADD_OES:
271 case GL_FUNC_SUBTRACT_OES:
272 case GL_FUNC_REVERSE_SUBTRACT_OES:
273 case GL_MIN_EXT:
274 case GL_MAX_EXT:
275 break;
276 default:
277 return error(GL_INVALID_ENUM);
278 }
279
280 es1::Context *context = es1::getContext();
281
282 if(context)
283 {
284 context->setBlendEquation(modeRGB, modeAlpha);
285 }
286 }
287
288 void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
289
BlendFunc(GLenum sfactor,GLenum dfactor)290 void BlendFunc(GLenum sfactor, GLenum dfactor)
291 {
292 BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor);
293 }
294
BlendFuncSeparateOES(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)295 void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
296 {
297 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
298 srcRGB, dstRGB, srcAlpha, dstAlpha);
299
300 switch(srcRGB)
301 {
302 case GL_ZERO:
303 case GL_ONE:
304 case GL_SRC_COLOR:
305 case GL_ONE_MINUS_SRC_COLOR:
306 case GL_DST_COLOR:
307 case GL_ONE_MINUS_DST_COLOR:
308 case GL_SRC_ALPHA:
309 case GL_ONE_MINUS_SRC_ALPHA:
310 case GL_DST_ALPHA:
311 case GL_ONE_MINUS_DST_ALPHA:
312 case GL_SRC_ALPHA_SATURATE:
313 break;
314 default:
315 return error(GL_INVALID_ENUM);
316 }
317
318 switch(dstRGB)
319 {
320 case GL_ZERO:
321 case GL_ONE:
322 case GL_SRC_COLOR:
323 case GL_ONE_MINUS_SRC_COLOR:
324 case GL_DST_COLOR:
325 case GL_ONE_MINUS_DST_COLOR:
326 case GL_SRC_ALPHA:
327 case GL_ONE_MINUS_SRC_ALPHA:
328 case GL_DST_ALPHA:
329 case GL_ONE_MINUS_DST_ALPHA:
330 break;
331 default:
332 return error(GL_INVALID_ENUM);
333 }
334
335 switch(srcAlpha)
336 {
337 case GL_ZERO:
338 case GL_ONE:
339 case GL_SRC_COLOR:
340 case GL_ONE_MINUS_SRC_COLOR:
341 case GL_DST_COLOR:
342 case GL_ONE_MINUS_DST_COLOR:
343 case GL_SRC_ALPHA:
344 case GL_ONE_MINUS_SRC_ALPHA:
345 case GL_DST_ALPHA:
346 case GL_ONE_MINUS_DST_ALPHA:
347 case GL_SRC_ALPHA_SATURATE:
348 break;
349 default:
350 return error(GL_INVALID_ENUM);
351 }
352
353 switch(dstAlpha)
354 {
355 case GL_ZERO:
356 case GL_ONE:
357 case GL_SRC_COLOR:
358 case GL_ONE_MINUS_SRC_COLOR:
359 case GL_DST_COLOR:
360 case GL_ONE_MINUS_DST_COLOR:
361 case GL_SRC_ALPHA:
362 case GL_ONE_MINUS_SRC_ALPHA:
363 case GL_DST_ALPHA:
364 case GL_ONE_MINUS_DST_ALPHA:
365 break;
366 default:
367 return error(GL_INVALID_ENUM);
368 }
369
370 es1::Context *context = es1::getContext();
371
372 if(context)
373 {
374 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
375 }
376 }
377
BufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)378 void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
379 {
380 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
381
382 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
383 target, size, data, usage);
384
385 if(size < 0)
386 {
387 return error(GL_INVALID_VALUE);
388 }
389
390 switch(usage)
391 {
392 case GL_STATIC_DRAW:
393 case GL_DYNAMIC_DRAW:
394 break;
395 default:
396 return error(GL_INVALID_ENUM);
397 }
398
399 es1::Context *context = es1::getContext();
400
401 if(context)
402 {
403 es1::Buffer *buffer;
404
405 switch(target)
406 {
407 case GL_ARRAY_BUFFER:
408 buffer = context->getArrayBuffer();
409 break;
410 case GL_ELEMENT_ARRAY_BUFFER:
411 buffer = context->getElementArrayBuffer();
412 break;
413 default:
414 return error(GL_INVALID_ENUM);
415 }
416
417 if(!buffer)
418 {
419 return error(GL_INVALID_OPERATION);
420 }
421
422 buffer->bufferData(data, size, usage);
423 }
424 }
425
BufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)426 void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
427 {
428 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
429 offset = static_cast<GLint>(offset);
430
431 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
432 target, offset, size, data);
433
434 if(size < 0 || offset < 0)
435 {
436 return error(GL_INVALID_VALUE);
437 }
438
439 if(!data)
440 {
441 return;
442 }
443
444 es1::Context *context = es1::getContext();
445
446 if(context)
447 {
448 es1::Buffer *buffer;
449
450 switch(target)
451 {
452 case GL_ARRAY_BUFFER:
453 buffer = context->getArrayBuffer();
454 break;
455 case GL_ELEMENT_ARRAY_BUFFER:
456 buffer = context->getElementArrayBuffer();
457 break;
458 default:
459 return error(GL_INVALID_ENUM);
460 }
461
462 if(!buffer)
463 {
464 return error(GL_INVALID_OPERATION);
465 }
466
467 if((size_t)size + offset > buffer->size())
468 {
469 return error(GL_INVALID_VALUE);
470 }
471
472 buffer->bufferSubData(data, size, offset);
473 }
474 }
475
CheckFramebufferStatusOES(GLenum target)476 GLenum CheckFramebufferStatusOES(GLenum target)
477 {
478 TRACE("(GLenum target = 0x%X)", target);
479
480 if(target != GL_FRAMEBUFFER_OES)
481 {
482 return error(GL_INVALID_ENUM, 0);
483 }
484
485 es1::Context *context = es1::getContext();
486
487 if(context)
488 {
489 es1::Framebuffer *framebuffer = context->getFramebuffer();
490
491 return framebuffer->completeness();
492 }
493
494 return 0;
495 }
496
Clear(GLbitfield mask)497 void Clear(GLbitfield mask)
498 {
499 TRACE("(GLbitfield mask = %X)", mask);
500
501 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
502 {
503 return error(GL_INVALID_VALUE);
504 }
505
506 es1::Context *context = es1::getContext();
507
508 if(context)
509 {
510 context->clear(mask);
511 }
512 }
513
ClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)514 void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
515 {
516 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
517 red, green, blue, alpha);
518
519 es1::Context *context = es1::getContext();
520
521 if(context)
522 {
523 context->setClearColor(red, green, blue, alpha);
524 }
525 }
526
ClearColorx(GLclampx red,GLclampx green,GLclampx blue,GLclampx alpha)527 void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
528 {
529 ClearColor((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);
530 }
531
ClearDepthf(GLclampf depth)532 void ClearDepthf(GLclampf depth)
533 {
534 TRACE("(GLclampf depth = %f)", depth);
535
536 es1::Context *context = es1::getContext();
537
538 if(context)
539 {
540 context->setClearDepth(depth);
541 }
542 }
543
ClearDepthx(GLclampx depth)544 void ClearDepthx(GLclampx depth)
545 {
546 ClearDepthf((float)depth / 0x10000);
547 }
548
ClearStencil(GLint s)549 void ClearStencil(GLint s)
550 {
551 TRACE("(GLint s = %d)", s);
552
553 es1::Context *context = es1::getContext();
554
555 if(context)
556 {
557 context->setClearStencil(s);
558 }
559 }
560
ClientActiveTexture(GLenum texture)561 void ClientActiveTexture(GLenum texture)
562 {
563 TRACE("(GLenum texture = 0x%X)", texture);
564
565 switch(texture)
566 {
567 case GL_TEXTURE0:
568 case GL_TEXTURE1:
569 break;
570 default:
571 return error(GL_INVALID_ENUM);
572 }
573
574 es1::Context *context = es1::getContext();
575
576 if(context)
577 {
578 context->clientActiveTexture(texture);
579 }
580 }
581
ClipPlanef(GLenum plane,const GLfloat * equation)582 void ClipPlanef(GLenum plane, const GLfloat *equation)
583 {
584 TRACE("(GLenum plane = 0x%X, const GLfloat *equation)", plane);
585
586 int index = plane - GL_CLIP_PLANE0;
587
588 if(index < 0 || index >= MAX_CLIP_PLANES)
589 {
590 return error(GL_INVALID_ENUM);
591 }
592
593 es1::Context *context = es1::getContext();
594
595 if(context)
596 {
597 context->setClipPlane(index, equation);
598 }
599 }
600
ClipPlanex(GLenum plane,const GLfixed * equation)601 void ClipPlanex(GLenum plane, const GLfixed *equation)
602 {
603 GLfloat equationf[4] =
604 {
605 (float)equation[0] / 0x10000,
606 (float)equation[1] / 0x10000,
607 (float)equation[2] / 0x10000,
608 (float)equation[3] / 0x10000,
609 };
610
611 ClipPlanef(plane, equationf);
612 }
613
Color4f(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)614 void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
615 {
616 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);
617
618 es1::Context *context = es1::getContext();
619
620 if(context)
621 {
622 context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
623 }
624 }
625
Color4ub(GLubyte red,GLubyte green,GLubyte blue,GLubyte alpha)626 void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
627 {
628 Color4f((float)red / 0xFF, (float)green / 0xFF, (float)blue / 0xFF, (float)alpha / 0xFF);
629 }
630
Color4x(GLfixed red,GLfixed green,GLfixed blue,GLfixed alpha)631 void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
632 {
633 Color4f((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);
634 }
635
ColorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)636 void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
637 {
638 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
639 red, green, blue, alpha);
640
641 es1::Context *context = es1::getContext();
642
643 if(context)
644 {
645 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
646 }
647 }
648
VertexAttribPointer(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)649 void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
650 {
651 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
652 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
653 index, size, type, normalized, stride, ptr);
654
655 if(index >= es1::MAX_VERTEX_ATTRIBS)
656 {
657 return error(GL_INVALID_VALUE);
658 }
659
660 if(size < 1 || size > 4)
661 {
662 return error(GL_INVALID_VALUE);
663 }
664
665 switch(type)
666 {
667 case GL_BYTE:
668 case GL_UNSIGNED_BYTE:
669 case GL_SHORT:
670 case GL_UNSIGNED_SHORT:
671 case GL_FIXED:
672 case GL_FLOAT:
673 break;
674 default:
675 return error(GL_INVALID_ENUM);
676 }
677
678 if(stride < 0)
679 {
680 return error(GL_INVALID_VALUE);
681 }
682
683 es1::Context *context = es1::getContext();
684
685 if(context)
686 {
687 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
688 }
689 }
690
ColorPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)691 void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
692 {
693 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
694
695 if(size != 4)
696 {
697 return error(GL_INVALID_VALUE);
698 }
699
700 VertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
701 }
702
CompressedTexImage2D(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)703 void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
704 GLint border, GLsizei imageSize, const GLvoid* data)
705 {
706 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
707 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
708 target, level, internalformat, width, height, border, imageSize, data);
709
710 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
711 {
712 return error(GL_INVALID_VALUE);
713 }
714
715 if(!validImageSize(level, width, height) || imageSize < 0)
716 {
717 return error(GL_INVALID_VALUE);
718 }
719
720 switch(internalformat)
721 {
722 case GL_ETC1_RGB8_OES:
723 break;
724 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
725 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
726 if(!S3TC_SUPPORT)
727 {
728 return error(GL_INVALID_ENUM);
729 }
730 break;
731 case GL_DEPTH_COMPONENT16_OES:
732 case GL_DEPTH_COMPONENT32_OES:
733 case GL_DEPTH_STENCIL_OES:
734 case GL_DEPTH24_STENCIL8_OES:
735 return error(GL_INVALID_OPERATION);
736 default:
737 return error(GL_INVALID_ENUM);
738 }
739
740 if(border != 0)
741 {
742 return error(GL_INVALID_VALUE);
743 }
744
745 es1::Context *context = es1::getContext();
746
747 if(context)
748 {
749 switch(target)
750 {
751 case GL_TEXTURE_2D:
752 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
753 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
754 {
755 return error(GL_INVALID_VALUE);
756 }
757 break;
758 default:
759 return error(GL_INVALID_ENUM);
760 }
761
762 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))
763 {
764 return error(GL_INVALID_VALUE);
765 }
766
767 if(target == GL_TEXTURE_2D)
768 {
769 es1::Texture2D *texture = context->getTexture2D();
770
771 if(!texture)
772 {
773 return error(GL_INVALID_OPERATION);
774 }
775
776 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
777 }
778 else UNREACHABLE(target);
779 }
780 }
781
CompressedTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)782 void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
783 GLenum format, GLsizei imageSize, const GLvoid* data)
784 {
785 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
786 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
787 "GLsizei imageSize = %d, const GLvoid* data = %p)",
788 target, level, xoffset, yoffset, width, height, format, imageSize, data);
789
790 if(!es1::IsTextureTarget(target))
791 {
792 return error(GL_INVALID_ENUM);
793 }
794
795 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
796 {
797 return error(GL_INVALID_VALUE);
798 }
799
800 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
801 {
802 return error(GL_INVALID_VALUE);
803 }
804
805 switch(format)
806 {
807 case GL_ETC1_RGB8_OES:
808 break;
809 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
810 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
811 if(!S3TC_SUPPORT)
812 {
813 return error(GL_INVALID_ENUM);
814 }
815 break;
816 default:
817 return error(GL_INVALID_ENUM);
818 }
819
820 if(width == 0 || height == 0 || !data)
821 {
822 return;
823 }
824
825 es1::Context *context = es1::getContext();
826
827 if(context)
828 {
829 if(imageSize != egl::ComputeCompressedSize(width, height, format))
830 {
831 return error(GL_INVALID_VALUE);
832 }
833
834 if(xoffset % 4 != 0 || yoffset % 4 != 0)
835 {
836 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
837 return error(GL_INVALID_OPERATION);
838 }
839
840 if(target == GL_TEXTURE_2D)
841 {
842 es1::Texture2D *texture = context->getTexture2D();
843
844 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
845 {
846 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
847 }
848 }
849 else UNREACHABLE(target);
850 }
851 }
852
CopyTexImage2D(GLenum target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)853 void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
854 {
855 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
856 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
857 target, level, internalformat, x, y, width, height, border);
858
859 if(!validImageSize(level, width, height))
860 {
861 return error(GL_INVALID_VALUE);
862 }
863
864 if(border != 0)
865 {
866 return error(GL_INVALID_VALUE);
867 }
868
869 es1::Context *context = es1::getContext();
870
871 if(context)
872 {
873 switch(target)
874 {
875 case GL_TEXTURE_2D:
876 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
877 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
878 {
879 return error(GL_INVALID_VALUE);
880 }
881 break;
882 default:
883 return error(GL_INVALID_ENUM);
884 }
885
886 es1::Framebuffer *framebuffer = context->getFramebuffer();
887
888 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)
889 {
890 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
891 }
892
893 if(context->getFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
894 {
895 return error(GL_INVALID_OPERATION);
896 }
897
898 es1::Renderbuffer *source = framebuffer->getColorbuffer();
899 GLenum colorbufferFormat = source->getFormat();
900
901 // [OpenGL ES 2.0.24] table 3.9
902 switch(internalformat)
903 {
904 case GL_ALPHA:
905 if(colorbufferFormat != GL_ALPHA &&
906 colorbufferFormat != GL_RGBA &&
907 colorbufferFormat != GL_RGBA4_OES &&
908 colorbufferFormat != GL_RGB5_A1_OES &&
909 colorbufferFormat != GL_RGBA8_OES)
910 {
911 return error(GL_INVALID_OPERATION);
912 }
913 break;
914 case GL_LUMINANCE:
915 case GL_RGB:
916 if(colorbufferFormat != GL_RGB &&
917 colorbufferFormat != GL_RGB565_OES &&
918 colorbufferFormat != GL_RGB8_OES &&
919 colorbufferFormat != GL_RGBA &&
920 colorbufferFormat != GL_RGBA4_OES &&
921 colorbufferFormat != GL_RGB5_A1_OES &&
922 colorbufferFormat != GL_RGBA8_OES)
923 {
924 return error(GL_INVALID_OPERATION);
925 }
926 break;
927 case GL_LUMINANCE_ALPHA:
928 case GL_RGBA:
929 if(colorbufferFormat != GL_RGBA &&
930 colorbufferFormat != GL_RGBA4_OES &&
931 colorbufferFormat != GL_RGB5_A1_OES &&
932 colorbufferFormat != GL_RGBA8_OES)
933 {
934 return error(GL_INVALID_OPERATION);
935 }
936 break;
937 case GL_ETC1_RGB8_OES:
938 return error(GL_INVALID_OPERATION);
939 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
940 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
941 if(S3TC_SUPPORT)
942 {
943 return error(GL_INVALID_OPERATION);
944 }
945 else
946 {
947 return error(GL_INVALID_ENUM);
948 }
949 default:
950 return error(GL_INVALID_ENUM);
951 }
952
953 if(target == GL_TEXTURE_2D)
954 {
955 es1::Texture2D *texture = context->getTexture2D();
956
957 if(!texture)
958 {
959 return error(GL_INVALID_OPERATION);
960 }
961
962 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
963 }
964 else UNREACHABLE(target);
965 }
966 }
967
CopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)968 void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
969 {
970 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
971 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
972 target, level, xoffset, yoffset, x, y, width, height);
973
974 if(!es1::IsTextureTarget(target))
975 {
976 return error(GL_INVALID_ENUM);
977 }
978
979 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
980 {
981 return error(GL_INVALID_VALUE);
982 }
983
984 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
985 {
986 return error(GL_INVALID_VALUE);
987 }
988
989 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
990 {
991 return error(GL_INVALID_VALUE);
992 }
993
994 if(width == 0 || height == 0)
995 {
996 return;
997 }
998
999 es1::Context *context = es1::getContext();
1000
1001 if(context)
1002 {
1003
1004 es1::Framebuffer *framebuffer = context->getFramebuffer();
1005
1006 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)
1007 {
1008 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
1009 }
1010
1011 es1::Renderbuffer *source = framebuffer->getColorbuffer();
1012
1013 if(context->getFramebufferName() != 0 && (!source || source->getSamples() > 1))
1014 {
1015 return error(GL_INVALID_OPERATION);
1016 }
1017
1018 es1::Texture *texture = nullptr;
1019
1020 if(target == GL_TEXTURE_2D)
1021 {
1022 texture = context->getTexture2D();
1023 }
1024 else UNREACHABLE(target);
1025
1026 if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE_OES, texture))
1027 {
1028 return;
1029 }
1030
1031 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
1032 }
1033 }
1034
CullFace(GLenum mode)1035 void CullFace(GLenum mode)
1036 {
1037 TRACE("(GLenum mode = 0x%X)", mode);
1038
1039 switch(mode)
1040 {
1041 case GL_FRONT:
1042 case GL_BACK:
1043 case GL_FRONT_AND_BACK:
1044 {
1045 es1::Context *context = es1::getContext();
1046
1047 if(context)
1048 {
1049 context->setCullMode(mode);
1050 }
1051 }
1052 break;
1053 default:
1054 return error(GL_INVALID_ENUM);
1055 }
1056 }
1057
DeleteBuffers(GLsizei n,const GLuint * buffers)1058 void DeleteBuffers(GLsizei n, const GLuint* buffers)
1059 {
1060 TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
1061
1062 if(n < 0)
1063 {
1064 return error(GL_INVALID_VALUE);
1065 }
1066
1067 es1::Context *context = es1::getContext();
1068
1069 if(context)
1070 {
1071 for(int i = 0; i < n; i++)
1072 {
1073 context->deleteBuffer(buffers[i]);
1074 }
1075 }
1076 }
1077
DeleteFramebuffersOES(GLsizei n,const GLuint * framebuffers)1078 void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
1079 {
1080 TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
1081
1082 if(n < 0)
1083 {
1084 return error(GL_INVALID_VALUE);
1085 }
1086
1087 es1::Context *context = es1::getContext();
1088
1089 if(context)
1090 {
1091 for(int i = 0; i < n; i++)
1092 {
1093 if(framebuffers[i] != 0)
1094 {
1095 context->deleteFramebuffer(framebuffers[i]);
1096 }
1097 }
1098 }
1099 }
1100
DeleteRenderbuffersOES(GLsizei n,const GLuint * renderbuffers)1101 void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
1102 {
1103 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
1104
1105 if(n < 0)
1106 {
1107 return error(GL_INVALID_VALUE);
1108 }
1109
1110 es1::Context *context = es1::getContext();
1111
1112 if(context)
1113 {
1114 for(int i = 0; i < n; i++)
1115 {
1116 context->deleteRenderbuffer(renderbuffers[i]);
1117 }
1118 }
1119 }
1120
DeleteTextures(GLsizei n,const GLuint * textures)1121 void DeleteTextures(GLsizei n, const GLuint* textures)
1122 {
1123 TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
1124
1125 if(n < 0)
1126 {
1127 return error(GL_INVALID_VALUE);
1128 }
1129
1130 es1::Context *context = es1::getContext();
1131
1132 if(context)
1133 {
1134 for(int i = 0; i < n; i++)
1135 {
1136 if(textures[i] != 0)
1137 {
1138 context->deleteTexture(textures[i]);
1139 }
1140 }
1141 }
1142 }
1143
DepthFunc(GLenum func)1144 void DepthFunc(GLenum func)
1145 {
1146 TRACE("(GLenum func = 0x%X)", func);
1147
1148 switch(func)
1149 {
1150 case GL_NEVER:
1151 case GL_ALWAYS:
1152 case GL_LESS:
1153 case GL_LEQUAL:
1154 case GL_EQUAL:
1155 case GL_GREATER:
1156 case GL_GEQUAL:
1157 case GL_NOTEQUAL:
1158 break;
1159 default:
1160 return error(GL_INVALID_ENUM);
1161 }
1162
1163 es1::Context *context = es1::getContext();
1164
1165 if(context)
1166 {
1167 context->setDepthFunc(func);
1168 }
1169 }
1170
DepthMask(GLboolean flag)1171 void DepthMask(GLboolean flag)
1172 {
1173 TRACE("(GLboolean flag = %d)", flag);
1174
1175 es1::Context *context = es1::getContext();
1176
1177 if(context)
1178 {
1179 context->setDepthMask(flag != GL_FALSE);
1180 }
1181 }
1182
DepthRangef(GLclampf zNear,GLclampf zFar)1183 void DepthRangef(GLclampf zNear, GLclampf zFar)
1184 {
1185 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
1186
1187 es1::Context *context = es1::getContext();
1188
1189 if(context)
1190 {
1191 context->setDepthRange(zNear, zFar);
1192 }
1193 }
1194
DepthRangex(GLclampx zNear,GLclampx zFar)1195 void DepthRangex(GLclampx zNear, GLclampx zFar)
1196 {
1197 DepthRangef((float)zNear / 0x10000, (float)zFar / 0x10000);
1198 }
1199
Disable(GLenum cap)1200 void Disable(GLenum cap)
1201 {
1202 TRACE("(GLenum cap = 0x%X)", cap);
1203
1204 es1::Context *context = es1::getContext();
1205
1206 if(context)
1207 {
1208 switch(cap)
1209 {
1210 case GL_CULL_FACE: context->setCullFaceEnabled(false); break;
1211 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(false); break;
1212 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break;
1213 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(false); break;
1214 case GL_SCISSOR_TEST: context->setScissorTestEnabled(false); break;
1215 case GL_STENCIL_TEST: context->setStencilTestEnabled(false); break;
1216 case GL_DEPTH_TEST: context->setDepthTestEnabled(false); break;
1217 case GL_BLEND: context->setBlendEnabled(false); break;
1218 case GL_DITHER: context->setDitherEnabled(false); break;
1219 case GL_LIGHTING: context->setLightingEnabled(false); break;
1220 case GL_LIGHT0: context->setLightEnabled(0, false); break;
1221 case GL_LIGHT1: context->setLightEnabled(1, false); break;
1222 case GL_LIGHT2: context->setLightEnabled(2, false); break;
1223 case GL_LIGHT3: context->setLightEnabled(3, false); break;
1224 case GL_LIGHT4: context->setLightEnabled(4, false); break;
1225 case GL_LIGHT5: context->setLightEnabled(5, false); break;
1226 case GL_LIGHT6: context->setLightEnabled(6, false); break;
1227 case GL_LIGHT7: context->setLightEnabled(7, false); break;
1228 case GL_FOG: context->setFogEnabled(false); break;
1229 case GL_TEXTURE_2D: context->setTexture2Denabled(false); break;
1230 case GL_TEXTURE_EXTERNAL_OES: context->setTextureExternalEnabled(false); break;
1231 case GL_ALPHA_TEST: context->setAlphaTestEnabled(false); break;
1232 case GL_COLOR_LOGIC_OP: context->setColorLogicOpEnabled(false); break;
1233 case GL_POINT_SMOOTH: context->setPointSmoothEnabled(false); break;
1234 case GL_LINE_SMOOTH: context->setLineSmoothEnabled(false); break;
1235 case GL_COLOR_MATERIAL: context->setColorMaterialEnabled(false); break;
1236 case GL_NORMALIZE: context->setNormalizeEnabled(false); break;
1237 case GL_RESCALE_NORMAL: context->setRescaleNormalEnabled(false); break;
1238 case GL_VERTEX_ARRAY: context->setVertexArrayEnabled(false); break;
1239 case GL_NORMAL_ARRAY: context->setNormalArrayEnabled(false); break;
1240 case GL_COLOR_ARRAY: context->setColorArrayEnabled(false); break;
1241 case GL_POINT_SIZE_ARRAY_OES: context->setPointSizeArrayEnabled(false); break;
1242 case GL_TEXTURE_COORD_ARRAY: context->setTextureCoordArrayEnabled(false); break;
1243 case GL_MULTISAMPLE: context->setMultisampleEnabled(false); break;
1244 case GL_SAMPLE_ALPHA_TO_ONE: context->setSampleAlphaToOneEnabled(false); break;
1245 case GL_CLIP_PLANE0: context->setClipPlaneEnabled(0, false); break;
1246 case GL_CLIP_PLANE1: context->setClipPlaneEnabled(1, false); break;
1247 case GL_CLIP_PLANE2: context->setClipPlaneEnabled(2, false); break;
1248 case GL_CLIP_PLANE3: context->setClipPlaneEnabled(3, false); break;
1249 case GL_CLIP_PLANE4: context->setClipPlaneEnabled(4, false); break;
1250 case GL_CLIP_PLANE5: context->setClipPlaneEnabled(5, false); break;
1251 case GL_POINT_SPRITE_OES: context->setPointSpriteEnabled(false); break;
1252 default:
1253 return error(GL_INVALID_ENUM);
1254 }
1255 }
1256 }
1257
DisableClientState(GLenum array)1258 void DisableClientState(GLenum array)
1259 {
1260 TRACE("(GLenum array = 0x%X)", array);
1261
1262 switch(array)
1263 {
1264 case GL_VERTEX_ARRAY:
1265 case GL_NORMAL_ARRAY:
1266 case GL_COLOR_ARRAY:
1267 case GL_POINT_SIZE_ARRAY_OES:
1268 case GL_TEXTURE_COORD_ARRAY:
1269 break;
1270 default:
1271 return error(GL_INVALID_ENUM);
1272 }
1273
1274 es1::Context *context = es1::getContext();
1275
1276 if(context)
1277 {
1278 GLenum texture = context->getClientActiveTexture();
1279
1280 switch(array)
1281 {
1282 case GL_VERTEX_ARRAY: context->setVertexAttribArrayEnabled(sw::Position, false); break;
1283 case GL_NORMAL_ARRAY: context->setVertexAttribArrayEnabled(sw::Normal, false); break;
1284 case GL_COLOR_ARRAY: context->setVertexAttribArrayEnabled(sw::Color0, false); break;
1285 case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, false); break;
1286 case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
1287 default: UNREACHABLE(array);
1288 }
1289 }
1290 }
1291
DrawArrays(GLenum mode,GLint first,GLsizei count)1292 void DrawArrays(GLenum mode, GLint first, GLsizei count)
1293 {
1294 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
1295
1296 if(count < 0 || first < 0)
1297 {
1298 return error(GL_INVALID_VALUE);
1299 }
1300
1301 es1::Context *context = es1::getContext();
1302
1303 if(context)
1304 {
1305 context->drawArrays(mode, first, count);
1306 }
1307 }
1308
DrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1309 void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
1310 {
1311 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
1312 mode, count, type, indices);
1313
1314 if(count < 0)
1315 {
1316 return error(GL_INVALID_VALUE);
1317 }
1318
1319 es1::Context *context = es1::getContext();
1320
1321 if(context)
1322 {
1323 switch(type)
1324 {
1325 case GL_UNSIGNED_BYTE:
1326 case GL_UNSIGNED_SHORT:
1327 case GL_UNSIGNED_INT:
1328 break;
1329 default:
1330 return error(GL_INVALID_ENUM);
1331 }
1332
1333 context->drawElements(mode, count, type, indices);
1334 }
1335 }
1336
Enable(GLenum cap)1337 void Enable(GLenum cap)
1338 {
1339 TRACE("(GLenum cap = 0x%X)", cap);
1340
1341 es1::Context *context = es1::getContext();
1342
1343 if(context)
1344 {
1345 switch(cap)
1346 {
1347 case GL_CULL_FACE: context->setCullFaceEnabled(true); break;
1348 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(true); break;
1349 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break;
1350 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(true); break;
1351 case GL_SCISSOR_TEST: context->setScissorTestEnabled(true); break;
1352 case GL_STENCIL_TEST: context->setStencilTestEnabled(true); break;
1353 case GL_DEPTH_TEST: context->setDepthTestEnabled(true); break;
1354 case GL_BLEND: context->setBlendEnabled(true); break;
1355 case GL_DITHER: context->setDitherEnabled(true); break;
1356 case GL_LIGHTING: context->setLightingEnabled(true); break;
1357 case GL_LIGHT0: context->setLightEnabled(0, true); break;
1358 case GL_LIGHT1: context->setLightEnabled(1, true); break;
1359 case GL_LIGHT2: context->setLightEnabled(2, true); break;
1360 case GL_LIGHT3: context->setLightEnabled(3, true); break;
1361 case GL_LIGHT4: context->setLightEnabled(4, true); break;
1362 case GL_LIGHT5: context->setLightEnabled(5, true); break;
1363 case GL_LIGHT6: context->setLightEnabled(6, true); break;
1364 case GL_LIGHT7: context->setLightEnabled(7, true); break;
1365 case GL_FOG: context->setFogEnabled(true); break;
1366 case GL_TEXTURE_2D: context->setTexture2Denabled(true); break;
1367 case GL_TEXTURE_EXTERNAL_OES: context->setTextureExternalEnabled(true); break;
1368 case GL_ALPHA_TEST: context->setAlphaTestEnabled(true); break;
1369 case GL_COLOR_LOGIC_OP: context->setColorLogicOpEnabled(true); break;
1370 case GL_POINT_SMOOTH: context->setPointSmoothEnabled(true); break;
1371 case GL_LINE_SMOOTH: context->setLineSmoothEnabled(true); break;
1372 case GL_COLOR_MATERIAL: context->setColorMaterialEnabled(true); break;
1373 case GL_NORMALIZE: context->setNormalizeEnabled(true); break;
1374 case GL_RESCALE_NORMAL: context->setRescaleNormalEnabled(true); break;
1375 case GL_VERTEX_ARRAY: context->setVertexArrayEnabled(true); break;
1376 case GL_NORMAL_ARRAY: context->setNormalArrayEnabled(true); break;
1377 case GL_COLOR_ARRAY: context->setColorArrayEnabled(true); break;
1378 case GL_POINT_SIZE_ARRAY_OES: context->setPointSizeArrayEnabled(true); break;
1379 case GL_TEXTURE_COORD_ARRAY: context->setTextureCoordArrayEnabled(true); break;
1380 case GL_MULTISAMPLE: context->setMultisampleEnabled(true); break;
1381 case GL_SAMPLE_ALPHA_TO_ONE: context->setSampleAlphaToOneEnabled(true); break;
1382 case GL_CLIP_PLANE0: context->setClipPlaneEnabled(0, true); break;
1383 case GL_CLIP_PLANE1: context->setClipPlaneEnabled(1, true); break;
1384 case GL_CLIP_PLANE2: context->setClipPlaneEnabled(2, true); break;
1385 case GL_CLIP_PLANE3: context->setClipPlaneEnabled(3, true); break;
1386 case GL_CLIP_PLANE4: context->setClipPlaneEnabled(4, true); break;
1387 case GL_CLIP_PLANE5: context->setClipPlaneEnabled(5, true); break;
1388 case GL_POINT_SPRITE_OES: context->setPointSpriteEnabled(true); break;
1389 default:
1390 return error(GL_INVALID_ENUM);
1391 }
1392 }
1393 }
1394
EnableClientState(GLenum array)1395 void EnableClientState(GLenum array)
1396 {
1397 TRACE("(GLenum array = 0x%X)", array);
1398
1399 switch(array)
1400 {
1401 case GL_VERTEX_ARRAY:
1402 case GL_NORMAL_ARRAY:
1403 case GL_COLOR_ARRAY:
1404 case GL_POINT_SIZE_ARRAY_OES:
1405 case GL_TEXTURE_COORD_ARRAY:
1406 break;
1407 default:
1408 return error(GL_INVALID_ENUM);
1409 }
1410
1411 es1::Context *context = es1::getContext();
1412
1413 if(context)
1414 {
1415 GLenum texture = context->getClientActiveTexture();
1416
1417 switch(array)
1418 {
1419 case GL_VERTEX_ARRAY: context->setVertexAttribArrayEnabled(sw::Position, true); break;
1420 case GL_NORMAL_ARRAY: context->setVertexAttribArrayEnabled(sw::Normal, true); break;
1421 case GL_COLOR_ARRAY: context->setVertexAttribArrayEnabled(sw::Color0, true); break;
1422 case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, true); break;
1423 case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
1424 default: UNREACHABLE(array);
1425 }
1426 }
1427 }
1428
Finish(void)1429 void Finish(void)
1430 {
1431 TRACE("()");
1432
1433 es1::Context *context = es1::getContext();
1434
1435 if(context)
1436 {
1437 context->finish();
1438 }
1439 }
1440
Flush(void)1441 void Flush(void)
1442 {
1443 TRACE("()");
1444
1445 es1::Context *context = es1::getContext();
1446
1447 if(context)
1448 {
1449 context->flush();
1450 }
1451 }
1452
FramebufferRenderbufferOES(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)1453 void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1454 {
1455 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1456 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
1457
1458 if(target != GL_FRAMEBUFFER_OES || (renderbuffertarget != GL_RENDERBUFFER_OES && renderbuffer != 0))
1459 {
1460 return error(GL_INVALID_ENUM);
1461 }
1462
1463 es1::Context *context = es1::getContext();
1464
1465 if(context)
1466 {
1467 es1::Framebuffer *framebuffer = context->getFramebuffer();
1468 GLuint framebufferName = context->getFramebufferName();
1469
1470 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
1471 {
1472 return error(GL_INVALID_OPERATION);
1473 }
1474
1475 switch(attachment)
1476 {
1477 case GL_COLOR_ATTACHMENT0_OES:
1478 framebuffer->setColorbuffer(GL_RENDERBUFFER_OES, renderbuffer);
1479 break;
1480 case GL_DEPTH_ATTACHMENT_OES:
1481 framebuffer->setDepthbuffer(GL_RENDERBUFFER_OES, renderbuffer);
1482 break;
1483 case GL_STENCIL_ATTACHMENT_OES:
1484 framebuffer->setStencilbuffer(GL_RENDERBUFFER_OES, renderbuffer);
1485 break;
1486 default:
1487 return error(GL_INVALID_ENUM);
1488 }
1489 }
1490 }
1491
FramebufferTexture2DOES(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)1492 void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1493 {
1494 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1495 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
1496
1497 if(target != GL_FRAMEBUFFER_OES)
1498 {
1499 return error(GL_INVALID_ENUM);
1500 }
1501
1502 switch(attachment)
1503 {
1504 case GL_COLOR_ATTACHMENT0_OES:
1505 case GL_DEPTH_ATTACHMENT_OES:
1506 case GL_STENCIL_ATTACHMENT_OES:
1507 break;
1508 default:
1509 return error(GL_INVALID_ENUM);
1510 }
1511
1512 es1::Context *context = es1::getContext();
1513
1514 if(context)
1515 {
1516 if(texture == 0)
1517 {
1518 textarget = GL_NONE_OES;
1519 }
1520 else
1521 {
1522 es1::Texture *tex = context->getTexture(texture);
1523
1524 if(!tex)
1525 {
1526 return error(GL_INVALID_OPERATION);
1527 }
1528
1529 switch(textarget)
1530 {
1531 case GL_TEXTURE_2D:
1532 if(tex->getTarget() != GL_TEXTURE_2D)
1533 {
1534 return error(GL_INVALID_OPERATION);
1535 }
1536 break;
1537 default:
1538 return error(GL_INVALID_ENUM);
1539 }
1540
1541 if(level != 0)
1542 {
1543 return error(GL_INVALID_VALUE);
1544 }
1545
1546 if(tex->isCompressed(textarget, level))
1547 {
1548 return error(GL_INVALID_OPERATION);
1549 }
1550 }
1551
1552 es1::Framebuffer *framebuffer = context->getFramebuffer();
1553 GLuint framebufferName = context->getFramebufferName();
1554
1555 if(framebufferName == 0 || !framebuffer)
1556 {
1557 return error(GL_INVALID_OPERATION);
1558 }
1559
1560 switch(attachment)
1561 {
1562 case GL_COLOR_ATTACHMENT0_OES: framebuffer->setColorbuffer(textarget, texture); break;
1563 case GL_DEPTH_ATTACHMENT_OES: framebuffer->setDepthbuffer(textarget, texture); break;
1564 case GL_STENCIL_ATTACHMENT_OES: framebuffer->setStencilbuffer(textarget, texture); break;
1565 }
1566 }
1567 }
1568
Fogf(GLenum pname,GLfloat param)1569 void Fogf(GLenum pname, GLfloat param)
1570 {
1571 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
1572
1573 es1::Context *context = es1::getContext();
1574
1575 if(context)
1576 {
1577 switch(pname)
1578 {
1579 case GL_FOG_MODE:
1580 switch((GLenum)param)
1581 {
1582 case GL_LINEAR:
1583 case GL_EXP:
1584 case GL_EXP2:
1585 context->setFogMode((GLenum)param);
1586 break;
1587 default:
1588 return error(GL_INVALID_ENUM);
1589 }
1590 break;
1591 case GL_FOG_DENSITY:
1592 if(param < 0)
1593 {
1594 return error(GL_INVALID_VALUE);
1595 }
1596 context->setFogDensity(param);
1597 break;
1598 case GL_FOG_START:
1599 context->setFogStart(param);
1600 break;
1601 case GL_FOG_END:
1602 context->setFogEnd(param);
1603 break;
1604 case GL_FOG_COLOR:
1605 return error(GL_INVALID_ENUM); // Need four values, should call glFogfv() instead
1606 default:
1607 return error(GL_INVALID_ENUM);
1608 }
1609 }
1610 }
1611
Fogfv(GLenum pname,const GLfloat * params)1612 void Fogfv(GLenum pname, const GLfloat *params)
1613 {
1614 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
1615
1616 es1::Context *context = es1::getContext();
1617
1618 if(context)
1619 {
1620 switch(pname)
1621 {
1622 case GL_FOG_MODE:
1623 switch((GLenum)params[0])
1624 {
1625 case GL_LINEAR:
1626 case GL_EXP:
1627 case GL_EXP2:
1628 context->setFogMode((GLenum)params[0]);
1629 break;
1630 default:
1631 return error(GL_INVALID_ENUM);
1632 }
1633 break;
1634 case GL_FOG_DENSITY:
1635 if(params[0] < 0)
1636 {
1637 return error(GL_INVALID_VALUE);
1638 }
1639 context->setFogDensity(params[0]);
1640 break;
1641 case GL_FOG_START:
1642 context->setFogStart(params[0]);
1643 break;
1644 case GL_FOG_END:
1645 context->setFogEnd(params[0]);
1646 break;
1647 case GL_FOG_COLOR:
1648 context->setFogColor(params[0], params[1], params[2], params[3]);
1649 break;
1650 default:
1651 return error(GL_INVALID_ENUM);
1652 }
1653 }
1654 }
1655
Fogx(GLenum pname,GLfixed param)1656 void Fogx(GLenum pname, GLfixed param)
1657 {
1658 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
1659
1660 es1::Context *context = es1::getContext();
1661
1662 if(context)
1663 {
1664 switch(pname)
1665 {
1666 case GL_FOG_MODE:
1667 switch((GLenum)param)
1668 {
1669 case GL_LINEAR:
1670 case GL_EXP:
1671 case GL_EXP2:
1672 context->setFogMode((GLenum)param);
1673 break;
1674 default:
1675 return error(GL_INVALID_ENUM);
1676 }
1677 break;
1678 case GL_FOG_DENSITY:
1679 if(param < 0)
1680 {
1681 return error(GL_INVALID_VALUE);
1682 }
1683 context->setFogDensity((float)param / 0x10000);
1684 break;
1685 case GL_FOG_START:
1686 context->setFogStart((float)param / 0x10000);
1687 break;
1688 case GL_FOG_END:
1689 context->setFogEnd((float)param / 0x10000);
1690 break;
1691 case GL_FOG_COLOR:
1692 return error(GL_INVALID_ENUM); // Need four values, should call glFogxv() instead
1693 default:
1694 return error(GL_INVALID_ENUM);
1695 }
1696 }
1697 }
1698
Fogxv(GLenum pname,const GLfixed * params)1699 void Fogxv(GLenum pname, const GLfixed *params)
1700 {
1701 UNIMPLEMENTED();
1702 }
1703
FrontFace(GLenum mode)1704 void FrontFace(GLenum mode)
1705 {
1706 TRACE("(GLenum mode = 0x%X)", mode);
1707
1708 switch(mode)
1709 {
1710 case GL_CW:
1711 case GL_CCW:
1712 {
1713 es1::Context *context = es1::getContext();
1714
1715 if(context)
1716 {
1717 context->setFrontFace(mode);
1718 }
1719 }
1720 break;
1721 default:
1722 return error(GL_INVALID_ENUM);
1723 }
1724 }
1725
Frustumf(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)1726 void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
1727 {
1728 TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar);
1729
1730 if(zNear <= 0.0f || zFar <= 0.0f || left == right || bottom == top || zNear == zFar)
1731 {
1732 return error(GL_INVALID_VALUE);
1733 }
1734
1735 es1::Context *context = es1::getContext();
1736
1737 if(context)
1738 {
1739 context->frustum(left, right, bottom, top, zNear, zFar);
1740 }
1741 }
1742
Frustumx(GLfixed left,GLfixed right,GLfixed bottom,GLfixed top,GLfixed zNear,GLfixed zFar)1743 void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
1744 {
1745 Frustumf((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);
1746 }
1747
GenerateMipmapOES(GLenum target)1748 void GenerateMipmapOES(GLenum target)
1749 {
1750 TRACE("(GLenum target = 0x%X)", target);
1751
1752 es1::Context *context = es1::getContext();
1753
1754 if(context)
1755 {
1756 es1::Texture *texture;
1757
1758 switch(target)
1759 {
1760 case GL_TEXTURE_2D:
1761 texture = context->getTexture2D();
1762 break;
1763 default:
1764 return error(GL_INVALID_ENUM);
1765 }
1766
1767 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
1768 {
1769 return error(GL_INVALID_OPERATION);
1770 }
1771
1772 texture->generateMipmaps();
1773 }
1774 }
1775
GenBuffers(GLsizei n,GLuint * buffers)1776 void GenBuffers(GLsizei n, GLuint* buffers)
1777 {
1778 TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
1779
1780 if(n < 0)
1781 {
1782 return error(GL_INVALID_VALUE);
1783 }
1784
1785 es1::Context *context = es1::getContext();
1786
1787 if(context)
1788 {
1789 for(int i = 0; i < n; i++)
1790 {
1791 buffers[i] = context->createBuffer();
1792 }
1793 }
1794 }
1795
GenFramebuffersOES(GLsizei n,GLuint * framebuffers)1796 void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
1797 {
1798 TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
1799
1800 if(n < 0)
1801 {
1802 return error(GL_INVALID_VALUE);
1803 }
1804
1805 es1::Context *context = es1::getContext();
1806
1807 if(context)
1808 {
1809 for(int i = 0; i < n; i++)
1810 {
1811 framebuffers[i] = context->createFramebuffer();
1812 }
1813 }
1814 }
1815
GenRenderbuffersOES(GLsizei n,GLuint * renderbuffers)1816 void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
1817 {
1818 TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
1819
1820 if(n < 0)
1821 {
1822 return error(GL_INVALID_VALUE);
1823 }
1824
1825 es1::Context *context = es1::getContext();
1826
1827 if(context)
1828 {
1829 for(int i = 0; i < n; i++)
1830 {
1831 renderbuffers[i] = context->createRenderbuffer();
1832 }
1833 }
1834 }
1835
GenTextures(GLsizei n,GLuint * textures)1836 void GenTextures(GLsizei n, GLuint* textures)
1837 {
1838 TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
1839
1840 if(n < 0)
1841 {
1842 return error(GL_INVALID_VALUE);
1843 }
1844
1845 es1::Context *context = es1::getContext();
1846
1847 if(context)
1848 {
1849 for(int i = 0; i < n; i++)
1850 {
1851 textures[i] = context->createTexture();
1852 }
1853 }
1854 }
1855
GetRenderbufferParameterivOES(GLenum target,GLenum pname,GLint * params)1856 void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
1857 {
1858 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
1859
1860 es1::Context *context = es1::getContext();
1861
1862 if(context)
1863 {
1864 if(target != GL_RENDERBUFFER_OES)
1865 {
1866 return error(GL_INVALID_ENUM);
1867 }
1868
1869 if(context->getRenderbufferName() == 0)
1870 {
1871 return error(GL_INVALID_OPERATION);
1872 }
1873
1874 es1::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
1875
1876 switch(pname)
1877 {
1878 case GL_RENDERBUFFER_WIDTH_OES: *params = renderbuffer->getWidth(); break;
1879 case GL_RENDERBUFFER_HEIGHT_OES: *params = renderbuffer->getHeight(); break;
1880 case GL_RENDERBUFFER_INTERNAL_FORMAT_OES: *params = renderbuffer->getFormat(); break;
1881 case GL_RENDERBUFFER_RED_SIZE_OES: *params = renderbuffer->getRedSize(); break;
1882 case GL_RENDERBUFFER_GREEN_SIZE_OES: *params = renderbuffer->getGreenSize(); break;
1883 case GL_RENDERBUFFER_BLUE_SIZE_OES: *params = renderbuffer->getBlueSize(); break;
1884 case GL_RENDERBUFFER_ALPHA_SIZE_OES: *params = renderbuffer->getAlphaSize(); break;
1885 case GL_RENDERBUFFER_DEPTH_SIZE_OES: *params = renderbuffer->getDepthSize(); break;
1886 case GL_RENDERBUFFER_STENCIL_SIZE_OES: *params = renderbuffer->getStencilSize(); break;
1887 default:
1888 return error(GL_INVALID_ENUM);
1889 }
1890 }
1891 }
1892
GetBooleanv(GLenum pname,GLboolean * params)1893 void GetBooleanv(GLenum pname, GLboolean* params)
1894 {
1895 TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)", pname, params);
1896
1897 es1::Context *context = es1::getContext();
1898
1899 if(context)
1900 {
1901 if(!(context->getBooleanv(pname, params)))
1902 {
1903 int numParams = context->getQueryParameterNum(pname);
1904
1905 if(numParams < 0)
1906 {
1907 return error(GL_INVALID_ENUM);
1908 }
1909
1910 if(numParams == 0)
1911 {
1912 return;
1913 }
1914
1915 if(context->isQueryParameterFloat(pname))
1916 {
1917 GLfloat *floatParams = nullptr;
1918 floatParams = new GLfloat[numParams];
1919
1920 context->getFloatv(pname, floatParams);
1921
1922 for(int i = 0; i < numParams; ++i)
1923 {
1924 if(floatParams[i] == 0.0f)
1925 params[i] = GL_FALSE;
1926 else
1927 params[i] = GL_TRUE;
1928 }
1929
1930 delete [] floatParams;
1931 }
1932 else if(context->isQueryParameterInt(pname))
1933 {
1934 GLint *intParams = nullptr;
1935 intParams = new GLint[numParams];
1936
1937 context->getIntegerv(pname, intParams);
1938
1939 for(int i = 0; i < numParams; ++i)
1940 {
1941 if(intParams[i] == 0)
1942 params[i] = GL_FALSE;
1943 else
1944 params[i] = GL_TRUE;
1945 }
1946
1947 delete [] intParams;
1948 }
1949 else UNREACHABLE(pname);
1950 }
1951 }
1952 }
1953
GetBufferParameteriv(GLenum target,GLenum pname,GLint * params)1954 void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
1955 {
1956 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
1957
1958 es1::Context *context = es1::getContext();
1959
1960 if(context)
1961 {
1962 es1::Buffer *buffer;
1963
1964 switch(target)
1965 {
1966 case GL_ARRAY_BUFFER:
1967 buffer = context->getArrayBuffer();
1968 break;
1969 case GL_ELEMENT_ARRAY_BUFFER:
1970 buffer = context->getElementArrayBuffer();
1971 break;
1972 default:
1973 return error(GL_INVALID_ENUM);
1974 }
1975
1976 if(!buffer)
1977 {
1978 // A null buffer means that "0" is bound to the requested buffer target
1979 return error(GL_INVALID_OPERATION);
1980 }
1981
1982 switch(pname)
1983 {
1984 case GL_BUFFER_USAGE:
1985 *params = buffer->usage();
1986 break;
1987 case GL_BUFFER_SIZE:
1988 *params = (GLint)buffer->size();
1989 break;
1990 default:
1991 return error(GL_INVALID_ENUM);
1992 }
1993 }
1994 }
1995
GetClipPlanef(GLenum pname,GLfloat eqn[4])1996 void GetClipPlanef(GLenum pname, GLfloat eqn[4])
1997 {
1998 UNIMPLEMENTED();
1999 }
2000
GetClipPlanex(GLenum pname,GLfixed eqn[4])2001 void GetClipPlanex(GLenum pname, GLfixed eqn[4])
2002 {
2003 UNIMPLEMENTED();
2004 }
2005
GetError(void)2006 GLenum GetError(void)
2007 {
2008 TRACE("()");
2009
2010 es1::Context *context = es1::getContext();
2011
2012 if(context)
2013 {
2014 return context->getError();
2015 }
2016
2017 return GL_NO_ERROR;
2018 }
2019
GetFixedv(GLenum pname,GLfixed * params)2020 void GetFixedv(GLenum pname, GLfixed *params)
2021 {
2022 UNIMPLEMENTED();
2023 }
2024
GetFloatv(GLenum pname,GLfloat * params)2025 void GetFloatv(GLenum pname, GLfloat* params)
2026 {
2027 TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
2028
2029 es1::Context *context = es1::getContext();
2030
2031 if(context)
2032 {
2033 if(!(context->getFloatv(pname, params)))
2034 {
2035 int numParams = context->getQueryParameterNum(pname);
2036
2037 if(numParams < 0)
2038 {
2039 return error(GL_INVALID_ENUM);
2040 }
2041
2042 if(numParams == 0)
2043 {
2044 return;
2045 }
2046
2047 if(context->isQueryParameterBool(pname))
2048 {
2049 GLboolean *boolParams = nullptr;
2050 boolParams = new GLboolean[numParams];
2051
2052 context->getBooleanv(pname, boolParams);
2053
2054 for(int i = 0; i < numParams; ++i)
2055 {
2056 if(boolParams[i] == GL_FALSE)
2057 params[i] = 0.0f;
2058 else
2059 params[i] = 1.0f;
2060 }
2061
2062 delete [] boolParams;
2063 }
2064 else if(context->isQueryParameterInt(pname))
2065 {
2066 GLint *intParams = nullptr;
2067 intParams = new GLint[numParams];
2068
2069 context->getIntegerv(pname, intParams);
2070
2071 for(int i = 0; i < numParams; ++i)
2072 {
2073 params[i] = (GLfloat)intParams[i];
2074 }
2075
2076 delete [] intParams;
2077 }
2078 else UNREACHABLE(pname);
2079 }
2080 }
2081 }
2082
GetFramebufferAttachmentParameterivOES(GLenum target,GLenum attachment,GLenum pname,GLint * params)2083 void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2084 {
2085 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
2086 target, attachment, pname, params);
2087
2088 es1::Context *context = es1::getContext();
2089
2090 if(context)
2091 {
2092 if(target != GL_FRAMEBUFFER_OES)
2093 {
2094 return error(GL_INVALID_ENUM);
2095 }
2096
2097 if(context->getFramebufferName() == 0)
2098 {
2099 return error(GL_INVALID_OPERATION);
2100 }
2101
2102 es1::Framebuffer *framebuffer = context->getFramebuffer();
2103
2104 GLenum attachmentType;
2105 GLuint attachmentHandle;
2106 switch(attachment)
2107 {
2108 case GL_COLOR_ATTACHMENT0_OES:
2109 attachmentType = framebuffer->getColorbufferType();
2110 attachmentHandle = framebuffer->getColorbufferName();
2111 break;
2112 case GL_DEPTH_ATTACHMENT_OES:
2113 attachmentType = framebuffer->getDepthbufferType();
2114 attachmentHandle = framebuffer->getDepthbufferName();
2115 break;
2116 case GL_STENCIL_ATTACHMENT_OES:
2117 attachmentType = framebuffer->getStencilbufferType();
2118 attachmentHandle = framebuffer->getStencilbufferName();
2119 break;
2120 default:
2121 return error(GL_INVALID_ENUM);
2122 }
2123
2124 GLenum attachmentObjectType; // Type category
2125 if(attachmentType == GL_NONE_OES || attachmentType == GL_RENDERBUFFER_OES)
2126 {
2127 attachmentObjectType = attachmentType;
2128 }
2129 else if(es1::IsTextureTarget(attachmentType))
2130 {
2131 attachmentObjectType = GL_TEXTURE;
2132 }
2133 else UNREACHABLE(attachmentType);
2134
2135 switch(pname)
2136 {
2137 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES:
2138 *params = attachmentObjectType;
2139 break;
2140 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES:
2141 if(attachmentObjectType == GL_RENDERBUFFER_OES || attachmentObjectType == GL_TEXTURE)
2142 {
2143 *params = attachmentHandle;
2144 }
2145 else
2146 {
2147 return error(GL_INVALID_ENUM);
2148 }
2149 break;
2150 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES:
2151 if(attachmentObjectType == GL_TEXTURE)
2152 {
2153 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2154 }
2155 else
2156 {
2157 return error(GL_INVALID_ENUM);
2158 }
2159 break;
2160 default:
2161 return error(GL_INVALID_ENUM);
2162 }
2163 }
2164 }
2165
GetIntegerv(GLenum pname,GLint * params)2166 void GetIntegerv(GLenum pname, GLint* params)
2167 {
2168 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
2169
2170 es1::Context *context = es1::getContext();
2171
2172 if(context)
2173 {
2174 if(!(context->getIntegerv(pname, params)))
2175 {
2176 int numParams = context->getQueryParameterNum(pname);
2177
2178 if(numParams < 0)
2179 {
2180 return error(GL_INVALID_ENUM);
2181 }
2182
2183 if(numParams == 0)
2184 {
2185 return;
2186 }
2187
2188 if(context->isQueryParameterBool(pname))
2189 {
2190 GLboolean *boolParams = nullptr;
2191 boolParams = new GLboolean[numParams];
2192
2193 context->getBooleanv(pname, boolParams);
2194
2195 for(int i = 0; i < numParams; ++i)
2196 {
2197 if(boolParams[i] == GL_FALSE)
2198 params[i] = 0;
2199 else
2200 params[i] = 1;
2201 }
2202
2203 delete [] boolParams;
2204 }
2205 else if(context->isQueryParameterFloat(pname))
2206 {
2207 GLfloat *floatParams = nullptr;
2208 floatParams = new GLfloat[numParams];
2209
2210 context->getFloatv(pname, floatParams);
2211
2212 for(int i = 0; i < numParams; ++i)
2213 {
2214 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
2215 {
2216 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
2217 }
2218 else
2219 {
2220 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
2221 }
2222 }
2223
2224 delete [] floatParams;
2225 }
2226 else UNREACHABLE(pname);
2227 }
2228 }
2229 }
2230
GetLightfv(GLenum light,GLenum pname,GLfloat * params)2231 void GetLightfv(GLenum light, GLenum pname, GLfloat *params)
2232 {
2233 UNIMPLEMENTED();
2234 }
2235
GetLightxv(GLenum light,GLenum pname,GLfixed * params)2236 void GetLightxv(GLenum light, GLenum pname, GLfixed *params)
2237 {
2238 UNIMPLEMENTED();
2239 }
2240
GetMaterialfv(GLenum face,GLenum pname,GLfloat * params)2241 void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
2242 {
2243 UNIMPLEMENTED();
2244 }
2245
GetMaterialxv(GLenum face,GLenum pname,GLfixed * params)2246 void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
2247 {
2248 UNIMPLEMENTED();
2249 }
2250
GetPointerv(GLenum pname,GLvoid ** params)2251 void GetPointerv(GLenum pname, GLvoid **params)
2252 {
2253 TRACE("(GLenum pname = 0x%X, GLvoid **params = %p)", pname, params);
2254
2255 es1::Context *context = es1::getContext();
2256
2257 if(context)
2258 {
2259 if(!(context->getPointerv(pname, const_cast<const GLvoid**>(params))))
2260 {
2261 return error(GL_INVALID_ENUM);
2262 }
2263 }
2264 }
2265
GetString(GLenum name)2266 const GLubyte* GetString(GLenum name)
2267 {
2268 TRACE("(GLenum name = 0x%X)", name);
2269
2270 switch(name)
2271 {
2272 case GL_VENDOR:
2273 return (GLubyte*)"Google Inc.";
2274 case GL_RENDERER:
2275 return (GLubyte*)"Google SwiftShader " VERSION_STRING;
2276 case GL_VERSION:
2277 return (GLubyte*)"OpenGL ES-CM 1.1";
2278 case GL_EXTENSIONS:
2279 // Keep list sorted in following order:
2280 // OES extensions
2281 // EXT extensions
2282 // Vendor extensions
2283 return (GLubyte*)
2284 "GL_OES_blend_equation_separate "
2285 "GL_OES_blend_func_separate "
2286 "GL_OES_blend_subtract "
2287 "GL_OES_compressed_ETC1_RGB8_texture "
2288 "GL_OES_depth_texture "
2289 "GL_OES_EGL_image "
2290 "GL_OES_EGL_image_external "
2291 "GL_OES_EGL_sync "
2292 "GL_OES_element_index_uint "
2293 "GL_OES_framebuffer_object "
2294 "GL_OES_packed_depth_stencil "
2295 "GL_OES_read_format "
2296 "GL_OES_rgb8_rgba8 "
2297 "GL_OES_stencil8 "
2298 "GL_OES_stencil_wrap "
2299 "GL_OES_texture_mirrored_repeat "
2300 "GL_OES_texture_npot "
2301 "GL_EXT_blend_minmax "
2302 "GL_EXT_read_format_bgra "
2303 #if (S3TC_SUPPORT)
2304 "GL_EXT_texture_compression_dxt1 "
2305 "GL_ANGLE_texture_compression_dxt3 "
2306 "GL_ANGLE_texture_compression_dxt5 "
2307 #endif
2308 "GL_EXT_texture_filter_anisotropic "
2309 "GL_EXT_texture_format_BGRA8888";
2310 default:
2311 return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
2312 }
2313 }
2314
GetTexParameterfv(GLenum target,GLenum pname,GLfloat * params)2315 void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2316 {
2317 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
2318
2319 es1::Context *context = es1::getContext();
2320
2321 if(context)
2322 {
2323 es1::Texture *texture;
2324
2325 switch(target)
2326 {
2327 case GL_TEXTURE_2D:
2328 texture = context->getTexture2D();
2329 break;
2330 case GL_TEXTURE_EXTERNAL_OES:
2331 texture = context->getTextureExternal();
2332 break;
2333 default:
2334 return error(GL_INVALID_ENUM);
2335 }
2336
2337 switch(pname)
2338 {
2339 case GL_TEXTURE_MAG_FILTER:
2340 *params = (GLfloat)texture->getMagFilter();
2341 break;
2342 case GL_TEXTURE_MIN_FILTER:
2343 *params = (GLfloat)texture->getMinFilter();
2344 break;
2345 case GL_TEXTURE_WRAP_S:
2346 *params = (GLfloat)texture->getWrapS();
2347 break;
2348 case GL_TEXTURE_WRAP_T:
2349 *params = (GLfloat)texture->getWrapT();
2350 break;
2351 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2352 *params = texture->getMaxAnisotropy();
2353 break;
2354 case GL_GENERATE_MIPMAP:
2355 *params = (GLfloat)texture->getGenerateMipmap();
2356 break;
2357 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2358 *params = (GLfloat)1;
2359 break;
2360 default:
2361 return error(GL_INVALID_ENUM);
2362 }
2363 }
2364 }
2365
GetTexParameteriv(GLenum target,GLenum pname,GLint * params)2366 void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2367 {
2368 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
2369
2370 es1::Context *context = es1::getContext();
2371
2372 if(context)
2373 {
2374 es1::Texture *texture;
2375
2376 switch(target)
2377 {
2378 case GL_TEXTURE_2D:
2379 texture = context->getTexture2D();
2380 break;
2381 case GL_TEXTURE_EXTERNAL_OES:
2382 texture = context->getTextureExternal();
2383 break;
2384 default:
2385 return error(GL_INVALID_ENUM);
2386 }
2387
2388 switch(pname)
2389 {
2390 case GL_TEXTURE_MAG_FILTER:
2391 *params = texture->getMagFilter();
2392 break;
2393 case GL_TEXTURE_MIN_FILTER:
2394 *params = texture->getMinFilter();
2395 break;
2396 case GL_TEXTURE_WRAP_S:
2397 *params = texture->getWrapS();
2398 break;
2399 case GL_TEXTURE_WRAP_T:
2400 *params = texture->getWrapT();
2401 break;
2402 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2403 *params = (GLint)texture->getMaxAnisotropy();
2404 break;
2405 case GL_GENERATE_MIPMAP:
2406 *params = (GLint)texture->getGenerateMipmap();
2407 break;
2408 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2409 *params = 1;
2410 break;
2411 default:
2412 return error(GL_INVALID_ENUM);
2413 }
2414 }
2415 }
2416
GetTexEnvfv(GLenum env,GLenum pname,GLfloat * params)2417 void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
2418 {
2419 UNIMPLEMENTED();
2420 }
2421
GetTexEnviv(GLenum env,GLenum pname,GLint * params)2422 void GetTexEnviv(GLenum env, GLenum pname, GLint *params)
2423 {
2424 UNIMPLEMENTED();
2425 }
2426
GetTexEnvxv(GLenum env,GLenum pname,GLfixed * params)2427 void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
2428 {
2429 UNIMPLEMENTED();
2430 }
2431
GetTexParameterxv(GLenum target,GLenum pname,GLfixed * params)2432 void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
2433 {
2434 UNIMPLEMENTED();
2435 }
2436
Hint(GLenum target,GLenum mode)2437 void Hint(GLenum target, GLenum mode)
2438 {
2439 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
2440
2441 switch(mode)
2442 {
2443 case GL_FASTEST:
2444 case GL_NICEST:
2445 case GL_DONT_CARE:
2446 break;
2447 default:
2448 return error(GL_INVALID_ENUM);
2449 }
2450
2451 es1::Context *context = es1::getContext();
2452
2453 if(context)
2454 {
2455 switch(target)
2456 {
2457 case GL_GENERATE_MIPMAP_HINT:
2458 context->setGenerateMipmapHint(mode);
2459 break;
2460 case GL_PERSPECTIVE_CORRECTION_HINT:
2461 context->setPerspectiveCorrectionHint(mode);
2462 break;
2463 case GL_FOG_HINT:
2464 context->setFogHint(mode);
2465 break;
2466 default:
2467 return error(GL_INVALID_ENUM);
2468 }
2469 }
2470 }
2471
IsBuffer(GLuint buffer)2472 GLboolean IsBuffer(GLuint buffer)
2473 {
2474 TRACE("(GLuint buffer = %d)", buffer);
2475
2476 es1::Context *context = es1::getContext();
2477
2478 if(context && buffer)
2479 {
2480 es1::Buffer *bufferObject = context->getBuffer(buffer);
2481
2482 if(bufferObject)
2483 {
2484 return GL_TRUE;
2485 }
2486 }
2487
2488 return GL_FALSE;
2489 }
2490
IsEnabled(GLenum cap)2491 GLboolean IsEnabled(GLenum cap)
2492 {
2493 TRACE("(GLenum cap = 0x%X)", cap);
2494
2495 es1::Context *context = es1::getContext();
2496
2497 if(context)
2498 {
2499 switch(cap)
2500 {
2501 case GL_CULL_FACE: return context->isCullFaceEnabled(); break;
2502 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled(); break;
2503 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); break;
2504 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled(); break;
2505 case GL_SCISSOR_TEST: return context->isScissorTestEnabled(); break;
2506 case GL_STENCIL_TEST: return context->isStencilTestEnabled(); break;
2507 case GL_DEPTH_TEST: return context->isDepthTestEnabled(); break;
2508 case GL_BLEND: return context->isBlendEnabled(); break;
2509 case GL_DITHER: return context->isDitherEnabled(); break;
2510 case GL_LIGHTING: return context->isLightingEnabled(); break;
2511 case GL_LIGHT0: return context->isLightEnabled(0); break;
2512 case GL_LIGHT1: return context->isLightEnabled(1); break;
2513 case GL_LIGHT2: return context->isLightEnabled(2); break;
2514 case GL_LIGHT3: return context->isLightEnabled(3); break;
2515 case GL_LIGHT4: return context->isLightEnabled(4); break;
2516 case GL_LIGHT5: return context->isLightEnabled(5); break;
2517 case GL_LIGHT6: return context->isLightEnabled(6); break;
2518 case GL_LIGHT7: return context->isLightEnabled(7); break;
2519 case GL_FOG: return context->isFogEnabled(); break;
2520 case GL_TEXTURE_2D: return context->isTexture2Denabled(); break;
2521 case GL_TEXTURE_EXTERNAL_OES: return context->isTextureExternalEnabled(); break;
2522 case GL_ALPHA_TEST: return context->isAlphaTestEnabled(); break;
2523 case GL_COLOR_LOGIC_OP: return context->isColorLogicOpEnabled(); break;
2524 case GL_POINT_SMOOTH: return context->isPointSmoothEnabled(); break;
2525 case GL_LINE_SMOOTH: return context->isLineSmoothEnabled(); break;
2526 case GL_COLOR_MATERIAL: return context->isColorMaterialEnabled(); break;
2527 case GL_NORMALIZE: return context->isNormalizeEnabled(); break;
2528 case GL_RESCALE_NORMAL: return context->isRescaleNormalEnabled(); break;
2529 case GL_VERTEX_ARRAY: return context->isVertexArrayEnabled(); break;
2530 case GL_NORMAL_ARRAY: return context->isNormalArrayEnabled(); break;
2531 case GL_COLOR_ARRAY: return context->isColorArrayEnabled(); break;
2532 case GL_POINT_SIZE_ARRAY_OES: return context->isPointSizeArrayEnabled(); break;
2533 case GL_TEXTURE_COORD_ARRAY: return context->isTextureCoordArrayEnabled(); break;
2534 case GL_MULTISAMPLE: return context->isMultisampleEnabled(); break;
2535 case GL_SAMPLE_ALPHA_TO_ONE: return context->isSampleAlphaToOneEnabled(); break;
2536 case GL_CLIP_PLANE0: return context->isClipPlaneEnabled(0); break;
2537 case GL_CLIP_PLANE1: return context->isClipPlaneEnabled(1); break;
2538 case GL_CLIP_PLANE2: return context->isClipPlaneEnabled(2); break;
2539 case GL_CLIP_PLANE3: return context->isClipPlaneEnabled(3); break;
2540 case GL_CLIP_PLANE4: return context->isClipPlaneEnabled(4); break;
2541 case GL_CLIP_PLANE5: return context->isClipPlaneEnabled(5); break;
2542 case GL_POINT_SPRITE_OES: return context->isPointSpriteEnabled(); break;
2543 default:
2544 return error(GL_INVALID_ENUM, GL_FALSE);
2545 }
2546 }
2547
2548 return GL_FALSE;
2549 }
2550
IsFramebufferOES(GLuint framebuffer)2551 GLboolean IsFramebufferOES(GLuint framebuffer)
2552 {
2553 TRACE("(GLuint framebuffer = %d)", framebuffer);
2554
2555 es1::Context *context = es1::getContext();
2556
2557 if(context && framebuffer)
2558 {
2559 es1::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2560
2561 if(framebufferObject)
2562 {
2563 return GL_TRUE;
2564 }
2565 }
2566
2567 return GL_FALSE;
2568 }
2569
IsTexture(GLuint texture)2570 GLboolean IsTexture(GLuint texture)
2571 {
2572 TRACE("(GLuint texture = %d)", texture);
2573
2574 es1::Context *context = es1::getContext();
2575
2576 if(context && texture)
2577 {
2578 es1::Texture *textureObject = context->getTexture(texture);
2579
2580 if(textureObject)
2581 {
2582 return GL_TRUE;
2583 }
2584 }
2585
2586 return GL_FALSE;
2587 }
2588
IsRenderbufferOES(GLuint renderbuffer)2589 GLboolean IsRenderbufferOES(GLuint renderbuffer)
2590 {
2591 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
2592
2593 es1::Context *context = es1::getContext();
2594
2595 if(context && renderbuffer)
2596 {
2597 es1::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2598
2599 if(renderbufferObject)
2600 {
2601 return GL_TRUE;
2602 }
2603 }
2604
2605 return GL_FALSE;
2606 }
2607
LightModelf(GLenum pname,GLfloat param)2608 void LightModelf(GLenum pname, GLfloat param)
2609 {
2610 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
2611
2612 es1::Context *context = es1::getContext();
2613
2614 if(context)
2615 {
2616 switch(pname)
2617 {
2618 case GL_LIGHT_MODEL_TWO_SIDE:
2619 context->setLightModelTwoSide(param != 0.0f);
2620 break;
2621 case GL_LIGHT_MODEL_AMBIENT:
2622 return error(GL_INVALID_ENUM); // Need four values, should call glLightModelfv() instead
2623 default:
2624 return error(GL_INVALID_ENUM);
2625 }
2626 }
2627 }
2628
LightModelfv(GLenum pname,const GLfloat * params)2629 void LightModelfv(GLenum pname, const GLfloat *params)
2630 {
2631 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
2632
2633 es1::Context *context = es1::getContext();
2634
2635 if(context)
2636 {
2637 switch(pname)
2638 {
2639 case GL_LIGHT_MODEL_AMBIENT:
2640 context->setGlobalAmbient(params[0], params[1], params[2], params[3]);
2641 break;
2642 case GL_LIGHT_MODEL_TWO_SIDE:
2643 context->setLightModelTwoSide(params[0] != 0.0f);
2644 break;
2645 default:
2646 return error(GL_INVALID_ENUM);
2647 }
2648 }
2649 }
2650
LightModelx(GLenum pname,GLfixed param)2651 void LightModelx(GLenum pname, GLfixed param)
2652 {
2653 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
2654
2655 es1::Context *context = es1::getContext();
2656
2657 if(context)
2658 {
2659 switch(pname)
2660 {
2661 case GL_LIGHT_MODEL_TWO_SIDE:
2662 context->setLightModelTwoSide(param != 0);
2663 break;
2664 case GL_LIGHT_MODEL_AMBIENT:
2665 return error(GL_INVALID_ENUM); // Need four values, should call glLightModelxv() instead
2666 default:
2667 return error(GL_INVALID_ENUM);
2668 }
2669 }
2670 }
2671
LightModelxv(GLenum pname,const GLfixed * params)2672 void LightModelxv(GLenum pname, const GLfixed *params)
2673 {
2674 TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);
2675
2676 es1::Context *context = es1::getContext();
2677
2678 if(context)
2679 {
2680 switch(pname)
2681 {
2682 case GL_LIGHT_MODEL_AMBIENT:
2683 context->setGlobalAmbient((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000, (float)params[3] / 0x10000);
2684 break;
2685 case GL_LIGHT_MODEL_TWO_SIDE:
2686 context->setLightModelTwoSide(params[0] != 0);
2687 break;
2688 default:
2689 return error(GL_INVALID_ENUM);
2690 }
2691 }
2692 }
2693
Lightf(GLenum light,GLenum pname,GLfloat param)2694 void Lightf(GLenum light, GLenum pname, GLfloat param)
2695 {
2696 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", light, pname, param);
2697
2698 int index = light - GL_LIGHT0;
2699
2700 if(index < 0 || index >= es1::MAX_LIGHTS)
2701 {
2702 return error(GL_INVALID_ENUM);
2703 }
2704
2705 es1::Context *context = es1::getContext();
2706
2707 if(context)
2708 {
2709 switch(pname)
2710 {
2711 case GL_SPOT_EXPONENT:
2712 if(param < 0.0f || param > 128.0f)
2713 {
2714 return error(GL_INVALID_VALUE);
2715 }
2716 context->setSpotLightExponent(index, param);
2717 break;
2718 case GL_SPOT_CUTOFF:
2719 if((param < 0.0f || param > 90.0f) && param != 180.0f)
2720 {
2721 return error(GL_INVALID_VALUE);
2722 }
2723 context->setSpotLightCutoff(index, param);
2724 break;
2725 case GL_CONSTANT_ATTENUATION:
2726 if(param < 0.0f)
2727 {
2728 return error(GL_INVALID_VALUE);
2729 }
2730 context->setLightAttenuationConstant(index, param);
2731 break;
2732 case GL_LINEAR_ATTENUATION:
2733 if(param < 0.0f)
2734 {
2735 return error(GL_INVALID_VALUE);
2736 }
2737 context->setLightAttenuationLinear(index, param);
2738 break;
2739 case GL_QUADRATIC_ATTENUATION:
2740 if(param < 0.0f)
2741 {
2742 return error(GL_INVALID_VALUE);
2743 }
2744 context->setLightAttenuationQuadratic(index, param);
2745 break;
2746 case GL_AMBIENT:
2747 case GL_DIFFUSE:
2748 case GL_SPECULAR:
2749 case GL_POSITION:
2750 case GL_SPOT_DIRECTION:
2751 return error(GL_INVALID_ENUM); // Need four values, should call glLightfv() instead
2752 default:
2753 return error(GL_INVALID_ENUM);
2754 }
2755 }
2756 }
2757
Lightfv(GLenum light,GLenum pname,const GLfloat * params)2758 void Lightfv(GLenum light, GLenum pname, const GLfloat *params)
2759 {
2760 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
2761
2762 es1::Context *context = es1::getContext();
2763
2764 if(context)
2765 {
2766 int index = light - GL_LIGHT0;
2767
2768 if(index < 0 || index > es1::MAX_LIGHTS)
2769 {
2770 return error(GL_INVALID_ENUM);
2771 }
2772
2773 switch(pname)
2774 {
2775 case GL_AMBIENT: context->setLightAmbient(index, params[0], params[1], params[2], params[3]); break;
2776 case GL_DIFFUSE: context->setLightDiffuse(index, params[0], params[1], params[2], params[3]); break;
2777 case GL_SPECULAR: context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break;
2778 case GL_POSITION: context->setLightPosition(index, params[0], params[1], params[2], params[3]); break;
2779 case GL_SPOT_DIRECTION: context->setLightDirection(index, params[0], params[1], params[2]); break;
2780 case GL_SPOT_EXPONENT:
2781 if(params[0] < 0.0f || params[0] > 128.0f)
2782 {
2783 return error(GL_INVALID_VALUE);
2784 }
2785 context->setSpotLightExponent(index, params[0]);
2786 break;
2787 case GL_SPOT_CUTOFF:
2788 if((params[0] < 0.0f || params[0] > 90.0f) && params[0] != 180.0f)
2789 {
2790 return error(GL_INVALID_VALUE);
2791 }
2792 context->setSpotLightCutoff(index, params[0]);
2793 break;
2794 case GL_CONSTANT_ATTENUATION:
2795 if(params[0] < 0.0f)
2796 {
2797 return error(GL_INVALID_VALUE);
2798 }
2799 context->setLightAttenuationConstant(index, params[0]);
2800 break;
2801 case GL_LINEAR_ATTENUATION:
2802 if(params[0] < 0.0f)
2803 {
2804 return error(GL_INVALID_VALUE);
2805 }
2806 context->setLightAttenuationLinear(index, params[0]);
2807 break;
2808 case GL_QUADRATIC_ATTENUATION:
2809 if(params[0] < 0.0f)
2810 {
2811 return error(GL_INVALID_VALUE);
2812 }
2813 context->setLightAttenuationQuadratic(index, params[0]);
2814 break;
2815 default:
2816 return error(GL_INVALID_ENUM);
2817 }
2818 }
2819 }
2820
Lightx(GLenum light,GLenum pname,GLfixed param)2821 void Lightx(GLenum light, GLenum pname, GLfixed param)
2822 {
2823 UNIMPLEMENTED();
2824 }
2825
Lightxv(GLenum light,GLenum pname,const GLfixed * params)2826 void Lightxv(GLenum light, GLenum pname, const GLfixed *params)
2827 {
2828 UNIMPLEMENTED();
2829 }
2830
LineWidth(GLfloat width)2831 void LineWidth(GLfloat width)
2832 {
2833 TRACE("(GLfloat width = %f)", width);
2834
2835 if(width <= 0.0f)
2836 {
2837 return error(GL_INVALID_VALUE);
2838 }
2839
2840 es1::Context *context = es1::getContext();
2841
2842 if(context)
2843 {
2844 context->setLineWidth(width);
2845 }
2846 }
2847
LineWidthx(GLfixed width)2848 void LineWidthx(GLfixed width)
2849 {
2850 LineWidth((float)width / 0x10000);
2851 }
2852
LoadIdentity(void)2853 void LoadIdentity(void)
2854 {
2855 TRACE("()");
2856
2857 es1::Context *context = es1::getContext();
2858
2859 if(context)
2860 {
2861 context->loadIdentity();
2862 }
2863 }
2864
LoadMatrixf(const GLfloat * m)2865 void LoadMatrixf(const GLfloat *m)
2866 {
2867 TRACE("(const GLfloat *m)");
2868
2869 es1::Context *context = es1::getContext();
2870
2871 if(context)
2872 {
2873 context->load(m);
2874 }
2875 }
2876
LoadMatrixx(const GLfixed * m)2877 void LoadMatrixx(const GLfixed *m)
2878 {
2879 GLfloat matrix[16] =
2880 {
2881 (float)m[0] / 0x10000, (float)m[1] / 0x10000, (float)m[2] / 0x10000, (float)m[3] / 0x10000,
2882 (float)m[4] / 0x10000, (float)m[5] / 0x10000, (float)m[6] / 0x10000, (float)m[7] / 0x10000,
2883 (float)m[8] / 0x10000, (float)m[9] / 0x10000, (float)m[10] / 0x10000, (float)m[11] / 0x10000,
2884 (float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
2885 };
2886
2887 LoadMatrixf(matrix);
2888 }
2889
LogicOp(GLenum opcode)2890 void LogicOp(GLenum opcode)
2891 {
2892 TRACE("(GLenum opcode = 0x%X)", opcode);
2893
2894 switch(opcode)
2895 {
2896 case GL_CLEAR:
2897 case GL_SET:
2898 case GL_COPY:
2899 case GL_COPY_INVERTED:
2900 case GL_NOOP:
2901 case GL_INVERT:
2902 case GL_AND:
2903 case GL_NAND:
2904 case GL_OR:
2905 case GL_NOR:
2906 case GL_XOR:
2907 case GL_EQUIV:
2908 case GL_AND_REVERSE:
2909 case GL_AND_INVERTED:
2910 case GL_OR_REVERSE:
2911 case GL_OR_INVERTED:
2912 break;
2913 default:
2914 return error(GL_INVALID_ENUM);
2915 }
2916
2917 es1::Context *context = es1::getContext();
2918
2919 if(context)
2920 {
2921 context->setLogicalOperation(opcode);
2922 }
2923 }
2924
Materialf(GLenum face,GLenum pname,GLfloat param)2925 void Materialf(GLenum face, GLenum pname, GLfloat param)
2926 {
2927 TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", face, pname, param);
2928
2929 if(face != GL_FRONT_AND_BACK)
2930 {
2931 return error(GL_INVALID_ENUM);
2932 }
2933
2934 es1::Context *context = es1::getContext();
2935
2936 if(context)
2937 {
2938 switch(pname)
2939 {
2940 case GL_SHININESS:
2941 if(param < 0.0f || param > 128.0f)
2942 {
2943 return error(GL_INVALID_VALUE);
2944 }
2945 context->setMaterialShininess(param);
2946 break;
2947 case GL_AMBIENT:
2948 case GL_DIFFUSE:
2949 case GL_AMBIENT_AND_DIFFUSE:
2950 case GL_SPECULAR:
2951 case GL_EMISSION:
2952 return error(GL_INVALID_ENUM); // Need four values, should call glMaterialfv() instead
2953 default:
2954 return error(GL_INVALID_ENUM);
2955 }
2956 }
2957 }
2958
Materialfv(GLenum face,GLenum pname,const GLfloat * params)2959 void Materialfv(GLenum face, GLenum pname, const GLfloat *params)
2960 {
2961 TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat params)", face, pname);
2962
2963 if(face != GL_FRONT_AND_BACK)
2964 {
2965 return error(GL_INVALID_ENUM);
2966 }
2967
2968 es1::Context *context = es1::getContext();
2969
2970 if(context)
2971 {
2972 switch(pname)
2973 {
2974 case GL_AMBIENT:
2975 context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
2976 break;
2977 case GL_DIFFUSE:
2978 context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
2979 break;
2980 case GL_AMBIENT_AND_DIFFUSE:
2981 context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
2982 context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
2983 break;
2984 case GL_SPECULAR:
2985 context->setMaterialSpecular(params[0], params[1], params[2], params[3]);
2986 break;
2987 case GL_EMISSION:
2988 context->setMaterialEmission(params[0], params[1], params[2], params[3]);
2989 break;
2990 case GL_SHININESS:
2991 context->setMaterialShininess(params[0]);
2992 break;
2993 default:
2994 return error(GL_INVALID_ENUM);
2995 }
2996 }
2997 }
2998
Materialx(GLenum face,GLenum pname,GLfixed param)2999 void Materialx(GLenum face, GLenum pname, GLfixed param)
3000 {
3001 UNIMPLEMENTED();
3002 }
3003
Materialxv(GLenum face,GLenum pname,const GLfixed * params)3004 void Materialxv(GLenum face, GLenum pname, const GLfixed *params)
3005 {
3006 UNIMPLEMENTED();
3007 }
3008
MatrixMode(GLenum mode)3009 void MatrixMode(GLenum mode)
3010 {
3011 TRACE("(GLenum mode = 0x%X)", mode);
3012
3013 es1::Context *context = es1::getContext();
3014
3015 if(context)
3016 {
3017 context->setMatrixMode(mode);
3018 }
3019 }
3020
MultMatrixf(const GLfloat * m)3021 void MultMatrixf(const GLfloat *m)
3022 {
3023 TRACE("(const GLfloat *m)");
3024
3025 es1::Context *context = es1::getContext();
3026
3027 if(context)
3028 {
3029 context->multiply(m);
3030 }
3031 }
3032
MultMatrixx(const GLfixed * m)3033 void MultMatrixx(const GLfixed *m)
3034 {
3035 GLfloat matrix[16] =
3036 {
3037 (float)m[0] / 0x10000, (float)m[1] / 0x10000, (float)m[2] / 0x10000, (float)m[3] / 0x10000,
3038 (float)m[4] / 0x10000, (float)m[5] / 0x10000, (float)m[6] / 0x10000, (float)m[7] / 0x10000,
3039 (float)m[8] / 0x10000, (float)m[9] / 0x10000, (float)m[10] / 0x10000, (float)m[11] / 0x10000,
3040 (float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
3041 };
3042
3043 MultMatrixf(matrix);
3044 }
3045
MultiTexCoord4f(GLenum target,GLfloat s,GLfloat t,GLfloat r,GLfloat q)3046 void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
3047 {
3048 TRACE("(GLenum target = 0x%X, GLfloat s = %f, GLfloat t = %f, GLfloat r = %f, GLfloat q = %f)", target, s, t, r, q);
3049
3050 switch(target)
3051 {
3052 case GL_TEXTURE0:
3053 case GL_TEXTURE1:
3054 break;
3055 default:
3056 return error(GL_INVALID_ENUM);
3057 }
3058
3059 es1::Context *context = es1::getContext();
3060
3061 if(context)
3062 {
3063 context->setVertexAttrib(sw::TexCoord0 + (target - GL_TEXTURE0), s, t, r, q);
3064 }
3065 }
3066
MultiTexCoord4x(GLenum target,GLfixed s,GLfixed t,GLfixed r,GLfixed q)3067 void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
3068 {
3069 UNIMPLEMENTED();
3070 }
3071
Normal3f(GLfloat nx,GLfloat ny,GLfloat nz)3072 void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
3073 {
3074 TRACE("(GLfloat nx, GLfloat ny, GLfloat nz)", nx, ny, nz);
3075
3076 es1::Context *context = es1::getContext();
3077
3078 if(context)
3079 {
3080 context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
3081 }
3082 }
3083
Normal3x(GLfixed nx,GLfixed ny,GLfixed nz)3084 void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz)
3085 {
3086 UNIMPLEMENTED();
3087 }
3088
NormalPointer(GLenum type,GLsizei stride,const GLvoid * pointer)3089 void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
3090 {
3091 TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);
3092
3093 VertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);
3094 }
3095
Orthof(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)3096 void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
3097 {
3098 TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar);
3099
3100 if(left == right || bottom == top || zNear == zFar)
3101 {
3102 return error(GL_INVALID_VALUE);
3103 }
3104
3105 es1::Context *context = es1::getContext();
3106
3107 if(context)
3108 {
3109 context->ortho(left, right, bottom, top, zNear, zFar);
3110 }
3111 }
3112
Orthox(GLfixed left,GLfixed right,GLfixed bottom,GLfixed top,GLfixed zNear,GLfixed zFar)3113 void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
3114 {
3115 Orthof((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);
3116 }
3117
PixelStorei(GLenum pname,GLint param)3118 void PixelStorei(GLenum pname, GLint param)
3119 {
3120 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
3121
3122 es1::Context *context = es1::getContext();
3123
3124 if(context)
3125 {
3126 switch(pname)
3127 {
3128 case GL_UNPACK_ALIGNMENT:
3129 if(param != 1 && param != 2 && param != 4 && param != 8)
3130 {
3131 return error(GL_INVALID_VALUE);
3132 }
3133
3134 context->setUnpackAlignment(param);
3135 break;
3136 case GL_PACK_ALIGNMENT:
3137 if(param != 1 && param != 2 && param != 4 && param != 8)
3138 {
3139 return error(GL_INVALID_VALUE);
3140 }
3141
3142 context->setPackAlignment(param);
3143 break;
3144 default:
3145 return error(GL_INVALID_ENUM);
3146 }
3147 }
3148 }
3149
PointParameterf(GLenum pname,GLfloat param)3150 void PointParameterf(GLenum pname, GLfloat param)
3151 {
3152 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
3153
3154 es1::Context *context = es1::getContext();
3155
3156 if(context)
3157 {
3158 switch(pname)
3159 {
3160 case GL_POINT_SIZE_MIN:
3161 if(param < 0.0f)
3162 {
3163 return error(GL_INVALID_VALUE);
3164 }
3165 context->setPointSizeMin(param);
3166 break;
3167 case GL_POINT_SIZE_MAX:
3168 if(param < 0.0f)
3169 {
3170 return error(GL_INVALID_VALUE);
3171 }
3172 context->setPointSizeMax(param);
3173 break;
3174 case GL_POINT_FADE_THRESHOLD_SIZE:
3175 if(param < 0.0f)
3176 {
3177 return error(GL_INVALID_VALUE);
3178 }
3179 context->setPointFadeThresholdSize(param);
3180 break;
3181 case GL_POINT_DISTANCE_ATTENUATION:
3182 return error(GL_INVALID_ENUM); // Needs three values, should call glPointParameterfv() instead
3183 default:
3184 return error(GL_INVALID_ENUM);
3185 }
3186 }
3187 }
3188
PointParameterfv(GLenum pname,const GLfloat * params)3189 void PointParameterfv(GLenum pname, const GLfloat *params)
3190 {
3191 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
3192
3193 es1::Context *context = es1::getContext();
3194
3195 if(context)
3196 {
3197 switch(pname)
3198 {
3199 case GL_POINT_SIZE_MIN:
3200 if(params[0] < 0.0f)
3201 {
3202 return error(GL_INVALID_VALUE);
3203 }
3204 context->setPointSizeMin(params[0]);
3205 break;
3206 case GL_POINT_SIZE_MAX:
3207 if(params[0] < 0.0f)
3208 {
3209 return error(GL_INVALID_VALUE);
3210 }
3211 context->setPointSizeMax(params[0]);
3212 break;
3213 case GL_POINT_DISTANCE_ATTENUATION:
3214 context->setPointDistanceAttenuation(params[0], params[1], params[2]);
3215 break;
3216 case GL_POINT_FADE_THRESHOLD_SIZE:
3217 if(params[0] < 0.0f)
3218 {
3219 return error(GL_INVALID_VALUE);
3220 }
3221 context->setPointFadeThresholdSize(params[0]);
3222 break;
3223 default:
3224 return error(GL_INVALID_ENUM);
3225 }
3226 }
3227 }
3228
PointParameterx(GLenum pname,GLfixed param)3229 void PointParameterx(GLenum pname, GLfixed param)
3230 {
3231 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
3232
3233 es1::Context *context = es1::getContext();
3234
3235 if(context)
3236 {
3237 switch(pname)
3238 {
3239 case GL_POINT_SIZE_MIN:
3240 if(param < 0)
3241 {
3242 return error(GL_INVALID_VALUE);
3243 }
3244 context->setPointSizeMin((float)param / 0x10000);
3245 break;
3246 case GL_POINT_SIZE_MAX:
3247 if(param < 0)
3248 {
3249 return error(GL_INVALID_VALUE);
3250 }
3251 context->setPointSizeMax((float)param / 0x10000);
3252 break;
3253 case GL_POINT_FADE_THRESHOLD_SIZE:
3254 if(param < 0)
3255 {
3256 return error(GL_INVALID_VALUE);
3257 }
3258 context->setPointFadeThresholdSize((float)param / 0x10000);
3259 break;
3260 case GL_POINT_DISTANCE_ATTENUATION:
3261 return error(GL_INVALID_ENUM); // Needs three parameters, should call glPointParameterxv() instead
3262 default:
3263 return error(GL_INVALID_ENUM);
3264 }
3265 }
3266 }
3267
PointParameterxv(GLenum pname,const GLfixed * params)3268 void PointParameterxv(GLenum pname, const GLfixed *params)
3269 {
3270 TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);
3271
3272 es1::Context *context = es1::getContext();
3273
3274 if(context)
3275 {
3276 switch(pname)
3277 {
3278 case GL_POINT_SIZE_MIN:
3279 if(params[0] < 0)
3280 {
3281 return error(GL_INVALID_VALUE);
3282 }
3283 context->setPointSizeMin((float)params[0] / 0x10000);
3284 break;
3285 case GL_POINT_SIZE_MAX:
3286 if(params[0] < 0)
3287 {
3288 return error(GL_INVALID_VALUE);
3289 }
3290 context->setPointSizeMax((float)params[0] / 0x10000);
3291 break;
3292 case GL_POINT_DISTANCE_ATTENUATION:
3293 context->setPointDistanceAttenuation((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000);
3294 break;
3295 case GL_POINT_FADE_THRESHOLD_SIZE:
3296 if(params[0] < 0)
3297 {
3298 return error(GL_INVALID_VALUE);
3299 }
3300 context->setPointFadeThresholdSize((float)params[0] / 0x10000);
3301 break;
3302 default:
3303 return error(GL_INVALID_ENUM);
3304 }
3305 }
3306 }
3307
PointSize(GLfloat size)3308 void PointSize(GLfloat size)
3309 {
3310 TRACE("(GLfloat size = %f)", size);
3311
3312 if(size <= 0)
3313 {
3314 return error(GL_INVALID_VALUE);
3315 }
3316
3317 es1::Context *context = es1::getContext();
3318
3319 if(context)
3320 {
3321 context->setVertexAttrib(sw::PointSize, size, size, size, size);
3322 }
3323 }
3324
PointSizePointerOES(GLenum type,GLsizei stride,const GLvoid * pointer)3325 void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
3326 {
3327 TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);
3328
3329 switch(type)
3330 {
3331 case GL_FIXED:
3332 case GL_FLOAT:
3333 break;
3334 default:
3335 return error(GL_INVALID_ENUM);
3336 }
3337
3338 VertexAttribPointer(sw::PointSize, 1, type, true, stride, pointer);
3339 }
3340
PointSizex(GLfixed size)3341 void PointSizex(GLfixed size)
3342 {
3343 PointSize((float)size / 0x10000);
3344 }
3345
PolygonOffset(GLfloat factor,GLfloat units)3346 void PolygonOffset(GLfloat factor, GLfloat units)
3347 {
3348 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
3349
3350 es1::Context *context = es1::getContext();
3351
3352 if(context)
3353 {
3354 context->setPolygonOffsetParams(factor, units);
3355 }
3356 }
3357
PolygonOffsetx(GLfixed factor,GLfixed units)3358 void PolygonOffsetx(GLfixed factor, GLfixed units)
3359 {
3360 PolygonOffset((float)factor / 0x10000, (float)units / 0x10000);
3361 }
3362
PopMatrix(void)3363 void PopMatrix(void)
3364 {
3365 TRACE("()");
3366
3367 es1::Context *context = es1::getContext();
3368
3369 if(context)
3370 {
3371 context->popMatrix();
3372 }
3373 }
3374
PushMatrix(void)3375 void PushMatrix(void)
3376 {
3377 TRACE("()");
3378
3379 es1::Context *context = es1::getContext();
3380
3381 if(context)
3382 {
3383 context->pushMatrix();
3384 }
3385 }
3386
ReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)3387 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
3388 {
3389 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
3390 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
3391 x, y, width, height, format, type, pixels);
3392
3393 if(width < 0 || height < 0)
3394 {
3395 return error(GL_INVALID_VALUE);
3396 }
3397
3398 es1::Context *context = es1::getContext();
3399
3400 if(context)
3401 {
3402 context->readPixels(x, y, width, height, format, type, nullptr, pixels);
3403 }
3404 }
3405
RenderbufferStorageOES(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)3406 void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3407 {
3408 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3409 target, internalformat, width, height);
3410
3411 switch(target)
3412 {
3413 case GL_RENDERBUFFER_OES:
3414 break;
3415 default:
3416 return error(GL_INVALID_ENUM);
3417 }
3418
3419 if(!es1::IsColorRenderable(internalformat) && !es1::IsDepthRenderable(internalformat) && !es1::IsStencilRenderable(internalformat))
3420 {
3421 return error(GL_INVALID_ENUM);
3422 }
3423
3424 if(width < 0 || height < 0)
3425 {
3426 return error(GL_INVALID_VALUE);
3427 }
3428
3429 es1::Context *context = es1::getContext();
3430
3431 if(context)
3432 {
3433 if(width > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
3434 height > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
3435 {
3436 return error(GL_INVALID_VALUE);
3437 }
3438
3439 GLuint handle = context->getRenderbufferName();
3440 if(handle == 0)
3441 {
3442 return error(GL_INVALID_OPERATION);
3443 }
3444
3445 switch(internalformat)
3446 {
3447 case GL_DEPTH_COMPONENT16_OES:
3448 context->setRenderbufferStorage(new es1::Depthbuffer(width, height, 0));
3449 break;
3450 case GL_RGBA4_OES:
3451 case GL_RGB5_A1_OES:
3452 case GL_RGB565_OES:
3453 case GL_RGB8_OES:
3454 case GL_RGBA8_OES:
3455 context->setRenderbufferStorage(new es1::Colorbuffer(width, height, internalformat, 0));
3456 break;
3457 case GL_STENCIL_INDEX8_OES:
3458 context->setRenderbufferStorage(new es1::Stencilbuffer(width, height, 0));
3459 break;
3460 case GL_DEPTH24_STENCIL8_OES:
3461 context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, 0));
3462 break;
3463 default:
3464 return error(GL_INVALID_ENUM);
3465 }
3466 }
3467 }
3468
Rotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z)3469 void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3470 {
3471 TRACE("(GLfloat angle = %f, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", angle, x, y, z);
3472
3473 es1::Context *context = es1::getContext();
3474
3475 if(context)
3476 {
3477 context->rotate(angle, x, y, z);
3478 }
3479 }
3480
Rotatex(GLfixed angle,GLfixed x,GLfixed y,GLfixed z)3481 void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
3482 {
3483 Rotatef((float)angle / 0x10000, (float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
3484 }
3485
SampleCoverage(GLclampf value,GLboolean invert)3486 void SampleCoverage(GLclampf value, GLboolean invert)
3487 {
3488 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
3489
3490 es1::Context* context = es1::getContext();
3491
3492 if(context)
3493 {
3494 context->setSampleCoverageParams(es1::clamp01(value), invert == GL_TRUE);
3495 }
3496 }
3497
SampleCoveragex(GLclampx value,GLboolean invert)3498 void SampleCoveragex(GLclampx value, GLboolean invert)
3499 {
3500 SampleCoverage((float)value / 0x10000, invert);
3501 }
3502
Scalef(GLfloat x,GLfloat y,GLfloat z)3503 void Scalef(GLfloat x, GLfloat y, GLfloat z)
3504 {
3505 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
3506
3507 es1::Context *context = es1::getContext();
3508
3509 if(context)
3510 {
3511 context->scale(x, y, z);
3512 }
3513 }
3514
Scalex(GLfixed x,GLfixed y,GLfixed z)3515 void Scalex(GLfixed x, GLfixed y, GLfixed z)
3516 {
3517 Scalef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
3518 }
3519
Scissor(GLint x,GLint y,GLsizei width,GLsizei height)3520 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3521 {
3522 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
3523
3524 if(width < 0 || height < 0)
3525 {
3526 return error(GL_INVALID_VALUE);
3527 }
3528
3529 es1::Context* context = es1::getContext();
3530
3531 if(context)
3532 {
3533 context->setScissorParams(x, y, width, height);
3534 }
3535 }
3536
ShadeModel(GLenum mode)3537 void ShadeModel(GLenum mode)
3538 {
3539 switch(mode)
3540 {
3541 case GL_FLAT:
3542 case GL_SMOOTH:
3543 break;
3544 default:
3545 return error(GL_INVALID_ENUM);
3546 }
3547
3548 es1::Context *context = es1::getContext();
3549
3550 if(context)
3551 {
3552 context->setShadeModel(mode);
3553 }
3554 }
3555
StencilFunc(GLenum func,GLint ref,GLuint mask)3556 void StencilFunc(GLenum func, GLint ref, GLuint mask)
3557 {
3558 TRACE("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", func, ref, mask);
3559
3560 switch(func)
3561 {
3562 case GL_NEVER:
3563 case GL_ALWAYS:
3564 case GL_LESS:
3565 case GL_LEQUAL:
3566 case GL_EQUAL:
3567 case GL_GEQUAL:
3568 case GL_GREATER:
3569 case GL_NOTEQUAL:
3570 break;
3571 default:
3572 return error(GL_INVALID_ENUM);
3573 }
3574
3575 es1::Context *context = es1::getContext();
3576
3577 if(context)
3578 {
3579 context->setStencilParams(func, ref, mask);
3580 }
3581 }
3582
StencilMask(GLuint mask)3583 void StencilMask(GLuint mask)
3584 {
3585 TRACE("(GLuint mask = %d)", mask);
3586
3587 es1::Context *context = es1::getContext();
3588
3589 if(context)
3590 {
3591 context->setStencilWritemask(mask);
3592 }
3593 }
3594
StencilOp(GLenum fail,GLenum zfail,GLenum zpass)3595 void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3596 {
3597 TRACE("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", fail, zfail, zpass);
3598
3599 switch(fail)
3600 {
3601 case GL_ZERO:
3602 case GL_KEEP:
3603 case GL_REPLACE:
3604 case GL_INCR:
3605 case GL_DECR:
3606 case GL_INVERT:
3607 case GL_INCR_WRAP_OES:
3608 case GL_DECR_WRAP_OES:
3609 break;
3610 default:
3611 return error(GL_INVALID_ENUM);
3612 }
3613
3614 switch(zfail)
3615 {
3616 case GL_ZERO:
3617 case GL_KEEP:
3618 case GL_REPLACE:
3619 case GL_INCR:
3620 case GL_DECR:
3621 case GL_INVERT:
3622 case GL_INCR_WRAP_OES:
3623 case GL_DECR_WRAP_OES:
3624 break;
3625 default:
3626 return error(GL_INVALID_ENUM);
3627 }
3628
3629 switch(zpass)
3630 {
3631 case GL_ZERO:
3632 case GL_KEEP:
3633 case GL_REPLACE:
3634 case GL_INCR:
3635 case GL_DECR:
3636 case GL_INVERT:
3637 case GL_INCR_WRAP_OES:
3638 case GL_DECR_WRAP_OES:
3639 break;
3640 default:
3641 return error(GL_INVALID_ENUM);
3642 }
3643
3644 es1::Context *context = es1::getContext();
3645
3646 if(context)
3647 {
3648 context->setStencilOperations(fail, zfail, zpass);
3649 }
3650 }
3651
TexCoordPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)3652 void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
3653 {
3654 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
3655
3656 if(size < 2 || size > 4)
3657 {
3658 return error(GL_INVALID_VALUE);
3659 }
3660
3661 es1::Context *context = es1::getContext();
3662
3663 if(context)
3664 {
3665 GLenum texture = context->getClientActiveTexture();
3666 VertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
3667 }
3668 }
3669
3670 void TexEnvi(GLenum target, GLenum pname, GLint param);
3671
TexEnvf(GLenum target,GLenum pname,GLfloat param)3672 void TexEnvf(GLenum target, GLenum pname, GLfloat param)
3673 {
3674 TexEnvi(target, pname, (GLint)param);
3675 }
3676
TexEnvfv(GLenum target,GLenum pname,const GLfloat * params)3677 void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
3678 {
3679 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params)", target, pname);
3680
3681 es1::Context *context = es1::getContext();
3682
3683 if(context)
3684 {
3685 GLint iParam = (GLint)roundf(params[0]);
3686
3687 switch(target)
3688 {
3689 case GL_POINT_SPRITE_OES:
3690 UNIMPLEMENTED();
3691 break;
3692 case GL_TEXTURE_ENV:
3693 switch(pname)
3694 {
3695 case GL_TEXTURE_ENV_MODE:
3696 switch(iParam)
3697 {
3698 case GL_REPLACE:
3699 case GL_MODULATE:
3700 case GL_DECAL:
3701 case GL_BLEND:
3702 case GL_ADD:
3703 case GL_COMBINE:
3704 break;
3705 default:
3706 error(GL_INVALID_ENUM);
3707 }
3708
3709 context->setTextureEnvMode(iParam);
3710 break;
3711 case GL_TEXTURE_ENV_COLOR:
3712 context->setTextureEnvColor(clamp01(params[0]), clamp01(params[1]), clamp01(params[2]), clamp01(params[3]));
3713 break;
3714 case GL_COMBINE_RGB:
3715 switch(iParam)
3716 {
3717 case GL_REPLACE:
3718 case GL_MODULATE:
3719 case GL_ADD:
3720 case GL_ADD_SIGNED:
3721 case GL_INTERPOLATE:
3722 case GL_SUBTRACT:
3723 case GL_DOT3_RGB:
3724 case GL_DOT3_RGBA:
3725 break;
3726 default:
3727 error(GL_INVALID_ENUM);
3728 }
3729
3730 context->setCombineRGB(iParam);
3731 break;
3732 case GL_COMBINE_ALPHA:
3733 switch(iParam)
3734 {
3735 case GL_REPLACE:
3736 case GL_MODULATE:
3737 case GL_ADD:
3738 case GL_ADD_SIGNED:
3739 case GL_INTERPOLATE:
3740 case GL_SUBTRACT:
3741 break;
3742 default:
3743 error(GL_INVALID_ENUM);
3744 }
3745
3746 context->setCombineAlpha(iParam);
3747 break;
3748 case GL_RGB_SCALE:
3749 if(iParam != 1 && iParam != 2 && iParam != 4)
3750 {
3751 return error(GL_INVALID_VALUE);
3752 }
3753 if(iParam != 1) UNIMPLEMENTED();
3754 break;
3755 case GL_ALPHA_SCALE:
3756 if(iParam != 1 && iParam != 2 && iParam != 4)
3757 {
3758 return error(GL_INVALID_VALUE);
3759 }
3760 if(iParam != 1) UNIMPLEMENTED();
3761 break;
3762 case GL_OPERAND0_RGB:
3763 switch(iParam)
3764 {
3765 case GL_SRC_COLOR:
3766 case GL_ONE_MINUS_SRC_COLOR:
3767 case GL_SRC_ALPHA:
3768 case GL_ONE_MINUS_SRC_ALPHA:
3769 break;
3770 default:
3771 error(GL_INVALID_ENUM);
3772 }
3773
3774 context->setOperand0RGB(iParam);
3775 break;
3776 case GL_OPERAND1_RGB:
3777 switch(iParam)
3778 {
3779 case GL_SRC_COLOR:
3780 case GL_ONE_MINUS_SRC_COLOR:
3781 case GL_SRC_ALPHA:
3782 case GL_ONE_MINUS_SRC_ALPHA:
3783 break;
3784 default:
3785 error(GL_INVALID_ENUM);
3786 }
3787
3788 context->setOperand1RGB(iParam);
3789 break;
3790 case GL_OPERAND2_RGB:
3791 switch(iParam)
3792 {
3793 case GL_SRC_COLOR:
3794 case GL_ONE_MINUS_SRC_COLOR:
3795 case GL_SRC_ALPHA:
3796 case GL_ONE_MINUS_SRC_ALPHA:
3797 break;
3798 default:
3799 error(GL_INVALID_ENUM);
3800 }
3801
3802 context->setOperand2RGB(iParam);
3803 break;
3804 case GL_OPERAND0_ALPHA:
3805 switch(iParam)
3806 {
3807 case GL_SRC_ALPHA:
3808 case GL_ONE_MINUS_SRC_ALPHA:
3809 break;
3810 default:
3811 error(GL_INVALID_ENUM);
3812 }
3813
3814 context->setOperand0Alpha(iParam);
3815 break;
3816 case GL_OPERAND1_ALPHA:
3817 switch(iParam)
3818 {
3819 case GL_SRC_ALPHA:
3820 case GL_ONE_MINUS_SRC_ALPHA:
3821 break;
3822 default:
3823 error(GL_INVALID_ENUM);
3824 }
3825
3826 context->setOperand1Alpha(iParam);
3827 break;
3828 case GL_OPERAND2_ALPHA:
3829 switch(iParam)
3830 {
3831 case GL_SRC_ALPHA:
3832 case GL_ONE_MINUS_SRC_ALPHA:
3833 break;
3834 default:
3835 error(GL_INVALID_ENUM);
3836 }
3837
3838 context->setOperand2Alpha(iParam);
3839 break;
3840 case GL_SRC0_RGB:
3841 switch(iParam)
3842 {
3843 case GL_TEXTURE:
3844 case GL_CONSTANT:
3845 case GL_PRIMARY_COLOR:
3846 case GL_PREVIOUS:
3847 break;
3848 default:
3849 error(GL_INVALID_ENUM);
3850 }
3851
3852 context->setSrc0RGB(iParam);
3853 break;
3854 case GL_SRC1_RGB:
3855 switch(iParam)
3856 {
3857 case GL_TEXTURE:
3858 case GL_CONSTANT:
3859 case GL_PRIMARY_COLOR:
3860 case GL_PREVIOUS:
3861 break;
3862 default:
3863 error(GL_INVALID_ENUM);
3864 }
3865
3866 context->setSrc1RGB(iParam);
3867 break;
3868 case GL_SRC2_RGB:
3869 switch(iParam)
3870 {
3871 case GL_TEXTURE:
3872 case GL_CONSTANT:
3873 case GL_PRIMARY_COLOR:
3874 case GL_PREVIOUS:
3875 break;
3876 default:
3877 error(GL_INVALID_ENUM);
3878 }
3879
3880 context->setSrc2RGB(iParam);
3881 break;
3882 case GL_SRC0_ALPHA:
3883 switch(iParam)
3884 {
3885 case GL_TEXTURE:
3886 case GL_CONSTANT:
3887 case GL_PRIMARY_COLOR:
3888 case GL_PREVIOUS:
3889 break;
3890 default:
3891 error(GL_INVALID_ENUM);
3892 }
3893
3894 context->setSrc0Alpha(iParam);
3895 break;
3896 case GL_SRC1_ALPHA:
3897 switch(iParam)
3898 {
3899 case GL_TEXTURE:
3900 case GL_CONSTANT:
3901 case GL_PRIMARY_COLOR:
3902 case GL_PREVIOUS:
3903 break;
3904 default:
3905 error(GL_INVALID_ENUM);
3906 }
3907
3908 context->setSrc1Alpha(iParam);
3909 break;
3910 case GL_SRC2_ALPHA:
3911 switch(iParam)
3912 {
3913 case GL_TEXTURE:
3914 case GL_CONSTANT:
3915 case GL_PRIMARY_COLOR:
3916 case GL_PREVIOUS:
3917 break;
3918 default:
3919 error(GL_INVALID_ENUM);
3920 }
3921
3922 context->setSrc2Alpha(iParam);
3923 break;
3924 default:
3925 return error(GL_INVALID_ENUM);
3926 }
3927 break;
3928 default:
3929 return error(GL_INVALID_ENUM);
3930 }
3931 }
3932 }
3933
TexEnvi(GLenum target,GLenum pname,GLint param)3934 void TexEnvi(GLenum target, GLenum pname, GLint param)
3935 {
3936 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
3937
3938 es1::Context *context = es1::getContext();
3939
3940 if(context)
3941 {
3942 switch(target)
3943 {
3944 case GL_POINT_SPRITE_OES:
3945 UNIMPLEMENTED();
3946 break;
3947 case GL_TEXTURE_ENV:
3948 switch(pname)
3949 {
3950 case GL_TEXTURE_ENV_MODE:
3951 switch((GLenum)param)
3952 {
3953 case GL_REPLACE:
3954 case GL_MODULATE:
3955 case GL_DECAL:
3956 case GL_BLEND:
3957 case GL_ADD:
3958 case GL_COMBINE:
3959 break;
3960 default:
3961 error(GL_INVALID_ENUM);
3962 }
3963
3964 context->setTextureEnvMode((GLenum)param);
3965 break;
3966 case GL_TEXTURE_ENV_COLOR:
3967 return error(GL_INVALID_ENUM); // Needs four values, should call glTexEnviv() instead
3968 break;
3969 case GL_COMBINE_RGB:
3970 switch((GLenum)param)
3971 {
3972 case GL_REPLACE:
3973 case GL_MODULATE:
3974 case GL_ADD:
3975 case GL_ADD_SIGNED:
3976 case GL_INTERPOLATE:
3977 case GL_SUBTRACT:
3978 case GL_DOT3_RGB:
3979 case GL_DOT3_RGBA:
3980 break;
3981 default:
3982 error(GL_INVALID_ENUM);
3983 }
3984
3985 context->setCombineRGB((GLenum)param);
3986 break;
3987 case GL_COMBINE_ALPHA:
3988 switch((GLenum)param)
3989 {
3990 case GL_REPLACE:
3991 case GL_MODULATE:
3992 case GL_ADD:
3993 case GL_ADD_SIGNED:
3994 case GL_INTERPOLATE:
3995 case GL_SUBTRACT:
3996 break;
3997 default:
3998 error(GL_INVALID_ENUM);
3999 }
4000
4001 context->setCombineAlpha((GLenum)param);
4002 break;
4003 case GL_RGB_SCALE:
4004 if(param != 1 && param != 2 && param != 4)
4005 {
4006 return error(GL_INVALID_VALUE);
4007 }
4008 if(param != 1) UNIMPLEMENTED();
4009 break;
4010 case GL_ALPHA_SCALE:
4011 if(param != 1 && param != 2 && param != 4)
4012 {
4013 return error(GL_INVALID_VALUE);
4014 }
4015 if(param != 1) UNIMPLEMENTED();
4016 break;
4017 case GL_OPERAND0_RGB:
4018 switch((GLenum)param)
4019 {
4020 case GL_SRC_COLOR:
4021 case GL_ONE_MINUS_SRC_COLOR:
4022 case GL_SRC_ALPHA:
4023 case GL_ONE_MINUS_SRC_ALPHA:
4024 break;
4025 default:
4026 error(GL_INVALID_ENUM);
4027 }
4028
4029 context->setOperand0RGB((GLenum)param);
4030 break;
4031 case GL_OPERAND1_RGB:
4032 switch((GLenum)param)
4033 {
4034 case GL_SRC_COLOR:
4035 case GL_ONE_MINUS_SRC_COLOR:
4036 case GL_SRC_ALPHA:
4037 case GL_ONE_MINUS_SRC_ALPHA:
4038 break;
4039 default:
4040 error(GL_INVALID_ENUM);
4041 }
4042
4043 context->setOperand1RGB((GLenum)param);
4044 break;
4045 case GL_OPERAND2_RGB:
4046 switch((GLenum)param)
4047 {
4048 case GL_SRC_COLOR:
4049 case GL_ONE_MINUS_SRC_COLOR:
4050 case GL_SRC_ALPHA:
4051 case GL_ONE_MINUS_SRC_ALPHA:
4052 break;
4053 default:
4054 error(GL_INVALID_ENUM);
4055 }
4056
4057 context->setOperand2RGB((GLenum)param);
4058 break;
4059 case GL_OPERAND0_ALPHA:
4060 switch((GLenum)param)
4061 {
4062 case GL_SRC_ALPHA:
4063 case GL_ONE_MINUS_SRC_ALPHA:
4064 break;
4065 default:
4066 error(GL_INVALID_ENUM);
4067 }
4068
4069 context->setOperand0Alpha((GLenum)param);
4070 break;
4071 case GL_OPERAND1_ALPHA:
4072 switch((GLenum)param)
4073 {
4074 case GL_SRC_ALPHA:
4075 case GL_ONE_MINUS_SRC_ALPHA:
4076 break;
4077 default:
4078 error(GL_INVALID_ENUM);
4079 }
4080
4081 context->setOperand1Alpha((GLenum)param);
4082 break;
4083 case GL_OPERAND2_ALPHA:
4084 switch((GLenum)param)
4085 {
4086 case GL_SRC_ALPHA:
4087 case GL_ONE_MINUS_SRC_ALPHA:
4088 break;
4089 default:
4090 error(GL_INVALID_ENUM);
4091 }
4092
4093 context->setOperand2Alpha((GLenum)param);
4094 break;
4095 case GL_SRC0_RGB:
4096 switch((GLenum)param)
4097 {
4098 case GL_TEXTURE:
4099 case GL_CONSTANT:
4100 case GL_PRIMARY_COLOR:
4101 case GL_PREVIOUS:
4102 break;
4103 default:
4104 error(GL_INVALID_ENUM);
4105 }
4106
4107 context->setSrc0RGB((GLenum)param);
4108 break;
4109 case GL_SRC1_RGB:
4110 switch((GLenum)param)
4111 {
4112 case GL_TEXTURE:
4113 case GL_CONSTANT:
4114 case GL_PRIMARY_COLOR:
4115 case GL_PREVIOUS:
4116 break;
4117 default:
4118 error(GL_INVALID_ENUM);
4119 }
4120
4121 context->setSrc1RGB((GLenum)param);
4122 break;
4123 case GL_SRC2_RGB:
4124 switch((GLenum)param)
4125 {
4126 case GL_TEXTURE:
4127 case GL_CONSTANT:
4128 case GL_PRIMARY_COLOR:
4129 case GL_PREVIOUS:
4130 break;
4131 default:
4132 error(GL_INVALID_ENUM);
4133 }
4134
4135 context->setSrc2RGB((GLenum)param);
4136 break;
4137 case GL_SRC0_ALPHA:
4138 switch((GLenum)param)
4139 {
4140 case GL_TEXTURE:
4141 case GL_CONSTANT:
4142 case GL_PRIMARY_COLOR:
4143 case GL_PREVIOUS:
4144 break;
4145 default:
4146 error(GL_INVALID_ENUM);
4147 }
4148
4149 context->setSrc0Alpha((GLenum)param);
4150 break;
4151 case GL_SRC1_ALPHA:
4152 switch((GLenum)param)
4153 {
4154 case GL_TEXTURE:
4155 case GL_CONSTANT:
4156 case GL_PRIMARY_COLOR:
4157 case GL_PREVIOUS:
4158 break;
4159 default:
4160 error(GL_INVALID_ENUM);
4161 }
4162
4163 context->setSrc1Alpha((GLenum)param);
4164 break;
4165 case GL_SRC2_ALPHA:
4166 switch((GLenum)param)
4167 {
4168 case GL_TEXTURE:
4169 case GL_CONSTANT:
4170 case GL_PRIMARY_COLOR:
4171 case GL_PREVIOUS:
4172 break;
4173 default:
4174 error(GL_INVALID_ENUM);
4175 }
4176
4177 context->setSrc2Alpha((GLenum)param);
4178 break;
4179 default:
4180 return error(GL_INVALID_ENUM);
4181 }
4182 break;
4183 default:
4184 return error(GL_INVALID_ENUM);
4185 }
4186 }
4187 }
4188
TexEnvx(GLenum target,GLenum pname,GLfixed param)4189 void TexEnvx(GLenum target, GLenum pname, GLfixed param)
4190 {
4191 TexEnvi(target, pname, (GLint)param);
4192 }
4193
TexEnviv(GLenum target,GLenum pname,const GLint * params)4194 void TexEnviv(GLenum target, GLenum pname, const GLint *params)
4195 {
4196 UNIMPLEMENTED();
4197 }
4198
TexEnvxv(GLenum target,GLenum pname,const GLfixed * params)4199 void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
4200 {
4201 UNIMPLEMENTED();
4202 }
4203
TexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)4204 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4205 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4206 {
4207 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
4208 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)",
4209 target, level, internalformat, width, height, border, format, type, pixels);
4210
4211 if(!validImageSize(level, width, height))
4212 {
4213 return error(GL_INVALID_VALUE);
4214 }
4215
4216 if(internalformat != (GLint)format)
4217 {
4218 return error(GL_INVALID_OPERATION);
4219 }
4220
4221 switch(format)
4222 {
4223 case GL_ALPHA:
4224 case GL_LUMINANCE:
4225 case GL_LUMINANCE_ALPHA:
4226 switch(type)
4227 {
4228 case GL_UNSIGNED_BYTE:
4229 case GL_FLOAT:
4230 break;
4231 default:
4232 return error(GL_INVALID_ENUM);
4233 }
4234 break;
4235 case GL_RGB:
4236 switch(type)
4237 {
4238 case GL_UNSIGNED_BYTE:
4239 case GL_UNSIGNED_SHORT_5_6_5:
4240 case GL_FLOAT:
4241 break;
4242 default:
4243 return error(GL_INVALID_ENUM);
4244 }
4245 break;
4246 case GL_RGBA:
4247 switch(type)
4248 {
4249 case GL_UNSIGNED_BYTE:
4250 case GL_UNSIGNED_SHORT_4_4_4_4:
4251 case GL_UNSIGNED_SHORT_5_5_5_1:
4252 case GL_FLOAT:
4253 break;
4254 default:
4255 return error(GL_INVALID_ENUM);
4256 }
4257 break;
4258 case GL_BGRA_EXT:
4259 switch(type)
4260 {
4261 case GL_UNSIGNED_BYTE:
4262 break;
4263 default:
4264 return error(GL_INVALID_ENUM);
4265 }
4266 break;
4267 case GL_ETC1_RGB8_OES:
4268 return error(GL_INVALID_OPERATION);
4269 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
4270 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4271 if(S3TC_SUPPORT)
4272 {
4273 return error(GL_INVALID_OPERATION);
4274 }
4275 else
4276 {
4277 return error(GL_INVALID_ENUM);
4278 }
4279 case GL_DEPTH_STENCIL_OES:
4280 switch(type)
4281 {
4282 case GL_UNSIGNED_INT_24_8_OES:
4283 break;
4284 default:
4285 return error(GL_INVALID_ENUM);
4286 }
4287 break;
4288 default:
4289 return error(GL_INVALID_VALUE);
4290 }
4291
4292 if(border != 0)
4293 {
4294 return error(GL_INVALID_VALUE);
4295 }
4296
4297 es1::Context *context = es1::getContext();
4298
4299 if(context)
4300 {
4301 switch(target)
4302 {
4303 case GL_TEXTURE_2D:
4304 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4305 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4306 {
4307 return error(GL_INVALID_VALUE);
4308 }
4309 break;
4310 default:
4311 return error(GL_INVALID_ENUM);
4312 }
4313
4314 if(target == GL_TEXTURE_2D)
4315 {
4316 es1::Texture2D *texture = context->getTexture2D();
4317
4318 if(!texture)
4319 {
4320 return error(GL_INVALID_OPERATION);
4321 }
4322
4323 texture->setImage(context, level, width, height, format, type, context->getUnpackAlignment(), pixels);
4324 }
4325 else UNREACHABLE(target);
4326 }
4327 }
4328
TexParameterf(GLenum target,GLenum pname,GLfloat param)4329 void TexParameterf(GLenum target, GLenum pname, GLfloat param)
4330 {
4331 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
4332
4333 es1::Context *context = es1::getContext();
4334
4335 if(context)
4336 {
4337 es1::Texture *texture;
4338
4339 switch(target)
4340 {
4341 case GL_TEXTURE_2D:
4342 texture = context->getTexture2D();
4343 break;
4344 case GL_TEXTURE_EXTERNAL_OES:
4345 texture = context->getTextureExternal();
4346 break;
4347 default:
4348 return error(GL_INVALID_ENUM);
4349 }
4350
4351 switch(pname)
4352 {
4353 case GL_TEXTURE_WRAP_S:
4354 if(!texture->setWrapS((GLenum)param))
4355 {
4356 return error(GL_INVALID_ENUM);
4357 }
4358 break;
4359 case GL_TEXTURE_WRAP_T:
4360 if(!texture->setWrapT((GLenum)param))
4361 {
4362 return error(GL_INVALID_ENUM);
4363 }
4364 break;
4365 case GL_TEXTURE_MIN_FILTER:
4366 if(!texture->setMinFilter((GLenum)param))
4367 {
4368 return error(GL_INVALID_ENUM);
4369 }
4370 break;
4371 case GL_TEXTURE_MAG_FILTER:
4372 if(!texture->setMagFilter((GLenum)param))
4373 {
4374 return error(GL_INVALID_ENUM);
4375 }
4376 break;
4377 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4378 if(!texture->setMaxAnisotropy(param))
4379 {
4380 return error(GL_INVALID_VALUE);
4381 }
4382 break;
4383 case GL_GENERATE_MIPMAP:
4384 texture->setGenerateMipmap((GLboolean)param);
4385 break;
4386 case GL_TEXTURE_CROP_RECT_OES:
4387 return error(GL_INVALID_ENUM); // Needs four values, should call glTexParameterfv() instead
4388 default:
4389 return error(GL_INVALID_ENUM);
4390 }
4391 }
4392 }
4393
TexParameterfv(GLenum target,GLenum pname,const GLfloat * params)4394 void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4395 {
4396 TexParameterf(target, pname, *params);
4397 }
4398
TexParameteri(GLenum target,GLenum pname,GLint param)4399 void TexParameteri(GLenum target, GLenum pname, GLint param)
4400 {
4401 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
4402
4403 es1::Context *context = es1::getContext();
4404
4405 if(context)
4406 {
4407 es1::Texture *texture;
4408
4409 switch(target)
4410 {
4411 case GL_TEXTURE_2D:
4412 texture = context->getTexture2D();
4413 break;
4414 case GL_TEXTURE_EXTERNAL_OES:
4415 texture = context->getTextureExternal();
4416 break;
4417 default:
4418 return error(GL_INVALID_ENUM);
4419 }
4420
4421 switch(pname)
4422 {
4423 case GL_TEXTURE_WRAP_S:
4424 if(!texture->setWrapS((GLenum)param))
4425 {
4426 return error(GL_INVALID_ENUM);
4427 }
4428 break;
4429 case GL_TEXTURE_WRAP_T:
4430 if(!texture->setWrapT((GLenum)param))
4431 {
4432 return error(GL_INVALID_ENUM);
4433 }
4434 break;
4435 case GL_TEXTURE_MIN_FILTER:
4436 if(!texture->setMinFilter((GLenum)param))
4437 {
4438 return error(GL_INVALID_ENUM);
4439 }
4440 break;
4441 case GL_TEXTURE_MAG_FILTER:
4442 if(!texture->setMagFilter((GLenum)param))
4443 {
4444 return error(GL_INVALID_ENUM);
4445 }
4446 break;
4447 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4448 if(!texture->setMaxAnisotropy((GLfloat)param))
4449 {
4450 return error(GL_INVALID_VALUE);
4451 }
4452 break;
4453 case GL_GENERATE_MIPMAP:
4454 texture->setGenerateMipmap((GLboolean)param);
4455 break;
4456 case GL_TEXTURE_CROP_RECT_OES:
4457 return error(GL_INVALID_ENUM); // Needs four values, should call glTexParameteriv() instead
4458 default:
4459 return error(GL_INVALID_ENUM);
4460 }
4461 }
4462 }
4463
TexParameteriv(GLenum target,GLenum pname,const GLint * params)4464 void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
4465 {
4466 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %p)", target, pname, params);
4467
4468 switch(pname)
4469 {
4470 case GL_TEXTURE_CROP_RECT_OES:
4471 break;
4472 default:
4473 return TexParameteri(target, pname, params[0]);
4474 }
4475
4476 es1::Context *context = es1::getContext();
4477
4478 if(context)
4479 {
4480 es1::Texture *texture;
4481
4482 switch(target)
4483 {
4484 case GL_TEXTURE_2D:
4485 texture = context->getTexture2D();
4486 break;
4487 default:
4488 return error(GL_INVALID_ENUM);
4489 }
4490
4491 switch(pname)
4492 {
4493 case GL_TEXTURE_CROP_RECT_OES:
4494 texture->setCropRect(params[0], params[1], params[2], params[3]);
4495 break;
4496 default:
4497 return error(GL_INVALID_ENUM);
4498 }
4499 }
4500 }
4501
TexParameterx(GLenum target,GLenum pname,GLfixed param)4502 void TexParameterx(GLenum target, GLenum pname, GLfixed param)
4503 {
4504 TexParameteri(target, pname, (GLint)param);
4505 }
4506
TexParameterxv(GLenum target,GLenum pname,const GLfixed * params)4507 void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
4508 {
4509 UNIMPLEMENTED();
4510 }
4511
TexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)4512 void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4513 GLenum format, GLenum type, const GLvoid* pixels)
4514 {
4515 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4516 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
4517 "const GLvoid* pixels = %p)",
4518 target, level, xoffset, yoffset, width, height, format, type, pixels);
4519
4520 if(!es1::IsTextureTarget(target))
4521 {
4522 return error(GL_INVALID_ENUM);
4523 }
4524
4525 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
4526 {
4527 return error(GL_INVALID_VALUE);
4528 }
4529
4530 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
4531 {
4532 return error(GL_INVALID_VALUE);
4533 }
4534
4535 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4536 {
4537 return error(GL_INVALID_VALUE);
4538 }
4539
4540 if(!es1::CheckTextureFormatType(format, type))
4541 {
4542 return error(GL_INVALID_ENUM);
4543 }
4544
4545 if(width == 0 || height == 0 || !pixels)
4546 {
4547 return;
4548 }
4549
4550 es1::Context *context = es1::getContext();
4551
4552 if(context)
4553 {
4554 if(target == GL_TEXTURE_2D)
4555 {
4556 es1::Texture2D *texture = context->getTexture2D();
4557
4558 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
4559 {
4560 texture->subImage(context, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4561 }
4562 }
4563 else UNREACHABLE(target);
4564 }
4565 }
4566
Translatef(GLfloat x,GLfloat y,GLfloat z)4567 void Translatef(GLfloat x, GLfloat y, GLfloat z)
4568 {
4569 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
4570
4571 es1::Context *context = es1::getContext();
4572
4573 if(context)
4574 {
4575 context->translate(x, y, z);
4576 }
4577 }
4578
Translatex(GLfixed x,GLfixed y,GLfixed z)4579 void Translatex(GLfixed x, GLfixed y, GLfixed z)
4580 {
4581 Translatef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
4582 }
4583
VertexPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)4584 void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
4585 {
4586 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
4587
4588 if(size < 2 || size > 4)
4589 {
4590 return error(GL_INVALID_VALUE);
4591 }
4592
4593 VertexAttribPointer(sw::Position, size, type, false, stride, pointer);
4594 }
4595
Viewport(GLint x,GLint y,GLsizei width,GLsizei height)4596 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
4597 {
4598 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4599
4600 if(width < 0 || height < 0)
4601 {
4602 return error(GL_INVALID_VALUE);
4603 }
4604
4605 es1::Context *context = es1::getContext();
4606
4607 if(context)
4608 {
4609 context->setViewportParams(x, y, width, height);
4610 }
4611 }
4612
EGLImageTargetTexture2DOES(GLenum target,GLeglImageOES image)4613 void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
4614 {
4615 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
4616
4617 switch(target)
4618 {
4619 case GL_TEXTURE_2D:
4620 case GL_TEXTURE_EXTERNAL_OES:
4621 break;
4622 default:
4623 return error(GL_INVALID_ENUM);
4624 }
4625
4626 es1::Context *context = es1::getContext();
4627
4628 if(context)
4629 {
4630 es1::Texture2D *texture = nullptr;
4631
4632 switch(target)
4633 {
4634 case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
4635 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
4636 default: UNREACHABLE(target);
4637 }
4638
4639 if(!texture)
4640 {
4641 return error(GL_INVALID_OPERATION);
4642 }
4643
4644 egl::Image *eglImage = context->getSharedImage(image);
4645
4646 if(!eglImage)
4647 {
4648 return error(GL_INVALID_OPERATION);
4649 }
4650
4651 texture->setSharedImage(eglImage);
4652 }
4653 }
4654
EGLImageTargetRenderbufferStorageOES(GLenum target,GLeglImageOES image)4655 void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
4656 {
4657 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
4658
4659 UNIMPLEMENTED();
4660 }
4661
DrawTexsOES(GLshort x,GLshort y,GLshort z,GLshort width,GLshort height)4662 void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
4663 {
4664 UNIMPLEMENTED();
4665 }
4666
DrawTexiOES(GLint x,GLint y,GLint z,GLint width,GLint height)4667 void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
4668 {
4669 TRACE("(GLint x = %d, GLint y = %d, GLint z = %d, GLint width = %d, GLint height = %d)", x, y, z, width, height);
4670
4671 if(width <= 0 || height <= 0)
4672 {
4673 return error(GL_INVALID_VALUE);
4674 }
4675
4676 es1::Context *context = es1::getContext();
4677
4678 if(context)
4679 {
4680 context->drawTexture((GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)width, (GLfloat)height);
4681 }
4682 }
4683
DrawTexxOES(GLfixed x,GLfixed y,GLfixed z,GLfixed width,GLfixed height)4684 void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
4685 {
4686 UNIMPLEMENTED();
4687 }
4688
DrawTexsvOES(const GLshort * coords)4689 void DrawTexsvOES(const GLshort *coords)
4690 {
4691 UNIMPLEMENTED();
4692 }
4693
DrawTexivOES(const GLint * coords)4694 void DrawTexivOES(const GLint *coords)
4695 {
4696 UNIMPLEMENTED();
4697 }
4698
DrawTexxvOES(const GLfixed * coords)4699 void DrawTexxvOES(const GLfixed *coords)
4700 {
4701 UNIMPLEMENTED();
4702 }
4703
DrawTexfOES(GLfloat x,GLfloat y,GLfloat z,GLfloat width,GLfloat height)4704 void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
4705 {
4706 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat width = %f, GLfloat height = %f)", x, y, z, width, height);
4707
4708 if(width <= 0 || height <= 0)
4709 {
4710 return error(GL_INVALID_VALUE);
4711 }
4712
4713 es1::Context *context = es1::getContext();
4714
4715 if(context)
4716 {
4717 context->drawTexture(x, y, z, width, height);
4718 }
4719 }
4720
DrawTexfvOES(const GLfloat * coords)4721 void DrawTexfvOES(const GLfloat *coords)
4722 {
4723 UNIMPLEMENTED();
4724 }
4725
4726 }
4727
es1GetProcAddress(const char * procname)4728 extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname)
4729 {
4730 struct Extension
4731 {
4732 const char *name;
4733 __eglMustCastToProperFunctionPointerType address;
4734 };
4735
4736 static const Extension glExtensions[] =
4737 {
4738 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
4739
4740 EXTENSION(glEGLImageTargetTexture2DOES),
4741 EXTENSION(glEGLImageTargetRenderbufferStorageOES),
4742 EXTENSION(glIsRenderbufferOES),
4743 EXTENSION(glBindRenderbufferOES),
4744 EXTENSION(glDeleteRenderbuffersOES),
4745 EXTENSION(glGenRenderbuffersOES),
4746 EXTENSION(glRenderbufferStorageOES),
4747 EXTENSION(glGetRenderbufferParameterivOES),
4748 EXTENSION(glIsFramebufferOES),
4749 EXTENSION(glBindFramebufferOES),
4750 EXTENSION(glDeleteFramebuffersOES),
4751 EXTENSION(glGenFramebuffersOES),
4752 EXTENSION(glCheckFramebufferStatusOES),
4753 EXTENSION(glFramebufferRenderbufferOES),
4754 EXTENSION(glFramebufferTexture2DOES),
4755 EXTENSION(glGetFramebufferAttachmentParameterivOES),
4756 EXTENSION(glGenerateMipmapOES),
4757 EXTENSION(glBlendEquationOES),
4758 EXTENSION(glBlendEquationSeparateOES),
4759 EXTENSION(glBlendFuncSeparateOES),
4760 EXTENSION(glPointSizePointerOES),
4761
4762 #undef EXTENSION
4763 };
4764
4765 for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
4766 {
4767 if(strcmp(procname, glExtensions[ext].name) == 0)
4768 {
4769 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
4770 }
4771 }
4772
4773 return nullptr;
4774 }
4775