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