Home | History | Annotate | Download | only in libGLES_CM
      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 
     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 
     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 
     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 
    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 
    129 void AlphaFuncx(GLenum func, GLclampx ref)
    130 {
    131 	AlphaFunc(func, (float)ref / 0x10000);
    132 }
    133 
    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 
    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 
    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 
    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 
    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 
    247 void BlendEquationOES(GLenum mode)
    248 {
    249 	BlendEquationSeparateOES(mode, mode);
    250 }
    251 
    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 
    290 void BlendFunc(GLenum sfactor, GLenum dfactor)
    291 {
    292 	BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor);
    293 }
    294 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    544 void ClearDepthx(GLclampx depth)
    545 {
    546 	ClearDepthf((float)depth / 0x10000);
    547 }
    548 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1195 void DepthRangex(GLclampx zNear, GLclampx zFar)
   1196 {
   1197 	DepthRangef((float)zNear / 0x10000, (float)zFar / 0x10000);
   1198 }
   1199 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1699 void Fogxv(GLenum pname, const GLfixed *params)
   1700 {
   1701 	UNIMPLEMENTED();
   1702 }
   1703 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1996 void GetClipPlanef(GLenum pname, GLfloat eqn[4])
   1997 {
   1998 	UNIMPLEMENTED();
   1999 }
   2000 
   2001 void GetClipPlanex(GLenum pname, GLfixed eqn[4])
   2002 {
   2003 	UNIMPLEMENTED();
   2004 }
   2005 
   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 
   2020 void GetFixedv(GLenum pname, GLfixed *params)
   2021 {
   2022 	UNIMPLEMENTED();
   2023 }
   2024 
   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 
   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 
   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 
   2231 void GetLightfv(GLenum light, GLenum pname, GLfloat *params)
   2232 {
   2233 	UNIMPLEMENTED();
   2234 }
   2235 
   2236 void GetLightxv(GLenum light, GLenum pname, GLfixed *params)
   2237 {
   2238 	UNIMPLEMENTED();
   2239 }
   2240 
   2241 void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
   2242 {
   2243 	UNIMPLEMENTED();
   2244 }
   2245 
   2246 void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
   2247 {
   2248 	UNIMPLEMENTED();
   2249 }
   2250 
   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 
   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 
   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 
   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 
   2417 void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
   2418 {
   2419 	UNIMPLEMENTED();
   2420 }
   2421 
   2422 void GetTexEnviv(GLenum env, GLenum pname, GLint *params)
   2423 {
   2424 	UNIMPLEMENTED();
   2425 }
   2426 
   2427 void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
   2428 {
   2429 	UNIMPLEMENTED();
   2430 }
   2431 
   2432 void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
   2433 {
   2434 	UNIMPLEMENTED();
   2435 }
   2436 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   2821 void Lightx(GLenum light, GLenum pname, GLfixed param)
   2822 {
   2823 	UNIMPLEMENTED();
   2824 }
   2825 
   2826 void Lightxv(GLenum light, GLenum pname, const GLfixed *params)
   2827 {
   2828 	UNIMPLEMENTED();
   2829 }
   2830 
   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 
   2848 void LineWidthx(GLfixed width)
   2849 {
   2850 	LineWidth((float)width / 0x10000);
   2851 }
   2852 
   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 
   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 
   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 
   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 
   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 
   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 
   2999 void Materialx(GLenum face, GLenum pname, GLfixed param)
   3000 {
   3001 	UNIMPLEMENTED();
   3002 }
   3003 
   3004 void Materialxv(GLenum face, GLenum pname, const GLfixed *params)
   3005 {
   3006 	UNIMPLEMENTED();
   3007 }
   3008 
   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 
   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 
   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 
   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 
   3067 void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
   3068 {
   3069 	UNIMPLEMENTED();
   3070 }
   3071 
   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 
   3084 void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz)
   3085 {
   3086 	UNIMPLEMENTED();
   3087 }
   3088 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   3341 void PointSizex(GLfixed size)
   3342 {
   3343 	PointSize((float)size / 0x10000);
   3344 }
   3345 
   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 
   3358 void PolygonOffsetx(GLfixed factor, GLfixed units)
   3359 {
   3360 	PolygonOffset((float)factor / 0x10000, (float)units / 0x10000);
   3361 }
   3362 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   3498 void SampleCoveragex(GLclampx value, GLboolean invert)
   3499 {
   3500 	SampleCoverage((float)value / 0x10000, invert);
   3501 }
   3502 
   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 
   3515 void Scalex(GLfixed x, GLfixed y, GLfixed z)
   3516 {
   3517 	Scalef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
   3518 }
   3519 
   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 
   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 
   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 
   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 
   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 
   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 
   3672 void TexEnvf(GLenum target, GLenum pname, GLfloat param)
   3673 {
   3674 	TexEnvi(target, pname, (GLint)param);
   3675 }
   3676 
   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 
   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 
   4189 void TexEnvx(GLenum target, GLenum pname, GLfixed param)
   4190 {
   4191 	TexEnvi(target, pname, (GLint)param);
   4192 }
   4193 
   4194 void TexEnviv(GLenum target, GLenum pname, const GLint *params)
   4195 {
   4196 	UNIMPLEMENTED();
   4197 }
   4198 
   4199 void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
   4200 {
   4201 	UNIMPLEMENTED();
   4202 }
   4203 
   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 
   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 
   4394 void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
   4395 {
   4396 	TexParameterf(target, pname, *params);
   4397 }
   4398 
   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 
   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 
   4502 void TexParameterx(GLenum target, GLenum pname, GLfixed param)
   4503 {
   4504 	TexParameteri(target, pname, (GLint)param);
   4505 }
   4506 
   4507 void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
   4508 {
   4509 	UNIMPLEMENTED();
   4510 }
   4511 
   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 
   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 
   4579 void Translatex(GLfixed x, GLfixed y, GLfixed z)
   4580 {
   4581 	Translatef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
   4582 }
   4583 
   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 
   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 
   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 
   4655 void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
   4656 {
   4657 	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
   4658 
   4659 	UNIMPLEMENTED();
   4660 }
   4661 
   4662 void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
   4663 {
   4664 	UNIMPLEMENTED();
   4665 }
   4666 
   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 
   4684 void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
   4685 {
   4686 	UNIMPLEMENTED();
   4687 }
   4688 
   4689 void DrawTexsvOES(const GLshort *coords)
   4690 {
   4691 	UNIMPLEMENTED();
   4692 }
   4693 
   4694 void DrawTexivOES(const GLint *coords)
   4695 {
   4696 	UNIMPLEMENTED();
   4697 }
   4698 
   4699 void DrawTexxvOES(const GLfixed *coords)
   4700 {
   4701 	UNIMPLEMENTED();
   4702 }
   4703 
   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 
   4721 void DrawTexfvOES(const GLfloat *coords)
   4722 {
   4723 	UNIMPLEMENTED();
   4724 }
   4725 
   4726 }
   4727 
   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