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