• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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 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 AlphaFuncx(GLenum func, GLclampx ref)
96 {
97 	AlphaFunc(func, (float)ref / 0x10000);
98 }
99 
BindBuffer(GLenum target,GLuint buffer)100 void 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 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 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 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 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 BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);
206 
BlendEquationOES(GLenum mode)207 void BlendEquationOES(GLenum mode)
208 {
209 	BlendEquationSeparateOES(mode, mode);
210 }
211 
BlendEquationSeparateOES(GLenum modeRGB,GLenum modeAlpha)212 void 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 BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
249 
BlendFunc(GLenum sfactor,GLenum dfactor)250 void 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 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 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 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 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 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 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 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 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 ClearDepthx(GLclampx depth)
510 {
511 	ClearDepthf((float)depth / 0x10000);
512 }
513 
ClearStencil(GLint s)514 void 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 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 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 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 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 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 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 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_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
611 	}
612 }
613 
VertexAttribPointer(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)614 void 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_TRUE), stride, ptr);
653 	}
654 }
655 
ColorPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)656 void 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 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 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 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 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 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 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 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 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 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 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 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 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 DepthRangex(GLclampx zNear, GLclampx zFar)
1165 {
1166 	DepthRangef((float)zNear / 0x10000, (float)zFar / 0x10000);
1167 }
1168 
Disable(GLenum cap)1169 void 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 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 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 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 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 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 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 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 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 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)
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);   break;
1532 		case GL_DEPTH_ATTACHMENT_OES:   framebuffer->setDepthbuffer(textarget, texture);   break;
1533 		case GL_STENCIL_ATTACHMENT_OES: framebuffer->setStencilbuffer(textarget, texture); break;
1534 		}
1535 	}
1536 }
1537 
Fogf(GLenum pname,GLfloat param)1538 void 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 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 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 Fogxv(GLenum pname, const GLfixed *params)
1669 {
1670 	UNIMPLEMENTED();
1671 }
1672 
FrontFace(GLenum mode)1673 void 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 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 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 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 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 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 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 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 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 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 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 GetClipPlanef(GLenum pname, GLfloat eqn[4])
1971 {
1972 	UNIMPLEMENTED();
1973 }
1974 
GetClipPlanex(GLenum pname,GLfixed eqn[4])1975 void GetClipPlanex(GLenum pname, GLfixed eqn[4])
1976 {
1977 	UNIMPLEMENTED();
1978 }
1979 
GetError(void)1980 GLenum 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 GetFixedv(GLenum pname, GLfixed *params)
1995 {
1996 	UNIMPLEMENTED();
1997 }
1998 
GetFloatv(GLenum pname,GLfloat * params)1999 void 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 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 		switch(attachment)
2086 		{
2087 		case GL_COLOR_ATTACHMENT0_OES:
2088 			attachmentType = framebuffer->getColorbufferType();
2089 			attachmentHandle = framebuffer->getColorbufferName();
2090 			break;
2091 		case GL_DEPTH_ATTACHMENT_OES:
2092 			attachmentType = framebuffer->getDepthbufferType();
2093 			attachmentHandle = framebuffer->getDepthbufferName();
2094 			break;
2095 		case GL_STENCIL_ATTACHMENT_OES:
2096 			attachmentType = framebuffer->getStencilbufferType();
2097 			attachmentHandle = framebuffer->getStencilbufferName();
2098 			break;
2099 		default:
2100 			return error(GL_INVALID_ENUM);
2101 		}
2102 
2103 		GLenum attachmentObjectType;   // Type category
2104 		if(attachmentType == GL_NONE_OES || attachmentType == GL_RENDERBUFFER_OES)
2105 		{
2106 			attachmentObjectType = attachmentType;
2107 		}
2108 		else if(es1::IsTextureTarget(attachmentType))
2109 		{
2110 			attachmentObjectType = GL_TEXTURE;
2111 		}
2112 		else UNREACHABLE(attachmentType);
2113 
2114 		switch(pname)
2115 		{
2116 		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES:
2117 			*params = attachmentObjectType;
2118 			break;
2119 		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES:
2120 			if(attachmentObjectType == GL_RENDERBUFFER_OES || attachmentObjectType == GL_TEXTURE)
2121 			{
2122 				*params = attachmentHandle;
2123 			}
2124 			else
2125 			{
2126 				return error(GL_INVALID_ENUM);
2127 			}
2128 			break;
2129 		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES:
2130 			if(attachmentObjectType == GL_TEXTURE)
2131 			{
2132 				*params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2133 			}
2134 			else
2135 			{
2136 				return error(GL_INVALID_ENUM);
2137 			}
2138 			break;
2139 		default:
2140 			return error(GL_INVALID_ENUM);
2141 		}
2142 	}
2143 }
2144 
GetIntegerv(GLenum pname,GLint * params)2145 void GetIntegerv(GLenum pname, GLint* params)
2146 {
2147 	TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
2148 
2149 	es1::Context *context = es1::getContext();
2150 
2151 	if(context)
2152 	{
2153 		if(!(context->getIntegerv(pname, params)))
2154 		{
2155 			int numParams = context->getQueryParameterNum(pname);
2156 
2157 			if(numParams < 0)
2158 			{
2159 				return error(GL_INVALID_ENUM);
2160 			}
2161 
2162 			if(numParams == 0)
2163 			{
2164 				return;
2165 			}
2166 
2167 			if(context->isQueryParameterBool(pname))
2168 			{
2169 				GLboolean *boolParams = nullptr;
2170 				boolParams = new GLboolean[numParams];
2171 
2172 				context->getBooleanv(pname, boolParams);
2173 
2174 				for(int i = 0; i < numParams; ++i)
2175 				{
2176 					if(boolParams[i] == GL_FALSE)
2177 						params[i] = 0;
2178 					else
2179 						params[i] = 1;
2180 				}
2181 
2182 				delete [] boolParams;
2183 			}
2184 			else if(context->isQueryParameterFloat(pname))
2185 			{
2186 				GLfloat *floatParams = nullptr;
2187 				floatParams = new GLfloat[numParams];
2188 
2189 				context->getFloatv(pname, floatParams);
2190 
2191 				for(int i = 0; i < numParams; ++i)
2192 				{
2193 					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
2194 					{
2195 						params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
2196 					}
2197 					else
2198 					{
2199 						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
2200 					}
2201 				}
2202 
2203 				delete [] floatParams;
2204 			}
2205 			else UNREACHABLE(pname);
2206 		}
2207 	}
2208 }
2209 
GetLightfv(GLenum light,GLenum pname,GLfloat * params)2210 void GetLightfv(GLenum light, GLenum pname, GLfloat *params)
2211 {
2212 	UNIMPLEMENTED();
2213 }
2214 
GetLightxv(GLenum light,GLenum pname,GLfixed * params)2215 void GetLightxv(GLenum light, GLenum pname, GLfixed *params)
2216 {
2217 	UNIMPLEMENTED();
2218 }
2219 
GetMaterialfv(GLenum face,GLenum pname,GLfloat * params)2220 void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
2221 {
2222 	UNIMPLEMENTED();
2223 }
2224 
GetMaterialxv(GLenum face,GLenum pname,GLfixed * params)2225 void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
2226 {
2227 	UNIMPLEMENTED();
2228 }
2229 
GetPointerv(GLenum pname,GLvoid ** params)2230 void GetPointerv(GLenum pname, GLvoid **params)
2231 {
2232 	TRACE("(GLenum pname = 0x%X, GLvoid **params = %p)", pname, params);
2233 
2234 	es1::Context *context = es1::getContext();
2235 
2236 	if(context)
2237 	{
2238 		if(!(context->getPointerv(pname, const_cast<const GLvoid**>(params))))
2239 		{
2240 			return error(GL_INVALID_ENUM);
2241 		}
2242 	}
2243 }
2244 
GetString(GLenum name)2245 const GLubyte* GetString(GLenum name)
2246 {
2247 	TRACE("(GLenum name = 0x%X)", name);
2248 
2249 	switch(name)
2250 	{
2251 	case GL_VENDOR:
2252 		return (GLubyte*)"Google Inc.";
2253 	case GL_RENDERER:
2254 		return (GLubyte*)"Google SwiftShader " VERSION_STRING;
2255 	case GL_VERSION:
2256 		return (GLubyte*)"OpenGL ES-CM 1.1";
2257 	case GL_EXTENSIONS:
2258 		// Keep list sorted in following order:
2259 		// OES extensions
2260 		// EXT extensions
2261 		// Vendor extensions
2262 		return (GLubyte*)
2263 			"GL_OES_blend_equation_separate "
2264 			"GL_OES_blend_func_separate "
2265 			"GL_OES_blend_subtract "
2266 			"GL_OES_compressed_ETC1_RGB8_texture "
2267 			"GL_OES_EGL_image "
2268 			"GL_OES_EGL_image_external "
2269 			"GL_OES_EGL_sync "
2270 			"GL_OES_element_index_uint "
2271 			"GL_OES_framebuffer_object "
2272 			"GL_OES_packed_depth_stencil "
2273 			"GL_OES_read_format "
2274 			"GL_OES_rgb8_rgba8 "
2275 			"GL_OES_stencil8 "
2276 			"GL_OES_stencil_wrap "
2277 			"GL_OES_surfaceless_context "
2278 			"GL_OES_texture_mirrored_repeat "
2279 			"GL_OES_texture_npot "
2280 			"GL_EXT_blend_minmax "
2281 			"GL_EXT_read_format_bgra "
2282 			"GL_EXT_texture_compression_dxt1 "
2283 			"GL_ANGLE_texture_compression_dxt3 "
2284 			"GL_ANGLE_texture_compression_dxt5 "
2285 			"GL_EXT_texture_filter_anisotropic "
2286 			"GL_EXT_texture_format_BGRA8888";
2287 	default:
2288 		return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
2289 	}
2290 }
2291 
GetTexParameterfv(GLenum target,GLenum pname,GLfloat * params)2292 void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2293 {
2294 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
2295 
2296 	es1::Context *context = es1::getContext();
2297 
2298 	if(context)
2299 	{
2300 		es1::Texture *texture;
2301 
2302 		switch(target)
2303 		{
2304 		case GL_TEXTURE_2D:
2305 			texture = context->getTexture2D();
2306 			break;
2307 		case GL_TEXTURE_EXTERNAL_OES:
2308 			texture = context->getTextureExternal();
2309 			break;
2310 		default:
2311 			return error(GL_INVALID_ENUM);
2312 		}
2313 
2314 		switch(pname)
2315 		{
2316 		case GL_TEXTURE_MAG_FILTER:
2317 			*params = (GLfloat)texture->getMagFilter();
2318 			break;
2319 		case GL_TEXTURE_MIN_FILTER:
2320 			*params = (GLfloat)texture->getMinFilter();
2321 			break;
2322 		case GL_TEXTURE_WRAP_S:
2323 			*params = (GLfloat)texture->getWrapS();
2324 			break;
2325 		case GL_TEXTURE_WRAP_T:
2326 			*params = (GLfloat)texture->getWrapT();
2327 			break;
2328 		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2329 			*params = texture->getMaxAnisotropy();
2330 			break;
2331 		case GL_GENERATE_MIPMAP:
2332 			*params = (GLfloat)texture->getGenerateMipmap();
2333 			break;
2334 		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2335 			*params = (GLfloat)1;
2336 			break;
2337 		default:
2338 			return error(GL_INVALID_ENUM);
2339 		}
2340 	}
2341 }
2342 
GetTexParameteriv(GLenum target,GLenum pname,GLint * params)2343 void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2344 {
2345 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
2346 
2347 	es1::Context *context = es1::getContext();
2348 
2349 	if(context)
2350 	{
2351 		es1::Texture *texture;
2352 
2353 		switch(target)
2354 		{
2355 		case GL_TEXTURE_2D:
2356 			texture = context->getTexture2D();
2357 			break;
2358 		case GL_TEXTURE_EXTERNAL_OES:
2359 			texture = context->getTextureExternal();
2360 			break;
2361 		default:
2362 			return error(GL_INVALID_ENUM);
2363 		}
2364 
2365 		switch(pname)
2366 		{
2367 		case GL_TEXTURE_MAG_FILTER:
2368 			*params = texture->getMagFilter();
2369 			break;
2370 		case GL_TEXTURE_MIN_FILTER:
2371 			*params = texture->getMinFilter();
2372 			break;
2373 		case GL_TEXTURE_WRAP_S:
2374 			*params = texture->getWrapS();
2375 			break;
2376 		case GL_TEXTURE_WRAP_T:
2377 			*params = texture->getWrapT();
2378 			break;
2379 		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2380 			*params = (GLint)texture->getMaxAnisotropy();
2381 			break;
2382 		case GL_GENERATE_MIPMAP:
2383 			*params = (GLint)texture->getGenerateMipmap();
2384 			break;
2385 		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2386 			*params = 1;
2387 			break;
2388 		default:
2389 			return error(GL_INVALID_ENUM);
2390 		}
2391 	}
2392 }
2393 
GetTexEnvfv(GLenum env,GLenum pname,GLfloat * params)2394 void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
2395 {
2396 	UNIMPLEMENTED();
2397 }
2398 
GetTexEnviv(GLenum env,GLenum pname,GLint * params)2399 void GetTexEnviv(GLenum env, GLenum pname, GLint *params)
2400 {
2401 	UNIMPLEMENTED();
2402 }
2403 
GetTexEnvxv(GLenum env,GLenum pname,GLfixed * params)2404 void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
2405 {
2406 	UNIMPLEMENTED();
2407 }
2408 
GetTexParameterxv(GLenum target,GLenum pname,GLfixed * params)2409 void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
2410 {
2411 	UNIMPLEMENTED();
2412 }
2413 
Hint(GLenum target,GLenum mode)2414 void Hint(GLenum target, GLenum mode)
2415 {
2416 	TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
2417 
2418 	switch(mode)
2419 	{
2420 	case GL_FASTEST:
2421 	case GL_NICEST:
2422 	case GL_DONT_CARE:
2423 		break;
2424 	default:
2425 		return error(GL_INVALID_ENUM);
2426 	}
2427 
2428 	es1::Context *context = es1::getContext();
2429 
2430 	if(context)
2431 	{
2432 		switch(target)
2433 		{
2434 		case GL_GENERATE_MIPMAP_HINT:
2435 			context->setGenerateMipmapHint(mode);
2436 			break;
2437 		case GL_PERSPECTIVE_CORRECTION_HINT:
2438 			context->setPerspectiveCorrectionHint(mode);
2439 			break;
2440 		case GL_FOG_HINT:
2441 			context->setFogHint(mode);
2442 			break;
2443 		default:
2444 			return error(GL_INVALID_ENUM);
2445 		}
2446 	}
2447 }
2448 
IsBuffer(GLuint buffer)2449 GLboolean IsBuffer(GLuint buffer)
2450 {
2451 	TRACE("(GLuint buffer = %d)", buffer);
2452 
2453 	es1::Context *context = es1::getContext();
2454 
2455 	if(context && buffer)
2456 	{
2457 		es1::Buffer *bufferObject = context->getBuffer(buffer);
2458 
2459 		if(bufferObject)
2460 		{
2461 			return GL_TRUE;
2462 		}
2463 	}
2464 
2465 	return GL_FALSE;
2466 }
2467 
IsEnabled(GLenum cap)2468 GLboolean IsEnabled(GLenum cap)
2469 {
2470 	TRACE("(GLenum cap = 0x%X)", cap);
2471 
2472 	es1::Context *context = es1::getContext();
2473 
2474 	if(context)
2475 	{
2476 		switch(cap)
2477 		{
2478 		case GL_CULL_FACE:                return context->isCullFaceEnabled();              break;
2479 		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();     break;
2480 		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); break;
2481 		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();        break;
2482 		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();           break;
2483 		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();           break;
2484 		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();             break;
2485 		case GL_BLEND:                    return context->isBlendEnabled();                 break;
2486 		case GL_DITHER:                   return context->isDitherEnabled();                break;
2487 		case GL_LIGHTING:                 return context->isLightingEnabled();              break;
2488 		case GL_LIGHT0:                   return context->isLightEnabled(0);                break;
2489 		case GL_LIGHT1:                   return context->isLightEnabled(1);                break;
2490 		case GL_LIGHT2:                   return context->isLightEnabled(2);                break;
2491 		case GL_LIGHT3:                   return context->isLightEnabled(3);                break;
2492 		case GL_LIGHT4:                   return context->isLightEnabled(4);                break;
2493 		case GL_LIGHT5:                   return context->isLightEnabled(5);                break;
2494 		case GL_LIGHT6:                   return context->isLightEnabled(6);                break;
2495 		case GL_LIGHT7:                   return context->isLightEnabled(7);                break;
2496 		case GL_FOG:                      return context->isFogEnabled();                   break;
2497 		case GL_TEXTURE_2D:               return context->isTexture2Denabled();             break;
2498 		case GL_TEXTURE_EXTERNAL_OES:     return context->isTextureExternalEnabled();       break;
2499 		case GL_ALPHA_TEST:               return context->isAlphaTestEnabled();             break;
2500 		case GL_COLOR_LOGIC_OP:           return context->isColorLogicOpEnabled();          break;
2501 		case GL_POINT_SMOOTH:             return context->isPointSmoothEnabled();           break;
2502 		case GL_LINE_SMOOTH:              return context->isLineSmoothEnabled();            break;
2503 		case GL_COLOR_MATERIAL:           return context->isColorMaterialEnabled();         break;
2504 		case GL_NORMALIZE:                return context->isNormalizeEnabled();             break;
2505 		case GL_RESCALE_NORMAL:           return context->isRescaleNormalEnabled();         break;
2506 		case GL_VERTEX_ARRAY:             return context->isVertexArrayEnabled();           break;
2507 		case GL_NORMAL_ARRAY:             return context->isNormalArrayEnabled();           break;
2508 		case GL_COLOR_ARRAY:              return context->isColorArrayEnabled();            break;
2509 		case GL_POINT_SIZE_ARRAY_OES:     return context->isPointSizeArrayEnabled();        break;
2510 		case GL_TEXTURE_COORD_ARRAY:      return context->isTextureCoordArrayEnabled();     break;
2511 		case GL_MULTISAMPLE:              return context->isMultisampleEnabled();           break;
2512 		case GL_SAMPLE_ALPHA_TO_ONE:      return context->isSampleAlphaToOneEnabled();      break;
2513 		case GL_CLIP_PLANE0:              return context->isClipPlaneEnabled(0);            break;
2514 		case GL_CLIP_PLANE1:              return context->isClipPlaneEnabled(1);            break;
2515 		case GL_CLIP_PLANE2:              return context->isClipPlaneEnabled(2);            break;
2516 		case GL_CLIP_PLANE3:              return context->isClipPlaneEnabled(3);            break;
2517 		case GL_CLIP_PLANE4:              return context->isClipPlaneEnabled(4);            break;
2518 		case GL_CLIP_PLANE5:              return context->isClipPlaneEnabled(5);            break;
2519 		case GL_POINT_SPRITE_OES:         return context->isPointSpriteEnabled();           break;
2520 		default:
2521 			return error(GL_INVALID_ENUM, GL_FALSE);
2522 		}
2523 	}
2524 
2525 	return GL_FALSE;
2526 }
2527 
IsFramebufferOES(GLuint framebuffer)2528 GLboolean IsFramebufferOES(GLuint framebuffer)
2529 {
2530 	TRACE("(GLuint framebuffer = %d)", framebuffer);
2531 
2532 	es1::Context *context = es1::getContext();
2533 
2534 	if(context && framebuffer)
2535 	{
2536 		es1::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2537 
2538 		if(framebufferObject)
2539 		{
2540 			return GL_TRUE;
2541 		}
2542 	}
2543 
2544 	return GL_FALSE;
2545 }
2546 
IsTexture(GLuint texture)2547 GLboolean IsTexture(GLuint texture)
2548 {
2549 	TRACE("(GLuint texture = %d)", texture);
2550 
2551 	es1::Context *context = es1::getContext();
2552 
2553 	if(context && texture)
2554 	{
2555 		es1::Texture *textureObject = context->getTexture(texture);
2556 
2557 		if(textureObject)
2558 		{
2559 			return GL_TRUE;
2560 		}
2561 	}
2562 
2563 	return GL_FALSE;
2564 }
2565 
IsRenderbufferOES(GLuint renderbuffer)2566 GLboolean IsRenderbufferOES(GLuint renderbuffer)
2567 {
2568 	TRACE("(GLuint renderbuffer = %d)", renderbuffer);
2569 
2570 	es1::Context *context = es1::getContext();
2571 
2572 	if(context && renderbuffer)
2573 	{
2574 		es1::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2575 
2576 		if(renderbufferObject)
2577 		{
2578 			return GL_TRUE;
2579 		}
2580 	}
2581 
2582 	return GL_FALSE;
2583 }
2584 
LightModelf(GLenum pname,GLfloat param)2585 void LightModelf(GLenum pname, GLfloat param)
2586 {
2587 	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
2588 
2589 	es1::Context *context = es1::getContext();
2590 
2591 	if(context)
2592 	{
2593 		switch(pname)
2594 		{
2595 		case GL_LIGHT_MODEL_TWO_SIDE:
2596 			context->setLightModelTwoSide(param != 0.0f);
2597 			break;
2598 		case GL_LIGHT_MODEL_AMBIENT:
2599 			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelfv() instead
2600 		default:
2601 			return error(GL_INVALID_ENUM);
2602 		}
2603 	}
2604 }
2605 
LightModelfv(GLenum pname,const GLfloat * params)2606 void LightModelfv(GLenum pname, const GLfloat *params)
2607 {
2608 	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
2609 
2610 	es1::Context *context = es1::getContext();
2611 
2612 	if(context)
2613 	{
2614 		switch(pname)
2615 		{
2616 		case GL_LIGHT_MODEL_AMBIENT:
2617 			context->setGlobalAmbient(params[0], params[1], params[2], params[3]);
2618 			break;
2619 		case GL_LIGHT_MODEL_TWO_SIDE:
2620 			context->setLightModelTwoSide(params[0] != 0.0f);
2621 			break;
2622 		default:
2623 			return error(GL_INVALID_ENUM);
2624 		}
2625 	}
2626 }
2627 
LightModelx(GLenum pname,GLfixed param)2628 void LightModelx(GLenum pname, GLfixed param)
2629 {
2630 	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
2631 
2632 	es1::Context *context = es1::getContext();
2633 
2634 	if(context)
2635 	{
2636 		switch(pname)
2637 		{
2638 		case GL_LIGHT_MODEL_TWO_SIDE:
2639 			context->setLightModelTwoSide(param != 0);
2640 			break;
2641 		case GL_LIGHT_MODEL_AMBIENT:
2642 			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelxv() instead
2643 		default:
2644 			return error(GL_INVALID_ENUM);
2645 		}
2646 	}
2647 }
2648 
LightModelxv(GLenum pname,const GLfixed * params)2649 void LightModelxv(GLenum pname, const GLfixed *params)
2650 {
2651 	TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);
2652 
2653 	es1::Context *context = es1::getContext();
2654 
2655 	if(context)
2656 	{
2657 		switch(pname)
2658 		{
2659 		case GL_LIGHT_MODEL_AMBIENT:
2660 			context->setGlobalAmbient((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000, (float)params[3] / 0x10000);
2661 			break;
2662 		case GL_LIGHT_MODEL_TWO_SIDE:
2663 			context->setLightModelTwoSide(params[0] != 0);
2664 			break;
2665 		default:
2666 			return error(GL_INVALID_ENUM);
2667 		}
2668 	}
2669 }
2670 
Lightf(GLenum light,GLenum pname,GLfloat param)2671 void Lightf(GLenum light, GLenum pname, GLfloat param)
2672 {
2673 	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", light, pname, param);
2674 
2675 	int index = light - GL_LIGHT0;
2676 
2677 	if(index < 0 || index >= es1::MAX_LIGHTS)
2678 	{
2679 		return error(GL_INVALID_ENUM);
2680 	}
2681 
2682 	es1::Context *context = es1::getContext();
2683 
2684 	if(context)
2685 	{
2686 		switch(pname)
2687 		{
2688 		case GL_SPOT_EXPONENT:
2689 			if(param < 0.0f || param > 128.0f)
2690 			{
2691 				return error(GL_INVALID_VALUE);
2692 			}
2693 			context->setSpotLightExponent(index, param);
2694 			break;
2695 		case GL_SPOT_CUTOFF:
2696 			if((param < 0.0f || param > 90.0f) && param != 180.0f)
2697 			{
2698 				return error(GL_INVALID_VALUE);
2699 			}
2700 			context->setSpotLightCutoff(index, param);
2701 			break;
2702 		case GL_CONSTANT_ATTENUATION:
2703 			if(param < 0.0f)
2704 			{
2705 				return error(GL_INVALID_VALUE);
2706 			}
2707 			context->setLightAttenuationConstant(index, param);
2708 			break;
2709 		case GL_LINEAR_ATTENUATION:
2710 			if(param < 0.0f)
2711 			{
2712 				return error(GL_INVALID_VALUE);
2713 			}
2714 			context->setLightAttenuationLinear(index, param);
2715 			break;
2716 		case GL_QUADRATIC_ATTENUATION:
2717 			if(param < 0.0f)
2718 			{
2719 				return error(GL_INVALID_VALUE);
2720 			}
2721 			context->setLightAttenuationQuadratic(index, param);
2722 			break;
2723 		case GL_AMBIENT:
2724 		case GL_DIFFUSE:
2725 		case GL_SPECULAR:
2726 		case GL_POSITION:
2727 		case GL_SPOT_DIRECTION:
2728 			return error(GL_INVALID_ENUM);   // Need four values, should call glLightfv() instead
2729 		default:
2730 			return error(GL_INVALID_ENUM);
2731 		}
2732 	}
2733 }
2734 
Lightfv(GLenum light,GLenum pname,const GLfloat * params)2735 void Lightfv(GLenum light, GLenum pname, const GLfloat *params)
2736 {
2737 	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
2738 
2739 	es1::Context *context = es1::getContext();
2740 
2741 	if(context)
2742 	{
2743 		int index = light - GL_LIGHT0;
2744 
2745 		if(index < 0 || index > es1::MAX_LIGHTS)
2746 		{
2747 			return error(GL_INVALID_ENUM);
2748 		}
2749 
2750 		switch(pname)
2751 		{
2752 		case GL_AMBIENT:               context->setLightAmbient(index, params[0], params[1], params[2], params[3]);  break;
2753 		case GL_DIFFUSE:               context->setLightDiffuse(index, params[0], params[1], params[2], params[3]);  break;
2754 		case GL_SPECULAR:              context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break;
2755 		case GL_POSITION:              context->setLightPosition(index, params[0], params[1], params[2], params[3]); break;
2756 		case GL_SPOT_DIRECTION:        context->setLightDirection(index, params[0], params[1], params[2]);           break;
2757 		case GL_SPOT_EXPONENT:
2758 			if(params[0] < 0.0f || params[0] > 128.0f)
2759 			{
2760 				return error(GL_INVALID_VALUE);
2761 			}
2762 			context->setSpotLightExponent(index, params[0]);
2763 			break;
2764 		case GL_SPOT_CUTOFF:
2765 			if((params[0] < 0.0f || params[0] > 90.0f) && params[0] != 180.0f)
2766 			{
2767 				return error(GL_INVALID_VALUE);
2768 			}
2769 			context->setSpotLightCutoff(index, params[0]);
2770 			break;
2771 		case GL_CONSTANT_ATTENUATION:
2772 			if(params[0] < 0.0f)
2773 			{
2774 				return error(GL_INVALID_VALUE);
2775 			}
2776 			context->setLightAttenuationConstant(index, params[0]);
2777 			break;
2778 		case GL_LINEAR_ATTENUATION:
2779 			if(params[0] < 0.0f)
2780 			{
2781 				return error(GL_INVALID_VALUE);
2782 			}
2783 			context->setLightAttenuationLinear(index, params[0]);
2784 			break;
2785 		case GL_QUADRATIC_ATTENUATION:
2786 			if(params[0] < 0.0f)
2787 			{
2788 				return error(GL_INVALID_VALUE);
2789 			}
2790 			context->setLightAttenuationQuadratic(index, params[0]);
2791 			break;
2792 		default:
2793 			return error(GL_INVALID_ENUM);
2794 		}
2795 	}
2796 }
2797 
Lightx(GLenum light,GLenum pname,GLfixed param)2798 void Lightx(GLenum light, GLenum pname, GLfixed param)
2799 {
2800 	UNIMPLEMENTED();
2801 }
2802 
Lightxv(GLenum light,GLenum pname,const GLfixed * params)2803 void Lightxv(GLenum light, GLenum pname, const GLfixed *params)
2804 {
2805 	UNIMPLEMENTED();
2806 }
2807 
LineWidth(GLfloat width)2808 void LineWidth(GLfloat width)
2809 {
2810 	TRACE("(GLfloat width = %f)", width);
2811 
2812 	if(width <= 0.0f)
2813 	{
2814 		return error(GL_INVALID_VALUE);
2815 	}
2816 
2817 	es1::Context *context = es1::getContext();
2818 
2819 	if(context)
2820 	{
2821 		context->setLineWidth(width);
2822 	}
2823 }
2824 
LineWidthx(GLfixed width)2825 void LineWidthx(GLfixed width)
2826 {
2827 	LineWidth((float)width / 0x10000);
2828 }
2829 
LoadIdentity(void)2830 void LoadIdentity(void)
2831 {
2832 	TRACE("()");
2833 
2834 	es1::Context *context = es1::getContext();
2835 
2836 	if(context)
2837 	{
2838 		context->loadIdentity();
2839 	}
2840 }
2841 
LoadMatrixf(const GLfloat * m)2842 void LoadMatrixf(const GLfloat *m)
2843 {
2844 	TRACE("(const GLfloat *m)");
2845 
2846 	es1::Context *context = es1::getContext();
2847 
2848 	if(context)
2849 	{
2850 		context->load(m);
2851 	}
2852 }
2853 
LoadMatrixx(const GLfixed * m)2854 void LoadMatrixx(const GLfixed *m)
2855 {
2856 	GLfloat matrix[16] =
2857 	{
2858 		(float)m[0] / 0x10000,  (float)m[1] / 0x10000,  (float)m[2] / 0x10000,  (float)m[3] / 0x10000,
2859 		(float)m[4] / 0x10000,  (float)m[5] / 0x10000,  (float)m[6] / 0x10000,  (float)m[7] / 0x10000,
2860 		(float)m[8] / 0x10000,  (float)m[9] / 0x10000,  (float)m[10] / 0x10000, (float)m[11] / 0x10000,
2861 		(float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
2862 	};
2863 
2864 	LoadMatrixf(matrix);
2865 }
2866 
LogicOp(GLenum opcode)2867 void LogicOp(GLenum opcode)
2868 {
2869 	TRACE("(GLenum opcode = 0x%X)", opcode);
2870 
2871 	switch(opcode)
2872 	{
2873 	case GL_CLEAR:
2874 	case GL_SET:
2875 	case GL_COPY:
2876 	case GL_COPY_INVERTED:
2877 	case GL_NOOP:
2878 	case GL_INVERT:
2879 	case GL_AND:
2880 	case GL_NAND:
2881 	case GL_OR:
2882 	case GL_NOR:
2883 	case GL_XOR:
2884 	case GL_EQUIV:
2885 	case GL_AND_REVERSE:
2886 	case GL_AND_INVERTED:
2887 	case GL_OR_REVERSE:
2888 	case GL_OR_INVERTED:
2889 		break;
2890 	default:
2891 		return error(GL_INVALID_ENUM);
2892 	}
2893 
2894 	es1::Context *context = es1::getContext();
2895 
2896 	if(context)
2897 	{
2898 		context->setLogicalOperation(opcode);
2899 	}
2900 }
2901 
Materialf(GLenum face,GLenum pname,GLfloat param)2902 void Materialf(GLenum face, GLenum pname, GLfloat param)
2903 {
2904 	TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", face, pname, param);
2905 
2906 	if(face != GL_FRONT_AND_BACK)
2907 	{
2908 		return error(GL_INVALID_ENUM);
2909 	}
2910 
2911 	es1::Context *context = es1::getContext();
2912 
2913 	if(context)
2914 	{
2915 		switch(pname)
2916 		{
2917 		case GL_SHININESS:
2918 			if(param < 0.0f || param > 128.0f)
2919 			{
2920 				return error(GL_INVALID_VALUE);
2921 			}
2922 			context->setMaterialShininess(param);
2923 			break;
2924 		case GL_AMBIENT:
2925 		case GL_DIFFUSE:
2926 		case GL_AMBIENT_AND_DIFFUSE:
2927 		case GL_SPECULAR:
2928 		case GL_EMISSION:
2929 			return error(GL_INVALID_ENUM);   // Need four values, should call glMaterialfv() instead
2930 		default:
2931 			return error(GL_INVALID_ENUM);
2932 		}
2933 	}
2934 }
2935 
Materialfv(GLenum face,GLenum pname,const GLfloat * params)2936 void Materialfv(GLenum face, GLenum pname, const GLfloat *params)
2937 {
2938 	TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat params)", face, pname);
2939 
2940 	if(face != GL_FRONT_AND_BACK)
2941 	{
2942 		return error(GL_INVALID_ENUM);
2943 	}
2944 
2945 	es1::Context *context = es1::getContext();
2946 
2947 	if(context)
2948 	{
2949 		switch(pname)
2950 		{
2951 		case GL_AMBIENT:
2952 			context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
2953 			break;
2954 		case GL_DIFFUSE:
2955 			context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
2956 			break;
2957 		case GL_AMBIENT_AND_DIFFUSE:
2958 			context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
2959 			context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
2960 			break;
2961 		case GL_SPECULAR:
2962 			context->setMaterialSpecular(params[0], params[1], params[2], params[3]);
2963 			break;
2964 		case GL_EMISSION:
2965 			context->setMaterialEmission(params[0], params[1], params[2], params[3]);
2966 			break;
2967 		case GL_SHININESS:
2968 			context->setMaterialShininess(params[0]);
2969 			break;
2970 		default:
2971 			return error(GL_INVALID_ENUM);
2972 		}
2973 	}
2974 }
2975 
Materialx(GLenum face,GLenum pname,GLfixed param)2976 void Materialx(GLenum face, GLenum pname, GLfixed param)
2977 {
2978 	UNIMPLEMENTED();
2979 }
2980 
Materialxv(GLenum face,GLenum pname,const GLfixed * params)2981 void Materialxv(GLenum face, GLenum pname, const GLfixed *params)
2982 {
2983 	UNIMPLEMENTED();
2984 }
2985 
MatrixMode(GLenum mode)2986 void MatrixMode(GLenum mode)
2987 {
2988 	TRACE("(GLenum mode = 0x%X)", mode);
2989 
2990 	es1::Context *context = es1::getContext();
2991 
2992 	if(context)
2993 	{
2994 		context->setMatrixMode(mode);
2995 	}
2996 }
2997 
MultMatrixf(const GLfloat * m)2998 void MultMatrixf(const GLfloat *m)
2999 {
3000 	TRACE("(const GLfloat *m)");
3001 
3002 	es1::Context *context = es1::getContext();
3003 
3004 	if(context)
3005 	{
3006 		context->multiply(m);
3007 	}
3008 }
3009 
MultMatrixx(const GLfixed * m)3010 void MultMatrixx(const GLfixed *m)
3011 {
3012 	GLfloat matrix[16] =
3013 	{
3014 		(float)m[0] / 0x10000,  (float)m[1] / 0x10000,  (float)m[2] / 0x10000,  (float)m[3] / 0x10000,
3015 		(float)m[4] / 0x10000,  (float)m[5] / 0x10000,  (float)m[6] / 0x10000,  (float)m[7] / 0x10000,
3016 		(float)m[8] / 0x10000,  (float)m[9] / 0x10000,  (float)m[10] / 0x10000, (float)m[11] / 0x10000,
3017 		(float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
3018 	};
3019 
3020 	MultMatrixf(matrix);
3021 }
3022 
MultiTexCoord4f(GLenum target,GLfloat s,GLfloat t,GLfloat r,GLfloat q)3023 void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
3024 {
3025 	TRACE("(GLenum target = 0x%X, GLfloat s = %f, GLfloat t = %f, GLfloat r = %f, GLfloat q = %f)", target, s, t, r, q);
3026 
3027 	switch(target)
3028 	{
3029 	case GL_TEXTURE0:
3030 	case GL_TEXTURE1:
3031 		break;
3032 	default:
3033 		return error(GL_INVALID_ENUM);
3034 	}
3035 
3036 	es1::Context *context = es1::getContext();
3037 
3038 	if(context)
3039 	{
3040 		context->setVertexAttrib(sw::TexCoord0 + (target - GL_TEXTURE0), s, t, r, q);
3041 	}
3042 }
3043 
MultiTexCoord4x(GLenum target,GLfixed s,GLfixed t,GLfixed r,GLfixed q)3044 void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
3045 {
3046 	UNIMPLEMENTED();
3047 }
3048 
Normal3f(GLfloat nx,GLfloat ny,GLfloat nz)3049 void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
3050 {
3051 	TRACE("(GLfloat nx, GLfloat ny, GLfloat nz)", nx, ny, nz);
3052 
3053 	es1::Context *context = es1::getContext();
3054 
3055 	if(context)
3056 	{
3057 		context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
3058 	}
3059 }
3060 
Normal3x(GLfixed nx,GLfixed ny,GLfixed nz)3061 void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz)
3062 {
3063 	UNIMPLEMENTED();
3064 }
3065 
NormalPointer(GLenum type,GLsizei stride,const GLvoid * pointer)3066 void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
3067 {
3068 	TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);
3069 
3070 	VertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);
3071 }
3072 
Orthof(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)3073 void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
3074 {
3075 	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);
3076 
3077 	if(left == right || bottom == top || zNear == zFar)
3078 	{
3079 		return error(GL_INVALID_VALUE);
3080 	}
3081 
3082 	es1::Context *context = es1::getContext();
3083 
3084 	if(context)
3085 	{
3086 		context->ortho(left, right, bottom, top, zNear, zFar);
3087 	}
3088 }
3089 
Orthox(GLfixed left,GLfixed right,GLfixed bottom,GLfixed top,GLfixed zNear,GLfixed zFar)3090 void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
3091 {
3092 	Orthof((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);
3093 }
3094 
PixelStorei(GLenum pname,GLint param)3095 void PixelStorei(GLenum pname, GLint param)
3096 {
3097 	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
3098 
3099 	es1::Context *context = es1::getContext();
3100 
3101 	if(context)
3102 	{
3103 		switch(pname)
3104 		{
3105 		case GL_UNPACK_ALIGNMENT:
3106 			if(param != 1 && param != 2 && param != 4 && param != 8)
3107 			{
3108 				return error(GL_INVALID_VALUE);
3109 			}
3110 
3111 			context->setUnpackAlignment(param);
3112 			break;
3113 		case GL_PACK_ALIGNMENT:
3114 			if(param != 1 && param != 2 && param != 4 && param != 8)
3115 			{
3116 				return error(GL_INVALID_VALUE);
3117 			}
3118 
3119 			context->setPackAlignment(param);
3120 			break;
3121 		default:
3122 			return error(GL_INVALID_ENUM);
3123 		}
3124 	}
3125 }
3126 
PointParameterf(GLenum pname,GLfloat param)3127 void PointParameterf(GLenum pname, GLfloat param)
3128 {
3129 	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
3130 
3131 	es1::Context *context = es1::getContext();
3132 
3133 	if(context)
3134 	{
3135 		switch(pname)
3136 		{
3137 		case GL_POINT_SIZE_MIN:
3138 			if(param < 0.0f)
3139 			{
3140 				return error(GL_INVALID_VALUE);
3141 			}
3142 			context->setPointSizeMin(param);
3143 			break;
3144 		case GL_POINT_SIZE_MAX:
3145 			if(param < 0.0f)
3146 			{
3147 				return error(GL_INVALID_VALUE);
3148 			}
3149 			context->setPointSizeMax(param);
3150 			break;
3151 		case GL_POINT_FADE_THRESHOLD_SIZE:
3152 			if(param < 0.0f)
3153 			{
3154 				return error(GL_INVALID_VALUE);
3155 			}
3156 			context->setPointFadeThresholdSize(param);
3157 			break;
3158 		case GL_POINT_DISTANCE_ATTENUATION:
3159 			return error(GL_INVALID_ENUM);   // Needs three values, should call glPointParameterfv() instead
3160 		default:
3161 			return error(GL_INVALID_ENUM);
3162 		}
3163 	}
3164 }
3165 
PointParameterfv(GLenum pname,const GLfloat * params)3166 void PointParameterfv(GLenum pname, const GLfloat *params)
3167 {
3168 	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
3169 
3170 	es1::Context *context = es1::getContext();
3171 
3172 	if(context)
3173 	{
3174 		switch(pname)
3175 		{
3176 		case GL_POINT_SIZE_MIN:
3177 			if(params[0] < 0.0f)
3178 			{
3179 				return error(GL_INVALID_VALUE);
3180 			}
3181 			context->setPointSizeMin(params[0]);
3182 			break;
3183 		case GL_POINT_SIZE_MAX:
3184 			if(params[0] < 0.0f)
3185 			{
3186 				return error(GL_INVALID_VALUE);
3187 			}
3188 			context->setPointSizeMax(params[0]);
3189 			break;
3190 		case GL_POINT_DISTANCE_ATTENUATION:
3191 			context->setPointDistanceAttenuation(params[0], params[1], params[2]);
3192 			break;
3193 		case GL_POINT_FADE_THRESHOLD_SIZE:
3194 			if(params[0] < 0.0f)
3195 			{
3196 				return error(GL_INVALID_VALUE);
3197 			}
3198 			context->setPointFadeThresholdSize(params[0]);
3199 			break;
3200 		default:
3201 			return error(GL_INVALID_ENUM);
3202 		}
3203 	}
3204 }
3205 
PointParameterx(GLenum pname,GLfixed param)3206 void PointParameterx(GLenum pname, GLfixed param)
3207 {
3208 	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
3209 
3210 	es1::Context *context = es1::getContext();
3211 
3212 	if(context)
3213 	{
3214 		switch(pname)
3215 		{
3216 		case GL_POINT_SIZE_MIN:
3217 			if(param < 0)
3218 			{
3219 				return error(GL_INVALID_VALUE);
3220 			}
3221 			context->setPointSizeMin((float)param / 0x10000);
3222 			break;
3223 		case GL_POINT_SIZE_MAX:
3224 			if(param < 0)
3225 			{
3226 				return error(GL_INVALID_VALUE);
3227 			}
3228 			context->setPointSizeMax((float)param / 0x10000);
3229 			break;
3230 		case GL_POINT_FADE_THRESHOLD_SIZE:
3231 			if(param < 0)
3232 			{
3233 				return error(GL_INVALID_VALUE);
3234 			}
3235 			context->setPointFadeThresholdSize((float)param / 0x10000);
3236 			break;
3237 		case GL_POINT_DISTANCE_ATTENUATION:
3238 			return error(GL_INVALID_ENUM);   // Needs three parameters, should call glPointParameterxv() instead
3239 		default:
3240 			return error(GL_INVALID_ENUM);
3241 		}
3242 	}
3243 }
3244 
PointParameterxv(GLenum pname,const GLfixed * params)3245 void PointParameterxv(GLenum pname, const GLfixed *params)
3246 {
3247 	TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);
3248 
3249 	es1::Context *context = es1::getContext();
3250 
3251 	if(context)
3252 	{
3253 		switch(pname)
3254 		{
3255 		case GL_POINT_SIZE_MIN:
3256 			if(params[0] < 0)
3257 			{
3258 				return error(GL_INVALID_VALUE);
3259 			}
3260 			context->setPointSizeMin((float)params[0] / 0x10000);
3261 			break;
3262 		case GL_POINT_SIZE_MAX:
3263 			if(params[0] < 0)
3264 			{
3265 				return error(GL_INVALID_VALUE);
3266 			}
3267 			context->setPointSizeMax((float)params[0] / 0x10000);
3268 			break;
3269 		case GL_POINT_DISTANCE_ATTENUATION:
3270 			context->setPointDistanceAttenuation((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000);
3271 			break;
3272 		case GL_POINT_FADE_THRESHOLD_SIZE:
3273 			if(params[0] < 0)
3274 			{
3275 				return error(GL_INVALID_VALUE);
3276 			}
3277 			context->setPointFadeThresholdSize((float)params[0] / 0x10000);
3278 			break;
3279 		default:
3280 			return error(GL_INVALID_ENUM);
3281 		}
3282 	}
3283 }
3284 
PointSize(GLfloat size)3285 void PointSize(GLfloat size)
3286 {
3287 	TRACE("(GLfloat size = %f)", size);
3288 
3289 	if(size <= 0)
3290 	{
3291 		return error(GL_INVALID_VALUE);
3292 	}
3293 
3294 	es1::Context *context = es1::getContext();
3295 
3296 	if(context)
3297 	{
3298 		context->setVertexAttrib(sw::PointSize, size, size, size, size);
3299 	}
3300 }
3301 
PointSizePointerOES(GLenum type,GLsizei stride,const GLvoid * pointer)3302 void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
3303 {
3304 	TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);
3305 
3306 	switch(type)
3307 	{
3308 	case GL_FIXED:
3309 	case GL_FLOAT:
3310 		break;
3311 	default:
3312 		return error(GL_INVALID_ENUM);
3313 	}
3314 
3315 	VertexAttribPointer(sw::PointSize, 1, type, true, stride, pointer);
3316 }
3317 
PointSizex(GLfixed size)3318 void PointSizex(GLfixed size)
3319 {
3320 	PointSize((float)size / 0x10000);
3321 }
3322 
PolygonOffset(GLfloat factor,GLfloat units)3323 void PolygonOffset(GLfloat factor, GLfloat units)
3324 {
3325 	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
3326 
3327 	es1::Context *context = es1::getContext();
3328 
3329 	if(context)
3330 	{
3331 		context->setPolygonOffsetParams(factor, units);
3332 	}
3333 }
3334 
PolygonOffsetx(GLfixed factor,GLfixed units)3335 void PolygonOffsetx(GLfixed factor, GLfixed units)
3336 {
3337 	PolygonOffset((float)factor / 0x10000, (float)units / 0x10000);
3338 }
3339 
PopMatrix(void)3340 void PopMatrix(void)
3341 {
3342 	TRACE("()");
3343 
3344 	es1::Context *context = es1::getContext();
3345 
3346 	if(context)
3347 	{
3348 		context->popMatrix();
3349 	}
3350 }
3351 
PushMatrix(void)3352 void PushMatrix(void)
3353 {
3354 	TRACE("()");
3355 
3356 	es1::Context *context = es1::getContext();
3357 
3358 	if(context)
3359 	{
3360 		context->pushMatrix();
3361 	}
3362 }
3363 
ReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)3364 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
3365 {
3366 	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
3367 	      "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
3368 	      x, y, width, height, format, type,  pixels);
3369 
3370 	if(width < 0 || height < 0)
3371 	{
3372 		return error(GL_INVALID_VALUE);
3373 	}
3374 
3375 	es1::Context *context = es1::getContext();
3376 
3377 	if(context)
3378 	{
3379 		context->readPixels(x, y, width, height, format, type, nullptr, pixels);
3380 	}
3381 }
3382 
RenderbufferStorageOES(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)3383 void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3384 {
3385 	TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3386 	      target, internalformat, width, height);
3387 
3388 	switch(target)
3389 	{
3390 	case GL_RENDERBUFFER_OES:
3391 		break;
3392 	default:
3393 		return error(GL_INVALID_ENUM);
3394 	}
3395 
3396 	if(!es1::IsColorRenderable(internalformat) && !es1::IsDepthRenderable(internalformat) && !es1::IsStencilRenderable(internalformat))
3397 	{
3398 		return error(GL_INVALID_ENUM);
3399 	}
3400 
3401 	if(width < 0 || height < 0)
3402 	{
3403 		return error(GL_INVALID_VALUE);
3404 	}
3405 
3406 	es1::Context *context = es1::getContext();
3407 
3408 	if(context)
3409 	{
3410 		if(width > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
3411 		   height > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
3412 		{
3413 			return error(GL_INVALID_VALUE);
3414 		}
3415 
3416 		GLuint handle = context->getRenderbufferName();
3417 		if(handle == 0)
3418 		{
3419 			return error(GL_INVALID_OPERATION);
3420 		}
3421 
3422 		switch(internalformat)
3423 		{
3424 		case GL_RGBA4_OES:
3425 		case GL_RGB5_A1_OES:
3426 		case GL_RGB565_OES:
3427 		case GL_RGB8_OES:
3428 		case GL_RGBA8_OES:
3429 			context->setRenderbufferStorage(new es1::Colorbuffer(width, height, internalformat, 0));
3430 			break;
3431 		case GL_DEPTH_COMPONENT16_OES:
3432 			context->setRenderbufferStorage(new es1::Depthbuffer(width, height, internalformat,  0));
3433 			break;
3434 		case GL_STENCIL_INDEX8_OES:
3435 			context->setRenderbufferStorage(new es1::Stencilbuffer(width, height, 0));
3436 			break;
3437 		case GL_DEPTH24_STENCIL8_OES:
3438 			context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, internalformat, 0));
3439 			break;
3440 		default:
3441 			return error(GL_INVALID_ENUM);
3442 		}
3443 	}
3444 }
3445 
Rotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z)3446 void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3447 {
3448 	TRACE("(GLfloat angle = %f, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", angle, x, y, z);
3449 
3450 	es1::Context *context = es1::getContext();
3451 
3452 	if(context)
3453 	{
3454 		context->rotate(angle, x, y, z);
3455 	}
3456 }
3457 
Rotatex(GLfixed angle,GLfixed x,GLfixed y,GLfixed z)3458 void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
3459 {
3460 	Rotatef((float)angle / 0x10000, (float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
3461 }
3462 
SampleCoverage(GLclampf value,GLboolean invert)3463 void SampleCoverage(GLclampf value, GLboolean invert)
3464 {
3465 	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
3466 
3467 	es1::Context* context = es1::getContext();
3468 
3469 	if(context)
3470 	{
3471 		context->setSampleCoverageParams(es1::clamp01(value), invert == GL_TRUE);
3472 	}
3473 }
3474 
SampleCoveragex(GLclampx value,GLboolean invert)3475 void SampleCoveragex(GLclampx value, GLboolean invert)
3476 {
3477 	SampleCoverage((float)value / 0x10000, invert);
3478 }
3479 
Scalef(GLfloat x,GLfloat y,GLfloat z)3480 void Scalef(GLfloat x, GLfloat y, GLfloat z)
3481 {
3482 	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
3483 
3484 	es1::Context *context = es1::getContext();
3485 
3486 	if(context)
3487 	{
3488 		context->scale(x, y, z);
3489 	}
3490 }
3491 
Scalex(GLfixed x,GLfixed y,GLfixed z)3492 void Scalex(GLfixed x, GLfixed y, GLfixed z)
3493 {
3494 	Scalef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
3495 }
3496 
Scissor(GLint x,GLint y,GLsizei width,GLsizei height)3497 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3498 {
3499 	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
3500 
3501 	if(width < 0 || height < 0)
3502 	{
3503 		return error(GL_INVALID_VALUE);
3504 	}
3505 
3506 	es1::Context* context = es1::getContext();
3507 
3508 	if(context)
3509 	{
3510 		context->setScissorParams(x, y, width, height);
3511 	}
3512 }
3513 
ShadeModel(GLenum mode)3514 void ShadeModel(GLenum mode)
3515 {
3516 	switch(mode)
3517 	{
3518 	case GL_FLAT:
3519 	case GL_SMOOTH:
3520 		break;
3521 	default:
3522 		return error(GL_INVALID_ENUM);
3523 	}
3524 
3525 	es1::Context *context = es1::getContext();
3526 
3527 	if(context)
3528 	{
3529 		context->setShadeModel(mode);
3530 	}
3531 }
3532 
StencilFunc(GLenum func,GLint ref,GLuint mask)3533 void StencilFunc(GLenum func, GLint ref, GLuint mask)
3534 {
3535 	TRACE("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)",  func, ref, mask);
3536 
3537 	switch(func)
3538 	{
3539 	case GL_NEVER:
3540 	case GL_ALWAYS:
3541 	case GL_LESS:
3542 	case GL_LEQUAL:
3543 	case GL_EQUAL:
3544 	case GL_GEQUAL:
3545 	case GL_GREATER:
3546 	case GL_NOTEQUAL:
3547 		break;
3548 	default:
3549 		return error(GL_INVALID_ENUM);
3550 	}
3551 
3552 	es1::Context *context = es1::getContext();
3553 
3554 	if(context)
3555 	{
3556 		context->setStencilParams(func, ref, mask);
3557 	}
3558 }
3559 
StencilMask(GLuint mask)3560 void StencilMask(GLuint mask)
3561 {
3562 	TRACE("(GLuint mask = %d)", mask);
3563 
3564 	es1::Context *context = es1::getContext();
3565 
3566 	if(context)
3567 	{
3568 		context->setStencilWritemask(mask);
3569 	}
3570 }
3571 
StencilOp(GLenum fail,GLenum zfail,GLenum zpass)3572 void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3573 {
3574 	TRACE("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", fail, zfail, zpass);
3575 
3576 	switch(fail)
3577 	{
3578 	case GL_ZERO:
3579 	case GL_KEEP:
3580 	case GL_REPLACE:
3581 	case GL_INCR:
3582 	case GL_DECR:
3583 	case GL_INVERT:
3584 	case GL_INCR_WRAP_OES:
3585 	case GL_DECR_WRAP_OES:
3586 		break;
3587 	default:
3588 		return error(GL_INVALID_ENUM);
3589 	}
3590 
3591 	switch(zfail)
3592 	{
3593 	case GL_ZERO:
3594 	case GL_KEEP:
3595 	case GL_REPLACE:
3596 	case GL_INCR:
3597 	case GL_DECR:
3598 	case GL_INVERT:
3599 	case GL_INCR_WRAP_OES:
3600 	case GL_DECR_WRAP_OES:
3601 		break;
3602 	default:
3603 		return error(GL_INVALID_ENUM);
3604 	}
3605 
3606 	switch(zpass)
3607 	{
3608 	case GL_ZERO:
3609 	case GL_KEEP:
3610 	case GL_REPLACE:
3611 	case GL_INCR:
3612 	case GL_DECR:
3613 	case GL_INVERT:
3614 	case GL_INCR_WRAP_OES:
3615 	case GL_DECR_WRAP_OES:
3616 		break;
3617 	default:
3618 		return error(GL_INVALID_ENUM);
3619 	}
3620 
3621 	es1::Context *context = es1::getContext();
3622 
3623 	if(context)
3624 	{
3625 		context->setStencilOperations(fail, zfail, zpass);
3626 	}
3627 }
3628 
TexCoordPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)3629 void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
3630 {
3631 	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
3632 
3633 	if(size < 2 || size > 4)
3634 	{
3635 		return error(GL_INVALID_VALUE);
3636 	}
3637 
3638 	es1::Context *context = es1::getContext();
3639 
3640 	if(context)
3641 	{
3642 		GLenum texture = context->getClientActiveTexture();
3643 		VertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
3644 	}
3645 }
3646 
3647 void TexEnvi(GLenum target, GLenum pname, GLint param);
3648 
TexEnvf(GLenum target,GLenum pname,GLfloat param)3649 void TexEnvf(GLenum target, GLenum pname, GLfloat param)
3650 {
3651 	TexEnvi(target, pname, (GLint)param);
3652 }
3653 
TexEnvfv(GLenum target,GLenum pname,const GLfloat * params)3654 void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
3655 {
3656 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params)", target, pname);
3657 
3658 	es1::Context *context = es1::getContext();
3659 
3660 	if(context)
3661 	{
3662 		GLint iParam = (GLint)roundf(params[0]);
3663 
3664 		switch(target)
3665 		{
3666 		case GL_POINT_SPRITE_OES:
3667 			UNIMPLEMENTED();
3668 			break;
3669 		case GL_TEXTURE_ENV:
3670 			switch(pname)
3671 			{
3672 			case GL_TEXTURE_ENV_MODE:
3673 				switch(iParam)
3674 				{
3675 				case GL_REPLACE:
3676 				case GL_MODULATE:
3677 				case GL_DECAL:
3678 				case GL_BLEND:
3679 				case GL_ADD:
3680 				case GL_COMBINE:
3681 					break;
3682 				default:
3683 					error(GL_INVALID_ENUM);
3684 				}
3685 
3686 				context->setTextureEnvMode(iParam);
3687 				break;
3688 			case GL_TEXTURE_ENV_COLOR:
3689 				context->setTextureEnvColor(clamp01(params[0]), clamp01(params[1]), clamp01(params[2]), clamp01(params[3]));
3690 				break;
3691 			case GL_COMBINE_RGB:
3692 				switch(iParam)
3693 				{
3694 				case GL_REPLACE:
3695 				case GL_MODULATE:
3696 				case GL_ADD:
3697 				case GL_ADD_SIGNED:
3698 				case GL_INTERPOLATE:
3699 				case GL_SUBTRACT:
3700 				case GL_DOT3_RGB:
3701 				case GL_DOT3_RGBA:
3702 					break;
3703 				default:
3704 					error(GL_INVALID_ENUM);
3705 				}
3706 
3707 				context->setCombineRGB(iParam);
3708 				break;
3709 			case GL_COMBINE_ALPHA:
3710 				switch(iParam)
3711 				{
3712 				case GL_REPLACE:
3713 				case GL_MODULATE:
3714 				case GL_ADD:
3715 				case GL_ADD_SIGNED:
3716 				case GL_INTERPOLATE:
3717 				case GL_SUBTRACT:
3718 					break;
3719 				default:
3720 					error(GL_INVALID_ENUM);
3721 				}
3722 
3723 				context->setCombineAlpha(iParam);
3724 				break;
3725 			case GL_RGB_SCALE:
3726 				if(iParam != 1 && iParam != 2 && iParam != 4)
3727 				{
3728 					return error(GL_INVALID_VALUE);
3729 				}
3730 				if(iParam != 1) UNIMPLEMENTED();
3731 				break;
3732 			case GL_ALPHA_SCALE:
3733 				if(iParam != 1 && iParam != 2 && iParam != 4)
3734 				{
3735 					return error(GL_INVALID_VALUE);
3736 				}
3737 				if(iParam != 1) UNIMPLEMENTED();
3738 				break;
3739 			case GL_OPERAND0_RGB:
3740 				switch(iParam)
3741 				{
3742 				case GL_SRC_COLOR:
3743 				case GL_ONE_MINUS_SRC_COLOR:
3744 				case GL_SRC_ALPHA:
3745 				case GL_ONE_MINUS_SRC_ALPHA:
3746 					break;
3747 				default:
3748 					error(GL_INVALID_ENUM);
3749 				}
3750 
3751 				context->setOperand0RGB(iParam);
3752 				break;
3753 			case GL_OPERAND1_RGB:
3754 				switch(iParam)
3755 				{
3756 				case GL_SRC_COLOR:
3757 				case GL_ONE_MINUS_SRC_COLOR:
3758 				case GL_SRC_ALPHA:
3759 				case GL_ONE_MINUS_SRC_ALPHA:
3760 					break;
3761 				default:
3762 					error(GL_INVALID_ENUM);
3763 				}
3764 
3765 				context->setOperand1RGB(iParam);
3766 				break;
3767 			case GL_OPERAND2_RGB:
3768 				switch(iParam)
3769 				{
3770 				case GL_SRC_COLOR:
3771 				case GL_ONE_MINUS_SRC_COLOR:
3772 				case GL_SRC_ALPHA:
3773 				case GL_ONE_MINUS_SRC_ALPHA:
3774 					break;
3775 				default:
3776 					error(GL_INVALID_ENUM);
3777 				}
3778 
3779 				context->setOperand2RGB(iParam);
3780 				break;
3781 			case GL_OPERAND0_ALPHA:
3782 				switch(iParam)
3783 				{
3784 				case GL_SRC_ALPHA:
3785 				case GL_ONE_MINUS_SRC_ALPHA:
3786 					break;
3787 				default:
3788 					error(GL_INVALID_ENUM);
3789 				}
3790 
3791 				context->setOperand0Alpha(iParam);
3792 				break;
3793 			case GL_OPERAND1_ALPHA:
3794 				switch(iParam)
3795 				{
3796 				case GL_SRC_ALPHA:
3797 				case GL_ONE_MINUS_SRC_ALPHA:
3798 					break;
3799 				default:
3800 					error(GL_INVALID_ENUM);
3801 				}
3802 
3803 				context->setOperand1Alpha(iParam);
3804 				break;
3805 			case GL_OPERAND2_ALPHA:
3806 				switch(iParam)
3807 				{
3808 				case GL_SRC_ALPHA:
3809 				case GL_ONE_MINUS_SRC_ALPHA:
3810 					break;
3811 				default:
3812 					error(GL_INVALID_ENUM);
3813 				}
3814 
3815 				context->setOperand2Alpha(iParam);
3816 				break;
3817 			case GL_SRC0_RGB:
3818 				switch(iParam)
3819 				{
3820 				case GL_TEXTURE:
3821 				case GL_CONSTANT:
3822 				case GL_PRIMARY_COLOR:
3823 				case GL_PREVIOUS:
3824 					break;
3825 				default:
3826 					error(GL_INVALID_ENUM);
3827 				}
3828 
3829 				context->setSrc0RGB(iParam);
3830 				break;
3831 			case GL_SRC1_RGB:
3832 				switch(iParam)
3833 				{
3834 				case GL_TEXTURE:
3835 				case GL_CONSTANT:
3836 				case GL_PRIMARY_COLOR:
3837 				case GL_PREVIOUS:
3838 					break;
3839 				default:
3840 					error(GL_INVALID_ENUM);
3841 				}
3842 
3843 				context->setSrc1RGB(iParam);
3844 				break;
3845 			case GL_SRC2_RGB:
3846 				switch(iParam)
3847 				{
3848 				case GL_TEXTURE:
3849 				case GL_CONSTANT:
3850 				case GL_PRIMARY_COLOR:
3851 				case GL_PREVIOUS:
3852 					break;
3853 				default:
3854 					error(GL_INVALID_ENUM);
3855 				}
3856 
3857 				context->setSrc2RGB(iParam);
3858 				break;
3859 			case GL_SRC0_ALPHA:
3860 				switch(iParam)
3861 				{
3862 				case GL_TEXTURE:
3863 				case GL_CONSTANT:
3864 				case GL_PRIMARY_COLOR:
3865 				case GL_PREVIOUS:
3866 					break;
3867 				default:
3868 					error(GL_INVALID_ENUM);
3869 				}
3870 
3871 				context->setSrc0Alpha(iParam);
3872 				break;
3873 			case GL_SRC1_ALPHA:
3874 				switch(iParam)
3875 				{
3876 				case GL_TEXTURE:
3877 				case GL_CONSTANT:
3878 				case GL_PRIMARY_COLOR:
3879 				case GL_PREVIOUS:
3880 					break;
3881 				default:
3882 					error(GL_INVALID_ENUM);
3883 				}
3884 
3885 				context->setSrc1Alpha(iParam);
3886 				break;
3887 			case GL_SRC2_ALPHA:
3888 				switch(iParam)
3889 				{
3890 				case GL_TEXTURE:
3891 				case GL_CONSTANT:
3892 				case GL_PRIMARY_COLOR:
3893 				case GL_PREVIOUS:
3894 					break;
3895 				default:
3896 					error(GL_INVALID_ENUM);
3897 				}
3898 
3899 				context->setSrc2Alpha(iParam);
3900 				break;
3901 			default:
3902 				return error(GL_INVALID_ENUM);
3903 			}
3904 			break;
3905 		default:
3906 			return error(GL_INVALID_ENUM);
3907 		}
3908 	}
3909 }
3910 
TexEnvi(GLenum target,GLenum pname,GLint param)3911 void TexEnvi(GLenum target, GLenum pname, GLint param)
3912 {
3913 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
3914 
3915 	es1::Context *context = es1::getContext();
3916 
3917 	if(context)
3918 	{
3919 		switch(target)
3920 		{
3921 		case GL_POINT_SPRITE_OES:
3922 			UNIMPLEMENTED();
3923 			break;
3924 		case GL_TEXTURE_ENV:
3925 			switch(pname)
3926 			{
3927 			case GL_TEXTURE_ENV_MODE:
3928 				switch((GLenum)param)
3929 				{
3930 				case GL_REPLACE:
3931 				case GL_MODULATE:
3932 				case GL_DECAL:
3933 				case GL_BLEND:
3934 				case GL_ADD:
3935 				case GL_COMBINE:
3936 					break;
3937 				default:
3938 					error(GL_INVALID_ENUM);
3939 				}
3940 
3941 				context->setTextureEnvMode((GLenum)param);
3942 				break;
3943 			case GL_TEXTURE_ENV_COLOR:
3944 				return error(GL_INVALID_ENUM);   // Needs four values, should call glTexEnviv() instead
3945 				break;
3946 			case GL_COMBINE_RGB:
3947 				switch((GLenum)param)
3948 				{
3949 				case GL_REPLACE:
3950 				case GL_MODULATE:
3951 				case GL_ADD:
3952 				case GL_ADD_SIGNED:
3953 				case GL_INTERPOLATE:
3954 				case GL_SUBTRACT:
3955 				case GL_DOT3_RGB:
3956 				case GL_DOT3_RGBA:
3957 					break;
3958 				default:
3959 					error(GL_INVALID_ENUM);
3960 				}
3961 
3962 				context->setCombineRGB((GLenum)param);
3963 				break;
3964 			case GL_COMBINE_ALPHA:
3965 				switch((GLenum)param)
3966 				{
3967 				case GL_REPLACE:
3968 				case GL_MODULATE:
3969 				case GL_ADD:
3970 				case GL_ADD_SIGNED:
3971 				case GL_INTERPOLATE:
3972 				case GL_SUBTRACT:
3973 					break;
3974 				default:
3975 					error(GL_INVALID_ENUM);
3976 				}
3977 
3978 				context->setCombineAlpha((GLenum)param);
3979 				break;
3980 			case GL_RGB_SCALE:
3981 				if(param != 1 && param != 2 && param != 4)
3982 				{
3983 					return error(GL_INVALID_VALUE);
3984 				}
3985 				if(param != 1) UNIMPLEMENTED();
3986 				break;
3987 			case GL_ALPHA_SCALE:
3988 				if(param != 1 && param != 2 && param != 4)
3989 				{
3990 					return error(GL_INVALID_VALUE);
3991 				}
3992 				if(param != 1) UNIMPLEMENTED();
3993 				break;
3994 			case GL_OPERAND0_RGB:
3995 				switch((GLenum)param)
3996 				{
3997 				case GL_SRC_COLOR:
3998 				case GL_ONE_MINUS_SRC_COLOR:
3999 				case GL_SRC_ALPHA:
4000 				case GL_ONE_MINUS_SRC_ALPHA:
4001 					break;
4002 				default:
4003 					error(GL_INVALID_ENUM);
4004 				}
4005 
4006 				context->setOperand0RGB((GLenum)param);
4007 				break;
4008 			case GL_OPERAND1_RGB:
4009 				switch((GLenum)param)
4010 				{
4011 				case GL_SRC_COLOR:
4012 				case GL_ONE_MINUS_SRC_COLOR:
4013 				case GL_SRC_ALPHA:
4014 				case GL_ONE_MINUS_SRC_ALPHA:
4015 					break;
4016 				default:
4017 					error(GL_INVALID_ENUM);
4018 				}
4019 
4020 				context->setOperand1RGB((GLenum)param);
4021 				break;
4022 			case GL_OPERAND2_RGB:
4023 				switch((GLenum)param)
4024 				{
4025 				case GL_SRC_COLOR:
4026 				case GL_ONE_MINUS_SRC_COLOR:
4027 				case GL_SRC_ALPHA:
4028 				case GL_ONE_MINUS_SRC_ALPHA:
4029 					break;
4030 				default:
4031 					error(GL_INVALID_ENUM);
4032 				}
4033 
4034 				context->setOperand2RGB((GLenum)param);
4035 				break;
4036 			case GL_OPERAND0_ALPHA:
4037 				switch((GLenum)param)
4038 				{
4039 				case GL_SRC_ALPHA:
4040 				case GL_ONE_MINUS_SRC_ALPHA:
4041 					break;
4042 				default:
4043 					error(GL_INVALID_ENUM);
4044 				}
4045 
4046 				context->setOperand0Alpha((GLenum)param);
4047 				break;
4048 			case GL_OPERAND1_ALPHA:
4049 				switch((GLenum)param)
4050 				{
4051 				case GL_SRC_ALPHA:
4052 				case GL_ONE_MINUS_SRC_ALPHA:
4053 					break;
4054 				default:
4055 					error(GL_INVALID_ENUM);
4056 				}
4057 
4058 				context->setOperand1Alpha((GLenum)param);
4059 				break;
4060 			case GL_OPERAND2_ALPHA:
4061 				switch((GLenum)param)
4062 				{
4063 				case GL_SRC_ALPHA:
4064 				case GL_ONE_MINUS_SRC_ALPHA:
4065 					break;
4066 				default:
4067 					error(GL_INVALID_ENUM);
4068 				}
4069 
4070 				context->setOperand2Alpha((GLenum)param);
4071 				break;
4072 			case GL_SRC0_RGB:
4073 				switch((GLenum)param)
4074 				{
4075 				case GL_TEXTURE:
4076 				case GL_CONSTANT:
4077 				case GL_PRIMARY_COLOR:
4078 				case GL_PREVIOUS:
4079 					break;
4080 				default:
4081 					error(GL_INVALID_ENUM);
4082 				}
4083 
4084 				context->setSrc0RGB((GLenum)param);
4085 				break;
4086 			case GL_SRC1_RGB:
4087 				switch((GLenum)param)
4088 				{
4089 				case GL_TEXTURE:
4090 				case GL_CONSTANT:
4091 				case GL_PRIMARY_COLOR:
4092 				case GL_PREVIOUS:
4093 					break;
4094 				default:
4095 					error(GL_INVALID_ENUM);
4096 				}
4097 
4098 				context->setSrc1RGB((GLenum)param);
4099 				break;
4100 			case GL_SRC2_RGB:
4101 				switch((GLenum)param)
4102 				{
4103 				case GL_TEXTURE:
4104 				case GL_CONSTANT:
4105 				case GL_PRIMARY_COLOR:
4106 				case GL_PREVIOUS:
4107 					break;
4108 				default:
4109 					error(GL_INVALID_ENUM);
4110 				}
4111 
4112 				context->setSrc2RGB((GLenum)param);
4113 				break;
4114 			case GL_SRC0_ALPHA:
4115 				switch((GLenum)param)
4116 				{
4117 				case GL_TEXTURE:
4118 				case GL_CONSTANT:
4119 				case GL_PRIMARY_COLOR:
4120 				case GL_PREVIOUS:
4121 					break;
4122 				default:
4123 					error(GL_INVALID_ENUM);
4124 				}
4125 
4126 				context->setSrc0Alpha((GLenum)param);
4127 				break;
4128 			case GL_SRC1_ALPHA:
4129 				switch((GLenum)param)
4130 				{
4131 				case GL_TEXTURE:
4132 				case GL_CONSTANT:
4133 				case GL_PRIMARY_COLOR:
4134 				case GL_PREVIOUS:
4135 					break;
4136 				default:
4137 					error(GL_INVALID_ENUM);
4138 				}
4139 
4140 				context->setSrc1Alpha((GLenum)param);
4141 				break;
4142 			case GL_SRC2_ALPHA:
4143 				switch((GLenum)param)
4144 				{
4145 				case GL_TEXTURE:
4146 				case GL_CONSTANT:
4147 				case GL_PRIMARY_COLOR:
4148 				case GL_PREVIOUS:
4149 					break;
4150 				default:
4151 					error(GL_INVALID_ENUM);
4152 				}
4153 
4154 				context->setSrc2Alpha((GLenum)param);
4155 				break;
4156 			default:
4157 				return error(GL_INVALID_ENUM);
4158 			}
4159 			break;
4160 		default:
4161 			return error(GL_INVALID_ENUM);
4162 		}
4163 	}
4164 }
4165 
TexEnvx(GLenum target,GLenum pname,GLfixed param)4166 void TexEnvx(GLenum target, GLenum pname, GLfixed param)
4167 {
4168 	TexEnvi(target, pname, (GLint)param);
4169 }
4170 
TexEnviv(GLenum target,GLenum pname,const GLint * params)4171 void TexEnviv(GLenum target, GLenum pname, const GLint *params)
4172 {
4173 	UNIMPLEMENTED();
4174 }
4175 
TexEnvxv(GLenum target,GLenum pname,const GLfixed * params)4176 void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
4177 {
4178 	UNIMPLEMENTED();
4179 }
4180 
TexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)4181 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4182                 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4183 {
4184 	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
4185 	      "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",
4186 	      target, level, internalformat, width, height, border, format, type, pixels);
4187 
4188 	if(!validImageSize(level, width, height))
4189 	{
4190 		return error(GL_INVALID_VALUE);
4191 	}
4192 
4193 	if(internalformat != (GLint)format)
4194 	{
4195 		return error(GL_INVALID_OPERATION);
4196 	}
4197 
4198 	switch(format)
4199 	{
4200 	case GL_ALPHA:
4201 	case GL_LUMINANCE:
4202 	case GL_LUMINANCE_ALPHA:
4203 		switch(type)
4204 		{
4205 		case GL_UNSIGNED_BYTE:
4206 			break;
4207 		default:
4208 			return error(GL_INVALID_ENUM);
4209 		}
4210 		break;
4211 	case GL_RGB:
4212 		switch(type)
4213 		{
4214 		case GL_UNSIGNED_BYTE:
4215 		case GL_UNSIGNED_SHORT_5_6_5:
4216 			break;
4217 		default:
4218 			return error(GL_INVALID_ENUM);
4219 		}
4220 		break;
4221 	case GL_RGBA:
4222 		switch(type)
4223 		{
4224 		case GL_UNSIGNED_BYTE:
4225 		case GL_UNSIGNED_SHORT_4_4_4_4:
4226 		case GL_UNSIGNED_SHORT_5_5_5_1:
4227 			break;
4228 		default:
4229 			return error(GL_INVALID_ENUM);
4230 		}
4231 		break;
4232 	case GL_BGRA_EXT:
4233 		switch(type)
4234 		{
4235 		case GL_UNSIGNED_BYTE:
4236 			break;
4237 		default:
4238 			return error(GL_INVALID_ENUM);
4239 		}
4240 		break;
4241 	case GL_ETC1_RGB8_OES:
4242 	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
4243 	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4244 		return error(GL_INVALID_OPERATION);
4245 	case GL_DEPTH_STENCIL_OES:
4246 		switch(type)
4247 		{
4248 		case GL_UNSIGNED_INT_24_8_OES:
4249 			break;
4250 		default:
4251 			return error(GL_INVALID_ENUM);
4252 		}
4253 		break;
4254 	default:
4255 		return error(GL_INVALID_VALUE);
4256 	}
4257 
4258 	if(border != 0)
4259 	{
4260 		return error(GL_INVALID_VALUE);
4261 	}
4262 
4263 	GLint sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type);
4264 
4265 	es1::Context *context = es1::getContext();
4266 
4267 	if(context)
4268 	{
4269 		switch(target)
4270 		{
4271 		case GL_TEXTURE_2D:
4272 			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4273 			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4274 			{
4275 				return error(GL_INVALID_VALUE);
4276 			}
4277 			break;
4278 		default:
4279 			return error(GL_INVALID_ENUM);
4280 		}
4281 
4282 		if(target == GL_TEXTURE_2D)
4283 		{
4284 			es1::Texture2D *texture = context->getTexture2D();
4285 
4286 			if(!texture)
4287 			{
4288 				return error(GL_INVALID_OPERATION);
4289 			}
4290 
4291 			texture->setImage(level, width, height, sizedInternalFormat, format, type, context->getUnpackAlignment(), pixels);
4292 		}
4293 		else UNREACHABLE(target);
4294 	}
4295 }
4296 
TexParameterf(GLenum target,GLenum pname,GLfloat param)4297 void TexParameterf(GLenum target, GLenum pname, GLfloat param)
4298 {
4299 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
4300 
4301 	es1::Context *context = es1::getContext();
4302 
4303 	if(context)
4304 	{
4305 		es1::Texture *texture;
4306 
4307 		switch(target)
4308 		{
4309 		case GL_TEXTURE_2D:
4310 			texture = context->getTexture2D();
4311 			break;
4312 		case GL_TEXTURE_EXTERNAL_OES:
4313 			texture = context->getTextureExternal();
4314 			break;
4315 		default:
4316 			return error(GL_INVALID_ENUM);
4317 		}
4318 
4319 		switch(pname)
4320 		{
4321 		case GL_TEXTURE_WRAP_S:
4322 			if(!texture->setWrapS((GLenum)param))
4323 			{
4324 				return error(GL_INVALID_ENUM);
4325 			}
4326 			break;
4327 		case GL_TEXTURE_WRAP_T:
4328 			if(!texture->setWrapT((GLenum)param))
4329 			{
4330 				return error(GL_INVALID_ENUM);
4331 			}
4332 			break;
4333 		case GL_TEXTURE_MIN_FILTER:
4334 			if(!texture->setMinFilter((GLenum)param))
4335 			{
4336 				return error(GL_INVALID_ENUM);
4337 			}
4338 			break;
4339 		case GL_TEXTURE_MAG_FILTER:
4340 			if(!texture->setMagFilter((GLenum)param))
4341 			{
4342 				return error(GL_INVALID_ENUM);
4343 			}
4344 			break;
4345 		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4346 			if(!texture->setMaxAnisotropy(param))
4347 			{
4348 				return error(GL_INVALID_VALUE);
4349 			}
4350 			break;
4351 		case GL_GENERATE_MIPMAP:
4352 			texture->setGenerateMipmap((GLboolean)param);
4353 			break;
4354 		case GL_TEXTURE_CROP_RECT_OES:
4355 			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameterfv() instead
4356 		default:
4357 			return error(GL_INVALID_ENUM);
4358 		}
4359 	}
4360 }
4361 
TexParameterfv(GLenum target,GLenum pname,const GLfloat * params)4362 void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4363 {
4364 	TexParameterf(target, pname, *params);
4365 }
4366 
TexParameteri(GLenum target,GLenum pname,GLint param)4367 void TexParameteri(GLenum target, GLenum pname, GLint param)
4368 {
4369 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
4370 
4371 	es1::Context *context = es1::getContext();
4372 
4373 	if(context)
4374 	{
4375 		es1::Texture *texture;
4376 
4377 		switch(target)
4378 		{
4379 		case GL_TEXTURE_2D:
4380 			texture = context->getTexture2D();
4381 			break;
4382 		case GL_TEXTURE_EXTERNAL_OES:
4383 			texture = context->getTextureExternal();
4384 			break;
4385 		default:
4386 			return error(GL_INVALID_ENUM);
4387 		}
4388 
4389 		switch(pname)
4390 		{
4391 		case GL_TEXTURE_WRAP_S:
4392 			if(!texture->setWrapS((GLenum)param))
4393 			{
4394 				return error(GL_INVALID_ENUM);
4395 			}
4396 			break;
4397 		case GL_TEXTURE_WRAP_T:
4398 			if(!texture->setWrapT((GLenum)param))
4399 			{
4400 				return error(GL_INVALID_ENUM);
4401 			}
4402 			break;
4403 		case GL_TEXTURE_MIN_FILTER:
4404 			if(!texture->setMinFilter((GLenum)param))
4405 			{
4406 				return error(GL_INVALID_ENUM);
4407 			}
4408 			break;
4409 		case GL_TEXTURE_MAG_FILTER:
4410 			if(!texture->setMagFilter((GLenum)param))
4411 			{
4412 				return error(GL_INVALID_ENUM);
4413 			}
4414 			break;
4415 		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4416 			if(!texture->setMaxAnisotropy((GLfloat)param))
4417 			{
4418 				return error(GL_INVALID_VALUE);
4419 			}
4420 			break;
4421 		case GL_GENERATE_MIPMAP:
4422 			texture->setGenerateMipmap((GLboolean)param);
4423 			break;
4424 		case GL_TEXTURE_CROP_RECT_OES:
4425 			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameteriv() instead
4426 		default:
4427 			return error(GL_INVALID_ENUM);
4428 		}
4429 	}
4430 }
4431 
TexParameteriv(GLenum target,GLenum pname,const GLint * params)4432 void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
4433 {
4434 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %p)", target, pname, params);
4435 
4436 	switch(pname)
4437 	{
4438 	case GL_TEXTURE_CROP_RECT_OES:
4439 		break;
4440 	default:
4441 		return TexParameteri(target, pname, params[0]);
4442 	}
4443 
4444 	es1::Context *context = es1::getContext();
4445 
4446 	if(context)
4447 	{
4448 		es1::Texture *texture;
4449 
4450 		switch(target)
4451 		{
4452 		case GL_TEXTURE_2D:
4453 			texture = context->getTexture2D();
4454 			break;
4455 		default:
4456 			return error(GL_INVALID_ENUM);
4457 		}
4458 
4459 		switch(pname)
4460 		{
4461 		case GL_TEXTURE_CROP_RECT_OES:
4462 			texture->setCropRect(params[0], params[1], params[2], params[3]);
4463 			break;
4464 		default:
4465 			return error(GL_INVALID_ENUM);
4466 		}
4467 	}
4468 }
4469 
TexParameterx(GLenum target,GLenum pname,GLfixed param)4470 void TexParameterx(GLenum target, GLenum pname, GLfixed param)
4471 {
4472 	TexParameteri(target, pname, (GLint)param);
4473 }
4474 
TexParameterxv(GLenum target,GLenum pname,const GLfixed * params)4475 void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
4476 {
4477 	UNIMPLEMENTED();
4478 }
4479 
TexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)4480 void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4481                    GLenum format, GLenum type, const GLvoid* pixels)
4482 {
4483 	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4484 	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
4485 	      "const GLvoid* pixels = %p)",
4486 	      target, level, xoffset, yoffset, width, height, format, type, pixels);
4487 
4488 	if(!es1::IsTextureTarget(target))
4489 	{
4490 		return error(GL_INVALID_ENUM);
4491 	}
4492 
4493 	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
4494 	{
4495 		return error(GL_INVALID_VALUE);
4496 	}
4497 
4498 	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
4499 	{
4500 		return error(GL_INVALID_VALUE);
4501 	}
4502 
4503 	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4504 	{
4505 		return error(GL_INVALID_VALUE);
4506 	}
4507 
4508 	if(width == 0 || height == 0 || !pixels)
4509 	{
4510 		return;
4511 	}
4512 
4513 	es1::Context *context = es1::getContext();
4514 
4515 	if(context)
4516 	{
4517 		if(target == GL_TEXTURE_2D)
4518 		{
4519 			es1::Texture2D *texture = context->getTexture2D();
4520 
4521 			GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture);
4522 			if(validationError != GL_NO_ERROR)
4523 			{
4524 				return error(validationError);
4525 			}
4526 
4527 			texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4528 		}
4529 		else UNREACHABLE(target);
4530 	}
4531 }
4532 
Translatef(GLfloat x,GLfloat y,GLfloat z)4533 void Translatef(GLfloat x, GLfloat y, GLfloat z)
4534 {
4535 	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
4536 
4537 	es1::Context *context = es1::getContext();
4538 
4539 	if(context)
4540 	{
4541 		context->translate(x, y, z);
4542 	}
4543 }
4544 
Translatex(GLfixed x,GLfixed y,GLfixed z)4545 void Translatex(GLfixed x, GLfixed y, GLfixed z)
4546 {
4547 	Translatef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
4548 }
4549 
VertexPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)4550 void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
4551 {
4552 	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
4553 
4554 	if(size < 2 || size > 4)
4555 	{
4556 		return error(GL_INVALID_VALUE);
4557 	}
4558 
4559 	VertexAttribPointer(sw::Position, size, type, false, stride, pointer);
4560 }
4561 
Viewport(GLint x,GLint y,GLsizei width,GLsizei height)4562 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
4563 {
4564 	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4565 
4566 	if(width < 0 || height < 0)
4567 	{
4568 		return error(GL_INVALID_VALUE);
4569 	}
4570 
4571 	es1::Context *context = es1::getContext();
4572 
4573 	if(context)
4574 	{
4575 		context->setViewportParams(x, y, width, height);
4576 	}
4577 }
4578 
EGLImageTargetTexture2DOES(GLenum target,GLeglImageOES image)4579 void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
4580 {
4581 	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
4582 
4583 	switch(target)
4584 	{
4585 	case GL_TEXTURE_2D:
4586 	case GL_TEXTURE_EXTERNAL_OES:
4587 		break;
4588 	default:
4589 		return error(GL_INVALID_ENUM);
4590 	}
4591 
4592 	es1::Context *context = es1::getContext();
4593 
4594 	if(context)
4595 	{
4596 		es1::Texture2D *texture = nullptr;
4597 
4598 		switch(target)
4599 		{
4600 		case GL_TEXTURE_2D:           texture = context->getTexture2D();       break;
4601 		case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
4602 		default:                      UNREACHABLE(target);
4603 		}
4604 
4605 		if(!texture)
4606 		{
4607 			return error(GL_INVALID_OPERATION);
4608 		}
4609 
4610 		egl::Image *eglImage = context->getSharedImage(image);
4611 
4612 		if(!eglImage)
4613 		{
4614 			return error(GL_INVALID_OPERATION);
4615 		}
4616 
4617 		texture->setSharedImage(eglImage);
4618 	}
4619 }
4620 
EGLImageTargetRenderbufferStorageOES(GLenum target,GLeglImageOES image)4621 void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
4622 {
4623 	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
4624 
4625 	UNIMPLEMENTED();
4626 }
4627 
DrawTexsOES(GLshort x,GLshort y,GLshort z,GLshort width,GLshort height)4628 void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
4629 {
4630 	UNIMPLEMENTED();
4631 }
4632 
DrawTexiOES(GLint x,GLint y,GLint z,GLint width,GLint height)4633 void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
4634 {
4635 	TRACE("(GLint x = %d, GLint y = %d, GLint z = %d, GLint width = %d, GLint height = %d)", x, y, z, width, height);
4636 
4637 	if(width <= 0 || height <= 0)
4638 	{
4639 		return error(GL_INVALID_VALUE);
4640 	}
4641 
4642 	es1::Context *context = es1::getContext();
4643 
4644 	if(context)
4645 	{
4646 		context->drawTexture((GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)width, (GLfloat)height);
4647 	}
4648 }
4649 
DrawTexxOES(GLfixed x,GLfixed y,GLfixed z,GLfixed width,GLfixed height)4650 void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
4651 {
4652 	UNIMPLEMENTED();
4653 }
4654 
DrawTexsvOES(const GLshort * coords)4655 void DrawTexsvOES(const GLshort *coords)
4656 {
4657 	UNIMPLEMENTED();
4658 }
4659 
DrawTexivOES(const GLint * coords)4660 void DrawTexivOES(const GLint *coords)
4661 {
4662 	UNIMPLEMENTED();
4663 }
4664 
DrawTexxvOES(const GLfixed * coords)4665 void DrawTexxvOES(const GLfixed *coords)
4666 {
4667 	UNIMPLEMENTED();
4668 }
4669 
DrawTexfOES(GLfloat x,GLfloat y,GLfloat z,GLfloat width,GLfloat height)4670 void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
4671 {
4672 	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat width = %f, GLfloat height = %f)", x, y, z, width, height);
4673 
4674 	if(width <= 0 || height <= 0)
4675 	{
4676 		return error(GL_INVALID_VALUE);
4677 	}
4678 
4679 	es1::Context *context = es1::getContext();
4680 
4681 	if(context)
4682 	{
4683 		context->drawTexture(x, y, z, width, height);
4684 	}
4685 }
4686 
DrawTexfvOES(const GLfloat * coords)4687 void DrawTexfvOES(const GLfloat *coords)
4688 {
4689 	UNIMPLEMENTED();
4690 }
4691 
4692 }
4693 
es1GetProcAddress(const char * procname)4694 extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname)
4695 {
4696 	struct Function
4697 	{
4698 		const char *name;
4699 		__eglMustCastToProperFunctionPointerType address;
4700 	};
4701 
4702 	struct CompareFunctor
4703 	{
4704 		bool operator()(const Function &a, const Function &b) const
4705 		{
4706 			return strcmp(a.name, b.name) < 0;
4707 		}
4708 	};
4709 
4710 	// This array must be kept sorted with respect to strcmp(), so that binary search works correctly.
4711 	// The Unix command "LC_COLLATE=C sort" will generate the correct order.
4712 	static const Function glFunctions[] =
4713 	{
4714 		#define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
4715 
4716 		FUNCTION(glActiveTexture),
4717 		FUNCTION(glAlphaFunc),
4718 		FUNCTION(glAlphaFuncx),
4719 		FUNCTION(glBindBuffer),
4720 		FUNCTION(glBindFramebufferOES),
4721 		FUNCTION(glBindRenderbufferOES),
4722 		FUNCTION(glBindTexture),
4723 		FUNCTION(glBlendEquationOES),
4724 		FUNCTION(glBlendEquationSeparateOES),
4725 		FUNCTION(glBlendFunc),
4726 		FUNCTION(glBlendFuncSeparateOES),
4727 		FUNCTION(glBufferData),
4728 		FUNCTION(glBufferSubData),
4729 		FUNCTION(glCheckFramebufferStatusOES),
4730 		FUNCTION(glClear),
4731 		FUNCTION(glClearColor),
4732 		FUNCTION(glClearColorx),
4733 		FUNCTION(glClearDepthf),
4734 		FUNCTION(glClearDepthx),
4735 		FUNCTION(glClearStencil),
4736 		FUNCTION(glClientActiveTexture),
4737 		FUNCTION(glClipPlanef),
4738 		FUNCTION(glClipPlanex),
4739 		FUNCTION(glColor4f),
4740 		FUNCTION(glColor4ub),
4741 		FUNCTION(glColor4x),
4742 		FUNCTION(glColorMask),
4743 		FUNCTION(glColorPointer),
4744 		FUNCTION(glCompressedTexImage2D),
4745 		FUNCTION(glCompressedTexSubImage2D),
4746 		FUNCTION(glCopyTexImage2D),
4747 		FUNCTION(glCopyTexSubImage2D),
4748 		FUNCTION(glCullFace),
4749 		FUNCTION(glDeleteBuffers),
4750 		FUNCTION(glDeleteFramebuffersOES),
4751 		FUNCTION(glDeleteRenderbuffersOES),
4752 		FUNCTION(glDeleteTextures),
4753 		FUNCTION(glDepthFunc),
4754 		FUNCTION(glDepthMask),
4755 		FUNCTION(glDepthRangef),
4756 		FUNCTION(glDepthRangex),
4757 		FUNCTION(glDisable),
4758 		FUNCTION(glDisableClientState),
4759 		FUNCTION(glDrawArrays),
4760 		FUNCTION(glDrawElements),
4761 		FUNCTION(glDrawTexfOES),
4762 		FUNCTION(glDrawTexfvOES),
4763 		FUNCTION(glDrawTexiOES),
4764 		FUNCTION(glDrawTexivOES),
4765 		FUNCTION(glDrawTexsOES),
4766 		FUNCTION(glDrawTexsvOES),
4767 		FUNCTION(glDrawTexxOES),
4768 		FUNCTION(glDrawTexxvOES),
4769 		FUNCTION(glEGLImageTargetRenderbufferStorageOES),
4770 		FUNCTION(glEGLImageTargetTexture2DOES),
4771 		FUNCTION(glEnable),
4772 		FUNCTION(glEnableClientState),
4773 		FUNCTION(glFinish),
4774 		FUNCTION(glFlush),
4775 		FUNCTION(glFogf),
4776 		FUNCTION(glFogfv),
4777 		FUNCTION(glFogx),
4778 		FUNCTION(glFogxv),
4779 		FUNCTION(glFramebufferRenderbufferOES),
4780 		FUNCTION(glFramebufferTexture2DOES),
4781 		FUNCTION(glFrontFace),
4782 		FUNCTION(glFrustumf),
4783 		FUNCTION(glFrustumx),
4784 		FUNCTION(glGenBuffers),
4785 		FUNCTION(glGenFramebuffersOES),
4786 		FUNCTION(glGenRenderbuffersOES),
4787 		FUNCTION(glGenTextures),
4788 		FUNCTION(glGenerateMipmapOES),
4789 		FUNCTION(glGetBooleanv),
4790 		FUNCTION(glGetBufferParameteriv),
4791 		FUNCTION(glGetClipPlanef),
4792 		FUNCTION(glGetClipPlanex),
4793 		FUNCTION(glGetError),
4794 		FUNCTION(glGetFixedv),
4795 		FUNCTION(glGetFloatv),
4796 		FUNCTION(glGetFramebufferAttachmentParameterivOES),
4797 		FUNCTION(glGetIntegerv),
4798 		FUNCTION(glGetLightfv),
4799 		FUNCTION(glGetLightxv),
4800 		FUNCTION(glGetMaterialfv),
4801 		FUNCTION(glGetMaterialxv),
4802 		FUNCTION(glGetPointerv),
4803 		FUNCTION(glGetRenderbufferParameterivOES),
4804 		FUNCTION(glGetString),
4805 		FUNCTION(glGetTexEnvfv),
4806 		FUNCTION(glGetTexEnviv),
4807 		FUNCTION(glGetTexEnvxv),
4808 		FUNCTION(glGetTexParameterfv),
4809 		FUNCTION(glGetTexParameteriv),
4810 		FUNCTION(glGetTexParameterxv),
4811 		FUNCTION(glHint),
4812 		FUNCTION(glIsBuffer),
4813 		FUNCTION(glIsEnabled),
4814 		FUNCTION(glIsFramebufferOES),
4815 		FUNCTION(glIsRenderbufferOES),
4816 		FUNCTION(glIsTexture),
4817 		FUNCTION(glLightModelf),
4818 		FUNCTION(glLightModelfv),
4819 		FUNCTION(glLightModelx),
4820 		FUNCTION(glLightModelxv),
4821 		FUNCTION(glLightf),
4822 		FUNCTION(glLightfv),
4823 		FUNCTION(glLightx),
4824 		FUNCTION(glLightxv),
4825 		FUNCTION(glLineWidth),
4826 		FUNCTION(glLineWidthx),
4827 		FUNCTION(glLoadIdentity),
4828 		FUNCTION(glLoadMatrixf),
4829 		FUNCTION(glLoadMatrixx),
4830 		FUNCTION(glLogicOp),
4831 		FUNCTION(glMaterialf),
4832 		FUNCTION(glMaterialfv),
4833 		FUNCTION(glMaterialx),
4834 		FUNCTION(glMaterialxv),
4835 		FUNCTION(glMatrixMode),
4836 		FUNCTION(glMultMatrixf),
4837 		FUNCTION(glMultMatrixx),
4838 		FUNCTION(glMultiTexCoord4f),
4839 		FUNCTION(glMultiTexCoord4x),
4840 		FUNCTION(glNormal3f),
4841 		FUNCTION(glNormal3x),
4842 		FUNCTION(glNormalPointer),
4843 		FUNCTION(glOrthof),
4844 		FUNCTION(glOrthox),
4845 		FUNCTION(glPixelStorei),
4846 		FUNCTION(glPointParameterf),
4847 		FUNCTION(glPointParameterfv),
4848 		FUNCTION(glPointParameterx),
4849 		FUNCTION(glPointParameterxv),
4850 		FUNCTION(glPointSize),
4851 		FUNCTION(glPointSizePointerOES),
4852 		FUNCTION(glPointSizex),
4853 		FUNCTION(glPolygonOffset),
4854 		FUNCTION(glPolygonOffsetx),
4855 		FUNCTION(glPopMatrix),
4856 		FUNCTION(glPushMatrix),
4857 		FUNCTION(glReadPixels),
4858 		FUNCTION(glRenderbufferStorageOES),
4859 		FUNCTION(glRotatef),
4860 		FUNCTION(glRotatex),
4861 		FUNCTION(glSampleCoverage),
4862 		FUNCTION(glSampleCoveragex),
4863 		FUNCTION(glScalef),
4864 		FUNCTION(glScalex),
4865 		FUNCTION(glScissor),
4866 		FUNCTION(glShadeModel),
4867 		FUNCTION(glStencilFunc),
4868 		FUNCTION(glStencilMask),
4869 		FUNCTION(glStencilOp),
4870 		FUNCTION(glTexCoordPointer),
4871 		FUNCTION(glTexEnvf),
4872 		FUNCTION(glTexEnvfv),
4873 		FUNCTION(glTexEnvi),
4874 		FUNCTION(glTexEnviv),
4875 		FUNCTION(glTexEnvx),
4876 		FUNCTION(glTexEnvxv),
4877 		FUNCTION(glTexImage2D),
4878 		FUNCTION(glTexParameterf),
4879 		FUNCTION(glTexParameterfv),
4880 		FUNCTION(glTexParameteri),
4881 		FUNCTION(glTexParameteriv),
4882 		FUNCTION(glTexParameterx),
4883 		FUNCTION(glTexParameterxv),
4884 		FUNCTION(glTexSubImage2D),
4885 		FUNCTION(glTranslatef),
4886 		FUNCTION(glTranslatex),
4887 		FUNCTION(glVertexPointer),
4888 		FUNCTION(glViewport),
4889 
4890 		#undef FUNCTION
4891 	};
4892 
4893 	static const size_t numFunctions = sizeof glFunctions / sizeof(Function);
4894 	static const Function *const glFunctionsEnd = glFunctions + numFunctions;
4895 
4896 	Function needle;
4897 	needle.name = procname;
4898 
4899 	if(procname && strncmp("gl", procname, 2) == 0)
4900 	{
4901 		const Function *result = std::lower_bound(glFunctions, glFunctionsEnd, needle, CompareFunctor());
4902 		if(result != glFunctionsEnd && strcmp(procname, result->name) == 0)
4903 		{
4904 			return (__eglMustCastToProperFunctionPointerType)result->address;
4905 		}
4906 	}
4907 
4908 	return nullptr;
4909 }
4910