// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// libGLES_CM.cpp: Implements the exported OpenGL ES 1.1 functions.

#include "main.h"
#include "mathutil.h"
#include "utilities.h"
#include "Buffer.h"
#include "Context.h"
#include "Framebuffer.h"
#include "Renderbuffer.h"
#include "Texture.h"
#include "common/debug.h"
#include "Common/SharedLibrary.hpp"
#include "Common/Version.h"

#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <GLES/gl.h>
#include <GLES/glext.h>

#include <algorithm>
#include <limits>

namespace es1
{

static bool validImageSize(GLint level, GLsizei width, GLsizei height)
{
	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
	{
		return false;
	}

	return true;
}

void ActiveTexture(GLenum texture)
{
	TRACE("(GLenum texture = 0x%X)", texture);

	es1::Context *context = es1::getContext();

	if(context)
	{
		if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es1::MAX_TEXTURE_UNITS - 1)
		{
			return error(GL_INVALID_ENUM);
		}

		context->setActiveSampler(texture - GL_TEXTURE0);
	}
}

void AlphaFunc(GLenum func, GLclampf ref)
{
	TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);

	switch(func)
	{
	case GL_NEVER:
	case GL_ALWAYS:
	case GL_LESS:
	case GL_LEQUAL:
	case GL_EQUAL:
	case GL_GEQUAL:
	case GL_GREATER:
	case GL_NOTEQUAL:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setAlphaFunc(func, clamp01(ref));
	}
}

void AlphaFuncx(GLenum func, GLclampx ref)
{
	AlphaFunc(func, (float)ref / 0x10000);
}

void BindBuffer(GLenum target, GLuint buffer)
{
	TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(target)
		{
		case GL_ARRAY_BUFFER:
			context->bindArrayBuffer(buffer);
			return;
		case GL_ELEMENT_ARRAY_BUFFER:
			context->bindElementArrayBuffer(buffer);
			return;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void BindFramebuffer(GLenum target, GLuint framebuffer)
{
	TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);

	if(target != GL_FRAMEBUFFER_OES)
	{
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->bindFramebuffer(framebuffer);
	}
}

void BindFramebufferOES(GLenum target, GLuint framebuffer)
{
	TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);

	if(target != GL_FRAMEBUFFER_OES)
	{
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->bindFramebuffer(framebuffer);
	}
}

void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
{
	TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);

	if(target != GL_RENDERBUFFER_OES)
	{
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		// [GL_EXT_framebuffer_object]
		// If <renderbuffer> is not zero, then the resulting renderbuffer object
		// is a new state vector, initialized with a zero-sized memory buffer
		context->bindRenderbuffer(renderbuffer);
	}
}

void BindTexture(GLenum target, GLuint texture)
{
	TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Texture *textureObject = context->getTexture(texture);

		if(textureObject && textureObject->getTarget() != target && texture != 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		switch(target)
		{
		case GL_TEXTURE_2D:
			context->bindTexture(TEXTURE_2D, texture);
			break;
		case GL_TEXTURE_EXTERNAL_OES:
			context->bindTexture(TEXTURE_EXTERNAL, texture);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);

void BlendEquationOES(GLenum mode)
{
	BlendEquationSeparateOES(mode, mode);
}

void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)
{
	TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);

	switch(modeRGB)
	{
	case GL_FUNC_ADD_OES:
	case GL_FUNC_SUBTRACT_OES:
	case GL_FUNC_REVERSE_SUBTRACT_OES:
	case GL_MIN_EXT:
	case GL_MAX_EXT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(modeAlpha)
	{
	case GL_FUNC_ADD_OES:
	case GL_FUNC_SUBTRACT_OES:
	case GL_FUNC_REVERSE_SUBTRACT_OES:
	case GL_MIN_EXT:
	case GL_MAX_EXT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setBlendEquation(modeRGB, modeAlpha);
	}
}

void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);

void BlendFunc(GLenum sfactor, GLenum dfactor)
{
	BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor);
}

void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
	TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
		  srcRGB, dstRGB, srcAlpha, dstAlpha);

	switch(srcRGB)
	{
	case GL_ZERO:
	case GL_ONE:
	case GL_SRC_COLOR:
	case GL_ONE_MINUS_SRC_COLOR:
	case GL_DST_COLOR:
	case GL_ONE_MINUS_DST_COLOR:
	case GL_SRC_ALPHA:
	case GL_ONE_MINUS_SRC_ALPHA:
	case GL_DST_ALPHA:
	case GL_ONE_MINUS_DST_ALPHA:
	case GL_SRC_ALPHA_SATURATE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(dstRGB)
	{
	case GL_ZERO:
	case GL_ONE:
	case GL_SRC_COLOR:
	case GL_ONE_MINUS_SRC_COLOR:
	case GL_DST_COLOR:
	case GL_ONE_MINUS_DST_COLOR:
	case GL_SRC_ALPHA:
	case GL_ONE_MINUS_SRC_ALPHA:
	case GL_DST_ALPHA:
	case GL_ONE_MINUS_DST_ALPHA:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(srcAlpha)
	{
	case GL_ZERO:
	case GL_ONE:
	case GL_SRC_COLOR:
	case GL_ONE_MINUS_SRC_COLOR:
	case GL_DST_COLOR:
	case GL_ONE_MINUS_DST_COLOR:
	case GL_SRC_ALPHA:
	case GL_ONE_MINUS_SRC_ALPHA:
	case GL_DST_ALPHA:
	case GL_ONE_MINUS_DST_ALPHA:
	case GL_SRC_ALPHA_SATURATE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(dstAlpha)
	{
	case GL_ZERO:
	case GL_ONE:
	case GL_SRC_COLOR:
	case GL_ONE_MINUS_SRC_COLOR:
	case GL_DST_COLOR:
	case GL_ONE_MINUS_DST_COLOR:
	case GL_SRC_ALPHA:
	case GL_ONE_MINUS_SRC_ALPHA:
	case GL_DST_ALPHA:
	case GL_ONE_MINUS_DST_ALPHA:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
	}
}

void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
{
	size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications

	TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
	      target, size, data, usage);

	if(size < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	switch(usage)
	{
	case GL_STATIC_DRAW:
	case GL_DYNAMIC_DRAW:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Buffer *buffer;

		switch(target)
		{
		case GL_ARRAY_BUFFER:
			buffer = context->getArrayBuffer();
			break;
		case GL_ELEMENT_ARRAY_BUFFER:
			buffer = context->getElementArrayBuffer();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(!buffer)
		{
			return error(GL_INVALID_OPERATION);
		}

		buffer->bufferData(data, size, usage);
	}
}

void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
{
	size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications
	offset = static_cast<GLint>(offset);

	TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
	      target, offset, size, data);

	if(size < 0 || offset < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(!data)
	{
		return;
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Buffer *buffer;

		switch(target)
		{
		case GL_ARRAY_BUFFER:
			buffer = context->getArrayBuffer();
			break;
		case GL_ELEMENT_ARRAY_BUFFER:
			buffer = context->getElementArrayBuffer();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(!buffer)
		{
			return error(GL_INVALID_OPERATION);
		}

		if((size_t)size + offset > buffer->size())
		{
			return error(GL_INVALID_VALUE);
		}

		buffer->bufferSubData(data, size, offset);
	}
}

GLenum CheckFramebufferStatusOES(GLenum target)
{
	TRACE("(GLenum target = 0x%X)", target);

	if(target != GL_FRAMEBUFFER_OES)
	{
		return error(GL_INVALID_ENUM, 0);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Framebuffer *framebuffer = context->getFramebuffer();

		if(!framebuffer)
		{
			return GL_FRAMEBUFFER_UNDEFINED_OES;
		}

		return framebuffer->completeness();
	}

	return 0;
}

void Clear(GLbitfield mask)
{
	TRACE("(GLbitfield mask = %X)", mask);

	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->clear(mask);
	}
}

void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
	      red, green, blue, alpha);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setClearColor(red, green, blue, alpha);
	}
}

void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
{
	ClearColor((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);
}

void ClearDepthf(GLclampf depth)
{
	TRACE("(GLclampf depth = %f)", depth);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setClearDepth(depth);
	}
}

void ClearDepthx(GLclampx depth)
{
	ClearDepthf((float)depth / 0x10000);
}

void ClearStencil(GLint s)
{
	TRACE("(GLint s = %d)", s);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setClearStencil(s);
	}
}

void ClientActiveTexture(GLenum texture)
{
	TRACE("(GLenum texture = 0x%X)", texture);

	switch(texture)
	{
	case GL_TEXTURE0:
	case GL_TEXTURE1:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->clientActiveTexture(texture);
	}
}

void ClipPlanef(GLenum plane, const GLfloat *equation)
{
	TRACE("(GLenum plane = 0x%X, const GLfloat *equation)", plane);

	int index = plane - GL_CLIP_PLANE0;

	if(index < 0 || index >= MAX_CLIP_PLANES)
	{
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setClipPlane(index, equation);
	}
}

void ClipPlanex(GLenum plane, const GLfixed *equation)
{
	GLfloat equationf[4] =
	{
		(float)equation[0] / 0x10000,
		(float)equation[1] / 0x10000,
		(float)equation[2] / 0x10000,
		(float)equation[3] / 0x10000,
	};

	ClipPlanef(plane, equationf);
}

void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
	TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
	}
}

void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
{
	Color4f((float)red / 0xFF, (float)green / 0xFF, (float)blue / 0xFF, (float)alpha / 0xFF);
}

void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
{
	Color4f((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);
}

void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
{
	TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
	      red, green, blue, alpha);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setColorMask(red != GL_FALSE, green != GL_FALSE, blue != GL_FALSE, alpha != GL_FALSE);
	}
}

void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
{
	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
	      index, size, type, normalized, stride, ptr);

	if(index >= es1::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	if(size < 1 || size > 4)
	{
		return error(GL_INVALID_VALUE);
	}

	switch(type)
	{
	case GL_BYTE:
	case GL_UNSIGNED_BYTE:
	case GL_SHORT:
	case GL_UNSIGNED_SHORT:
	case GL_FIXED:
	case GL_FLOAT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(stride < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized != GL_FALSE), stride, ptr);
	}
}

void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);

	if(size != 4)
	{
		return error(GL_INVALID_VALUE);
	}

	VertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
}

void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
                          GLint border, GLsizei imageSize, const GLvoid* data)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
	      "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
	      target, level, internalformat, width, height, border, imageSize, data);

	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
	{
		return error(GL_INVALID_VALUE);
	}

	if(!validImageSize(level, width, height) || imageSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	switch(internalformat)
	{
	case GL_ETC1_RGB8_OES:
	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
		break;
	case GL_DEPTH_COMPONENT16_OES:
	case GL_DEPTH_STENCIL_OES:
	case GL_DEPTH24_STENCIL8_OES:
		return error(GL_INVALID_OPERATION);
	default:
		return error(GL_INVALID_ENUM);
	}

	if(border != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(target)
		{
		case GL_TEXTURE_2D:
			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(imageSize != gl::ComputeCompressedSize(width, height, internalformat))
		{
			return error(GL_INVALID_VALUE);
		}

		if(target == GL_TEXTURE_2D)
		{
			es1::Texture2D *texture = context->getTexture2D();

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
		}
		else UNREACHABLE(target);
	}
}

void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                             GLenum format, GLsizei imageSize, const GLvoid* data)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
	      "GLsizei imageSize = %d, const GLvoid* data = %p)",
	      target, level, xoffset, yoffset, width, height, format, imageSize, data);

	if(!es1::IsTextureTarget(target))
	{
		return error(GL_INVALID_ENUM);
	}

	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
	{
		return error(GL_INVALID_VALUE);
	}

	if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	switch(format)
	{
	case GL_ETC1_RGB8_OES:
	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(width == 0 || height == 0 || !data)
	{
		return;
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		if(imageSize != gl::ComputeCompressedSize(width, height, format))
		{
			return error(GL_INVALID_VALUE);
		}

		if(xoffset % 4 != 0 || yoffset % 4 != 0)
		{
			// We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
			return error(GL_INVALID_OPERATION);
		}

		if(target == GL_TEXTURE_2D)
		{
			es1::Texture2D *texture = context->getTexture2D();

			GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE_OES, texture);
			if(validationError != GL_NO_ERROR)
			{
				return error(validationError);
			}

			texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
		}
		else UNREACHABLE(target);
	}
}

void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
	      target, level, internalformat, x, y, width, height, border);

	if(!validImageSize(level, width, height))
	{
		return error(GL_INVALID_VALUE);
	}

	if(border != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(target)
		{
		case GL_TEXTURE_2D:
			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		es1::Framebuffer *framebuffer = context->getFramebuffer();

		if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES))
		{
			return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
		}

		es1::Renderbuffer *source = framebuffer->getColorbuffer();

		if(!source || source->getSamples() > 1)
		{
			return error(GL_INVALID_OPERATION);
		}

		GLenum colorbufferFormat = source->getFormat();

		// [OpenGL ES 1.1.12] table 3.9
		switch(internalformat)
		{
		case GL_ALPHA:
			if(colorbufferFormat != GL_ALPHA &&
			   colorbufferFormat != GL_RGBA &&
			   colorbufferFormat != GL_RGBA4_OES &&
			   colorbufferFormat != GL_RGB5_A1_OES &&
			   colorbufferFormat != GL_RGBA8_OES)
			{
				return error(GL_INVALID_OPERATION);
			}
			break;
		case GL_LUMINANCE:
		case GL_RGB:
			if(colorbufferFormat != GL_RGB &&
			   colorbufferFormat != GL_RGB565_OES &&
			   colorbufferFormat != GL_RGB8_OES &&
			   colorbufferFormat != GL_RGBA &&
			   colorbufferFormat != GL_RGBA4_OES &&
			   colorbufferFormat != GL_RGB5_A1_OES &&
			   colorbufferFormat != GL_RGBA8_OES)
			{
				return error(GL_INVALID_OPERATION);
			}
			break;
		case GL_LUMINANCE_ALPHA:
		case GL_RGBA:
			if(colorbufferFormat != GL_RGBA &&
			   colorbufferFormat != GL_RGBA4_OES &&
			   colorbufferFormat != GL_RGB5_A1_OES &&
			   colorbufferFormat != GL_RGBA8_OES &&
			   colorbufferFormat != GL_BGRA_EXT &&  // GL_EXT_texture_format_BGRA8888
			   colorbufferFormat != GL_BGRA8_EXT)   // GL_EXT_texture_format_BGRA8888
			{
				return error(GL_INVALID_OPERATION);
			}
			break;
		case GL_ETC1_RGB8_OES:
		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
			return error(GL_INVALID_OPERATION);
		case GL_BGRA_EXT:   // GL_EXT_texture_format_BGRA8888 doesn't mention the format to be accepted by glCopyTexImage2D.
		default:
			return error(GL_INVALID_ENUM);
		}

		// Determine the sized internal format.
		if(gl::GetBaseInternalFormat(colorbufferFormat) == internalformat)
		{
			internalformat = colorbufferFormat;
		}
		else if(GetRedSize(colorbufferFormat) <= 8)
		{
			internalformat = gl::GetSizedInternalFormat(internalformat, GL_UNSIGNED_BYTE);
		}
		else
		{
			UNIMPLEMENTED();

			return error(GL_INVALID_OPERATION);
		}

		if(target == GL_TEXTURE_2D)
		{
			es1::Texture2D *texture = context->getTexture2D();

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
		}
		else UNREACHABLE(target);
	}
}

void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
	      target, level, xoffset, yoffset, x, y, width, height);

	if(!es1::IsTextureTarget(target))
	{
		return error(GL_INVALID_ENUM);
	}

	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
	{
		return error(GL_INVALID_VALUE);
	}

	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
	{
		return error(GL_INVALID_VALUE);
	}

	if(width == 0 || height == 0)
	{
		return;
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Framebuffer *framebuffer = context->getFramebuffer();

		if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES))
		{
			return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
		}

		es1::Renderbuffer *source = framebuffer->getColorbuffer();

		if(context->getFramebufferName() != 0 && (!source || source->getSamples() > 1))
		{
			return error(GL_INVALID_OPERATION);
		}

		es1::Texture *texture = nullptr;

		if(target == GL_TEXTURE_2D)
		{
			texture = context->getTexture2D();
		}
		else UNREACHABLE(target);

		GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, width, height, GL_NONE_OES, GL_NONE_OES, texture);
		if(validationError != GL_NO_ERROR)
		{
			return error(validationError);
		}

		texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
	}
}

void CullFace(GLenum mode)
{
	TRACE("(GLenum mode = 0x%X)", mode);

	switch(mode)
	{
	case GL_FRONT:
	case GL_BACK:
	case GL_FRONT_AND_BACK:
		{
			es1::Context *context = es1::getContext();

			if(context)
			{
				context->setCullMode(mode);
			}
		}
		break;
	default:
		return error(GL_INVALID_ENUM);
	}
}

void DeleteBuffers(GLsizei n, const GLuint* buffers)
{
	TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			context->deleteBuffer(buffers[i]);
		}
	}
}

void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
{
	TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			if(framebuffers[i] != 0)
			{
				context->deleteFramebuffer(framebuffers[i]);
			}
		}
	}
}

void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
{
	TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			context->deleteRenderbuffer(renderbuffers[i]);
		}
	}
}

void DeleteTextures(GLsizei n, const GLuint* textures)
{
	TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			if(textures[i] != 0)
			{
				context->deleteTexture(textures[i]);
			}
		}
	}
}

void DepthFunc(GLenum func)
{
	TRACE("(GLenum func = 0x%X)", func);

	switch(func)
	{
	case GL_NEVER:
	case GL_ALWAYS:
	case GL_LESS:
	case GL_LEQUAL:
	case GL_EQUAL:
	case GL_GREATER:
	case GL_GEQUAL:
	case GL_NOTEQUAL:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setDepthFunc(func);
	}
}

void DepthMask(GLboolean flag)
{
	TRACE("(GLboolean flag = %d)", flag);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setDepthMask(flag != GL_FALSE);
	}
}

void DepthRangef(GLclampf zNear, GLclampf zFar)
{
	TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setDepthRange(zNear, zFar);
	}
}

void DepthRangex(GLclampx zNear, GLclampx zFar)
{
	DepthRangef((float)zNear / 0x10000, (float)zFar / 0x10000);
}

void Disable(GLenum cap)
{
	TRACE("(GLenum cap = 0x%X)", cap);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(cap)
		{
		case GL_CULL_FACE:                context->setCullFaceEnabled(false);              break;
		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFillEnabled(false);     break;
		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break;
		case GL_SAMPLE_COVERAGE:          context->setSampleCoverageEnabled(false);        break;
		case GL_SCISSOR_TEST:             context->setScissorTestEnabled(false);           break;
		case GL_STENCIL_TEST:             context->setStencilTestEnabled(false);           break;
		case GL_DEPTH_TEST:               context->setDepthTestEnabled(false);             break;
		case GL_BLEND:                    context->setBlendEnabled(false);                 break;
		case GL_DITHER:                   context->setDitherEnabled(false);                break;
		case GL_LIGHTING:                 context->setLightingEnabled(false);              break;
		case GL_LIGHT0:                   context->setLightEnabled(0, false);              break;
		case GL_LIGHT1:                   context->setLightEnabled(1, false);              break;
		case GL_LIGHT2:                   context->setLightEnabled(2, false);              break;
		case GL_LIGHT3:                   context->setLightEnabled(3, false);              break;
		case GL_LIGHT4:                   context->setLightEnabled(4, false);              break;
		case GL_LIGHT5:                   context->setLightEnabled(5, false);              break;
		case GL_LIGHT6:                   context->setLightEnabled(6, false);              break;
		case GL_LIGHT7:                   context->setLightEnabled(7, false);              break;
		case GL_FOG:                      context->setFogEnabled(false);                   break;
		case GL_TEXTURE_2D:               context->setTexture2Denabled(false);             break;
		case GL_TEXTURE_EXTERNAL_OES:     context->setTextureExternalEnabled(false);       break;
		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(false);             break;
		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(false);          break;
		case GL_POINT_SMOOTH:             context->setPointSmoothEnabled(false);           break;
		case GL_LINE_SMOOTH:              context->setLineSmoothEnabled(false);            break;
		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(false);         break;
		case GL_NORMALIZE:                context->setNormalizeEnabled(false);             break;
		case GL_RESCALE_NORMAL:           context->setRescaleNormalEnabled(false);         break;
		case GL_VERTEX_ARRAY:             context->setVertexArrayEnabled(false);           break;
		case GL_NORMAL_ARRAY:             context->setNormalArrayEnabled(false);           break;
		case GL_COLOR_ARRAY:              context->setColorArrayEnabled(false);            break;
		case GL_POINT_SIZE_ARRAY_OES:     context->setPointSizeArrayEnabled(false);        break;
		case GL_TEXTURE_COORD_ARRAY:      context->setTextureCoordArrayEnabled(false);     break;
		case GL_MULTISAMPLE:              context->setMultisampleEnabled(false);           break;
		case GL_SAMPLE_ALPHA_TO_ONE:      context->setSampleAlphaToOneEnabled(false);      break;
		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, false);          break;
		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, false);          break;
		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, false);          break;
		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, false);          break;
		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, false);          break;
		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, false);          break;
		case GL_POINT_SPRITE_OES:         context->setPointSpriteEnabled(false);           break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void DisableClientState(GLenum array)
{
	TRACE("(GLenum array = 0x%X)", array);

	switch(array)
	{
	case GL_VERTEX_ARRAY:
	case GL_NORMAL_ARRAY:
	case GL_COLOR_ARRAY:
	case GL_POINT_SIZE_ARRAY_OES:
	case GL_TEXTURE_COORD_ARRAY:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		GLenum texture = context->getClientActiveTexture();

		switch(array)
		{
		case GL_VERTEX_ARRAY:         context->setVertexAttribArrayEnabled(sw::Position, false);                            break;
		case GL_NORMAL_ARRAY:         context->setVertexAttribArrayEnabled(sw::Normal, false);                              break;
		case GL_COLOR_ARRAY:          context->setVertexAttribArrayEnabled(sw::Color0, false);                              break;
		case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, false);                           break;
		case GL_TEXTURE_COORD_ARRAY:  context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
		default:                      UNREACHABLE(array);
		}
	}
}

void DrawArrays(GLenum mode, GLint first, GLsizei count)
{
	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);

	if(count < 0 || first < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->drawArrays(mode, first, count);
	}
}

void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
{
	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
	      mode, count, type, indices);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(type)
		{
		case GL_UNSIGNED_BYTE:
		case GL_UNSIGNED_SHORT:
		case GL_UNSIGNED_INT:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		context->drawElements(mode, count, type, indices);
	}
}

void Enable(GLenum cap)
{
	TRACE("(GLenum cap = 0x%X)", cap);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(cap)
		{
		case GL_CULL_FACE:                context->setCullFaceEnabled(true);              break;
		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFillEnabled(true);     break;
		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break;
		case GL_SAMPLE_COVERAGE:          context->setSampleCoverageEnabled(true);        break;
		case GL_SCISSOR_TEST:             context->setScissorTestEnabled(true);           break;
		case GL_STENCIL_TEST:             context->setStencilTestEnabled(true);           break;
		case GL_DEPTH_TEST:               context->setDepthTestEnabled(true);             break;
		case GL_BLEND:                    context->setBlendEnabled(true);                 break;
		case GL_DITHER:                   context->setDitherEnabled(true);                break;
		case GL_LIGHTING:                 context->setLightingEnabled(true);              break;
		case GL_LIGHT0:                   context->setLightEnabled(0, true);              break;
		case GL_LIGHT1:                   context->setLightEnabled(1, true);              break;
		case GL_LIGHT2:                   context->setLightEnabled(2, true);              break;
		case GL_LIGHT3:                   context->setLightEnabled(3, true);              break;
		case GL_LIGHT4:                   context->setLightEnabled(4, true);              break;
		case GL_LIGHT5:                   context->setLightEnabled(5, true);              break;
		case GL_LIGHT6:                   context->setLightEnabled(6, true);              break;
		case GL_LIGHT7:                   context->setLightEnabled(7, true);              break;
		case GL_FOG:                      context->setFogEnabled(true);                   break;
		case GL_TEXTURE_2D:               context->setTexture2Denabled(true);             break;
		case GL_TEXTURE_EXTERNAL_OES:     context->setTextureExternalEnabled(true);       break;
		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(true);             break;
		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(true);          break;
		case GL_POINT_SMOOTH:             context->setPointSmoothEnabled(true);           break;
		case GL_LINE_SMOOTH:              context->setLineSmoothEnabled(true);            break;
		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(true);         break;
		case GL_NORMALIZE:                context->setNormalizeEnabled(true);             break;
		case GL_RESCALE_NORMAL:           context->setRescaleNormalEnabled(true);         break;
		case GL_VERTEX_ARRAY:             context->setVertexArrayEnabled(true);           break;
		case GL_NORMAL_ARRAY:             context->setNormalArrayEnabled(true);           break;
		case GL_COLOR_ARRAY:              context->setColorArrayEnabled(true);            break;
		case GL_POINT_SIZE_ARRAY_OES:     context->setPointSizeArrayEnabled(true);        break;
		case GL_TEXTURE_COORD_ARRAY:      context->setTextureCoordArrayEnabled(true);     break;
		case GL_MULTISAMPLE:              context->setMultisampleEnabled(true);           break;
		case GL_SAMPLE_ALPHA_TO_ONE:      context->setSampleAlphaToOneEnabled(true);      break;
		case GL_CLIP_PLANE0:              context->setClipPlaneEnabled(0, true);          break;
		case GL_CLIP_PLANE1:              context->setClipPlaneEnabled(1, true);          break;
		case GL_CLIP_PLANE2:              context->setClipPlaneEnabled(2, true);          break;
		case GL_CLIP_PLANE3:              context->setClipPlaneEnabled(3, true);          break;
		case GL_CLIP_PLANE4:              context->setClipPlaneEnabled(4, true);          break;
		case GL_CLIP_PLANE5:              context->setClipPlaneEnabled(5, true);          break;
		case GL_POINT_SPRITE_OES:         context->setPointSpriteEnabled(true);           break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void EnableClientState(GLenum array)
{
	TRACE("(GLenum array = 0x%X)", array);

	switch(array)
	{
	case GL_VERTEX_ARRAY:
	case GL_NORMAL_ARRAY:
	case GL_COLOR_ARRAY:
	case GL_POINT_SIZE_ARRAY_OES:
	case GL_TEXTURE_COORD_ARRAY:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		GLenum texture = context->getClientActiveTexture();

		switch(array)
		{
		case GL_VERTEX_ARRAY:         context->setVertexAttribArrayEnabled(sw::Position, true);                            break;
		case GL_NORMAL_ARRAY:         context->setVertexAttribArrayEnabled(sw::Normal, true);                              break;
		case GL_COLOR_ARRAY:          context->setVertexAttribArrayEnabled(sw::Color0, true);                              break;
		case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, true);                           break;
		case GL_TEXTURE_COORD_ARRAY:  context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
		default:                      UNREACHABLE(array);
		}
	}
}

void Finish(void)
{
	TRACE("()");

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->finish();
	}
}

void Flush(void)
{
	TRACE("()");

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->flush();
	}
}

void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
	      "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);

	if(target != GL_FRAMEBUFFER_OES || (renderbuffertarget != GL_RENDERBUFFER_OES && renderbuffer != 0))
	{
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Framebuffer *framebuffer = context->getFramebuffer();
		GLuint framebufferName = context->getFramebufferName();

		if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
		{
			return error(GL_INVALID_OPERATION);
		}

		switch(attachment)
		{
		case GL_COLOR_ATTACHMENT0_OES:
			framebuffer->setColorbuffer(GL_RENDERBUFFER_OES, renderbuffer);
			break;
		case GL_DEPTH_ATTACHMENT_OES:
			framebuffer->setDepthbuffer(GL_RENDERBUFFER_OES, renderbuffer);
			break;
		case GL_STENCIL_ATTACHMENT_OES:
			framebuffer->setStencilbuffer(GL_RENDERBUFFER_OES, renderbuffer);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
	      "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);

	if(target != GL_FRAMEBUFFER_OES)
	{
		return error(GL_INVALID_ENUM);
	}

	switch(attachment)
	{
	case GL_COLOR_ATTACHMENT0_OES:
	case GL_DEPTH_ATTACHMENT_OES:
	case GL_STENCIL_ATTACHMENT_OES:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		if(texture == 0)
		{
			textarget = GL_NONE_OES;
		}
		else
		{
			es1::Texture *tex = context->getTexture(texture);

			if(!tex)
			{
				return error(GL_INVALID_OPERATION);
			}

			switch(textarget)
			{
			case GL_TEXTURE_2D:
				if(tex->getTarget() != GL_TEXTURE_2D)
				{
					return error(GL_INVALID_OPERATION);
				}
				break;
			default:
				return error(GL_INVALID_ENUM);
			}

			if((level < 0) || (level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
			{
				return error(GL_INVALID_VALUE);
			}

			if(tex->isCompressed(textarget, level))
			{
				return error(GL_INVALID_OPERATION);
			}
		}

		es1::Framebuffer *framebuffer = context->getFramebuffer();
		GLuint framebufferName = context->getFramebufferName();

		if(framebufferName == 0 || !framebuffer)
		{
			return error(GL_INVALID_OPERATION);
		}

		switch(attachment)
		{
		case GL_COLOR_ATTACHMENT0_OES:  framebuffer->setColorbuffer(textarget, texture, level);   break;
		case GL_DEPTH_ATTACHMENT_OES:   framebuffer->setDepthbuffer(textarget, texture, level);   break;
		case GL_STENCIL_ATTACHMENT_OES: framebuffer->setStencilbuffer(textarget, texture, level); break;
		}
	}
}

void Fogf(GLenum pname, GLfloat param)
{
	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_FOG_MODE:
			switch((GLenum)param)
			{
			case GL_LINEAR:
			case GL_EXP:
			case GL_EXP2:
				context->setFogMode((GLenum)param);
				break;
			default:
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_FOG_DENSITY:
			if(param < 0)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setFogDensity(param);
			break;
		case GL_FOG_START:
			context->setFogStart(param);
			break;
		case GL_FOG_END:
			context->setFogEnd(param);
			break;
		case GL_FOG_COLOR:
			return error(GL_INVALID_ENUM);   // Need four values, should call glFogfv() instead
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void Fogfv(GLenum pname, const GLfloat *params)
{
	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_FOG_MODE:
			switch((GLenum)params[0])
			{
			case GL_LINEAR:
			case GL_EXP:
			case GL_EXP2:
				context->setFogMode((GLenum)params[0]);
				break;
			default:
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_FOG_DENSITY:
			if(params[0] < 0)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setFogDensity(params[0]);
			break;
		case GL_FOG_START:
			context->setFogStart(params[0]);
			break;
		case GL_FOG_END:
			context->setFogEnd(params[0]);
			break;
		case GL_FOG_COLOR:
			context->setFogColor(params[0], params[1], params[2], params[3]);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void Fogx(GLenum pname, GLfixed param)
{
	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_FOG_MODE:
			switch((GLenum)param)
			{
			case GL_LINEAR:
			case GL_EXP:
			case GL_EXP2:
				context->setFogMode((GLenum)param);
				break;
			default:
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_FOG_DENSITY:
			if(param < 0)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setFogDensity((float)param / 0x10000);
			break;
		case GL_FOG_START:
			context->setFogStart((float)param / 0x10000);
			break;
		case GL_FOG_END:
			context->setFogEnd((float)param / 0x10000);
			break;
		case GL_FOG_COLOR:
			return error(GL_INVALID_ENUM);   // Need four values, should call glFogxv() instead
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void Fogxv(GLenum pname, const GLfixed *params)
{
	UNIMPLEMENTED();
}

void FrontFace(GLenum mode)
{
	TRACE("(GLenum mode = 0x%X)", mode);

	switch(mode)
	{
	case GL_CW:
	case GL_CCW:
		{
			es1::Context *context = es1::getContext();

			if(context)
			{
				context->setFrontFace(mode);
			}
		}
		break;
	default:
		return error(GL_INVALID_ENUM);
	}
}

void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
{
	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);

	if(zNear <= 0.0f || zFar <= 0.0f || left == right || bottom == top || zNear == zFar)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->frustum(left, right, bottom, top, zNear, zFar);
	}
}

void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
{
	Frustumf((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);
}

void GenerateMipmapOES(GLenum target)
{
	TRACE("(GLenum target = 0x%X)", target);

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
		{
			return error(GL_INVALID_OPERATION);
		}

		texture->generateMipmaps();
	}
}

void GenBuffers(GLsizei n, GLuint* buffers)
{
	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			buffers[i] = context->createBuffer();
		}
	}
}

void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
{
	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			framebuffers[i] = context->createFramebuffer();
		}
	}
}

void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
{
	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			renderbuffers[i] = context->createRenderbuffer();
		}
	}
}

void GenTextures(GLsizei n, GLuint* textures)
{
	TRACE("(GLsizei n = %d, GLuint* textures =  %p)", n, textures);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			textures[i] = context->createTexture();
		}
	}
}

void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);

	es1::Context *context = es1::getContext();

	if(context)
	{
		if(target != GL_RENDERBUFFER_OES)
		{
			return error(GL_INVALID_ENUM);
		}

		if(context->getRenderbufferName() == 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		es1::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());

		switch(pname)
		{
		case GL_RENDERBUFFER_WIDTH_OES:           *params = renderbuffer->getWidth();       break;
		case GL_RENDERBUFFER_HEIGHT_OES:          *params = renderbuffer->getHeight();      break;
		case GL_RENDERBUFFER_INTERNAL_FORMAT_OES:
			{
				GLint internalformat = renderbuffer->getFormat();
				*params = (internalformat == GL_NONE_OES) ? GL_RGBA4_OES : internalformat;
			}
			break;
		case GL_RENDERBUFFER_RED_SIZE_OES:        *params = renderbuffer->getRedSize();     break;
		case GL_RENDERBUFFER_GREEN_SIZE_OES:      *params = renderbuffer->getGreenSize();   break;
		case GL_RENDERBUFFER_BLUE_SIZE_OES:       *params = renderbuffer->getBlueSize();    break;
		case GL_RENDERBUFFER_ALPHA_SIZE_OES:      *params = renderbuffer->getAlphaSize();   break;
		case GL_RENDERBUFFER_DEPTH_SIZE_OES:      *params = renderbuffer->getDepthSize();   break;
		case GL_RENDERBUFFER_STENCIL_SIZE_OES:    *params = renderbuffer->getStencilSize(); break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void GetBooleanv(GLenum pname, GLboolean* params)
{
	TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)",  pname, params);

	es1::Context *context = es1::getContext();

	if(context)
	{
		if(!(context->getBooleanv(pname, params)))
		{
			int numParams = context->getQueryParameterNum(pname);

			if(numParams < 0)
			{
				return error(GL_INVALID_ENUM);
			}

			if(numParams == 0)
			{
				return;
			}

			if(context->isQueryParameterFloat(pname))
			{
				GLfloat *floatParams = nullptr;
				floatParams = new GLfloat[numParams];

				context->getFloatv(pname, floatParams);

				for(int i = 0; i < numParams; ++i)
				{
					if(floatParams[i] == 0.0f)
						params[i] = GL_FALSE;
					else
						params[i] = GL_TRUE;
				}

				delete [] floatParams;
			}
			else if(context->isQueryParameterInt(pname))
			{
				GLint *intParams = nullptr;
				intParams = new GLint[numParams];

				context->getIntegerv(pname, intParams);

				for(int i = 0; i < numParams; ++i)
				{
					if(intParams[i] == 0)
						params[i] = GL_FALSE;
					else
						params[i] = GL_TRUE;
				}

				delete [] intParams;
			}
			else UNREACHABLE(pname);
		}
	}
}

void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Buffer *buffer;

		switch(target)
		{
		case GL_ARRAY_BUFFER:
			buffer = context->getArrayBuffer();
			break;
		case GL_ELEMENT_ARRAY_BUFFER:
			buffer = context->getElementArrayBuffer();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(!buffer)
		{
			// A null buffer means that "0" is bound to the requested buffer target
			return error(GL_INVALID_OPERATION);
		}

		switch(pname)
		{
		case GL_BUFFER_USAGE:
			*params = buffer->usage();
			break;
		case GL_BUFFER_SIZE:
			*params = (GLint)buffer->size();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void GetClipPlanef(GLenum pname, GLfloat eqn[4])
{
	UNIMPLEMENTED();
}

void GetClipPlanex(GLenum pname, GLfixed eqn[4])
{
	UNIMPLEMENTED();
}

GLenum GetError(void)
{
	TRACE("()");

	es1::Context *context = es1::getContext();

	if(context)
	{
		return context->getError();
	}

	return GL_NO_ERROR;
}

void GetFixedv(GLenum pname, GLfixed *params)
{
	UNIMPLEMENTED();
}

void GetFloatv(GLenum pname, GLfloat* params)
{
	TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);

	es1::Context *context = es1::getContext();

	if(context)
	{
		if(!(context->getFloatv(pname, params)))
		{
			int numParams = context->getQueryParameterNum(pname);

			if(numParams < 0)
			{
				return error(GL_INVALID_ENUM);
			}

			if(numParams == 0)
			{
				return;
			}

			if(context->isQueryParameterBool(pname))
			{
				GLboolean *boolParams = nullptr;
				boolParams = new GLboolean[numParams];

				context->getBooleanv(pname, boolParams);

				for(int i = 0; i < numParams; ++i)
				{
					if(boolParams[i] == GL_FALSE)
						params[i] = 0.0f;
					else
						params[i] = 1.0f;
				}

				delete [] boolParams;
			}
			else if(context->isQueryParameterInt(pname))
			{
				GLint *intParams = nullptr;
				intParams = new GLint[numParams];

				context->getIntegerv(pname, intParams);

				for(int i = 0; i < numParams; ++i)
				{
					params[i] = (GLfloat)intParams[i];
				}

				delete [] intParams;
			}
			else UNREACHABLE(pname);
		}
	}
}

void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
	      target, attachment, pname, params);

	es1::Context *context = es1::getContext();

	if(context)
	{
		if(target != GL_FRAMEBUFFER_OES)
		{
			return error(GL_INVALID_ENUM);
		}

		if(context->getFramebufferName() == 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		es1::Framebuffer *framebuffer = context->getFramebuffer();

		if(!framebuffer)
		{
			return error(GL_INVALID_OPERATION);
		}

		GLenum attachmentType;
		GLuint attachmentHandle;
		Renderbuffer *renderbuffer = nullptr;
		switch(attachment)
		{
		case GL_COLOR_ATTACHMENT0_OES:
			attachmentType = framebuffer->getColorbufferType();
			attachmentHandle = framebuffer->getColorbufferName();
			renderbuffer = framebuffer->getColorbuffer();
			break;
		case GL_DEPTH_ATTACHMENT_OES:
			attachmentType = framebuffer->getDepthbufferType();
			attachmentHandle = framebuffer->getDepthbufferName();
			renderbuffer = framebuffer->getDepthbuffer();
			break;
		case GL_STENCIL_ATTACHMENT_OES:
			attachmentType = framebuffer->getStencilbufferType();
			attachmentHandle = framebuffer->getStencilbufferName();
			renderbuffer = framebuffer->getStencilbuffer();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		GLenum attachmentObjectType;   // Type category
		if(attachmentType == GL_NONE_OES || attachmentType == GL_RENDERBUFFER_OES)
		{
			attachmentObjectType = attachmentType;
		}
		else if(es1::IsTextureTarget(attachmentType))
		{
			attachmentObjectType = GL_TEXTURE;
		}
		else UNREACHABLE(attachmentType);

		switch(pname)
		{
		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES:
			*params = attachmentObjectType;
			break;
		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES:
			if(attachmentObjectType == GL_RENDERBUFFER_OES || attachmentObjectType == GL_TEXTURE)
			{
				*params = attachmentHandle;
			}
			else
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES:
			if(attachmentObjectType == GL_TEXTURE)
			{
				*params = renderbuffer->getLevel();
			}
			else
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void GetIntegerv(GLenum pname, GLint* params)
{
	TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);

	es1::Context *context = es1::getContext();

	if(context)
	{
		if(!(context->getIntegerv(pname, params)))
		{
			int numParams = context->getQueryParameterNum(pname);

			if(numParams < 0)
			{
				return error(GL_INVALID_ENUM);
			}

			if(numParams == 0)
			{
				return;
			}

			if(context->isQueryParameterBool(pname))
			{
				GLboolean *boolParams = nullptr;
				boolParams = new GLboolean[numParams];

				context->getBooleanv(pname, boolParams);

				for(int i = 0; i < numParams; ++i)
				{
					if(boolParams[i] == GL_FALSE)
						params[i] = 0;
					else
						params[i] = 1;
				}

				delete [] boolParams;
			}
			else if(context->isQueryParameterFloat(pname))
			{
				GLfloat *floatParams = nullptr;
				floatParams = new GLfloat[numParams];

				context->getFloatv(pname, floatParams);

				for(int i = 0; i < numParams; ++i)
				{
					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
					{
						params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
					}
					else
					{
						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
					}
				}

				delete [] floatParams;
			}
			else UNREACHABLE(pname);
		}
	}
}

void GetLightfv(GLenum light, GLenum pname, GLfloat *params)
{
	UNIMPLEMENTED();
}

void GetLightxv(GLenum light, GLenum pname, GLfixed *params)
{
	UNIMPLEMENTED();
}

void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
{
	UNIMPLEMENTED();
}

void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
{
	UNIMPLEMENTED();
}

void GetPointerv(GLenum pname, GLvoid **params)
{
	TRACE("(GLenum pname = 0x%X, GLvoid **params = %p)", pname, params);

	es1::Context *context = es1::getContext();

	if(context)
	{
		if(!(context->getPointerv(pname, const_cast<const GLvoid**>(params))))
		{
			return error(GL_INVALID_ENUM);
		}
	}
}

const GLubyte* GetString(GLenum name)
{
	TRACE("(GLenum name = 0x%X)", name);

	switch(name)
	{
	case GL_VENDOR:
		return (GLubyte*)"Google Inc.";
	case GL_RENDERER:
		return (GLubyte*)"Google SwiftShader " VERSION_STRING;
	case GL_VERSION:
		return (GLubyte*)"OpenGL ES-CM 1.1";
	case GL_EXTENSIONS:
		// Keep list sorted in following order:
		// OES extensions
		// EXT extensions
		// Vendor extensions
		return (GLubyte*)
			"GL_OES_blend_equation_separate "
			"GL_OES_blend_func_separate "
			"GL_OES_blend_subtract "
			"GL_OES_compressed_ETC1_RGB8_texture "
			"GL_OES_EGL_image "
			"GL_OES_EGL_image_external "
			"GL_OES_EGL_sync "
			"GL_OES_element_index_uint "
			"GL_OES_fbo_render_mipmap "
			"GL_OES_framebuffer_object "
			"GL_OES_packed_depth_stencil "
			"GL_OES_read_format "
			"GL_OES_rgb8_rgba8 "
			"GL_OES_stencil8 "
			"GL_OES_stencil_wrap "
			"GL_OES_surfaceless_context "
			"GL_OES_texture_mirrored_repeat "
			"GL_OES_texture_npot "
			"GL_EXT_blend_minmax "
			"GL_EXT_read_format_bgra "
			"GL_EXT_texture_compression_dxt1 "
			"GL_ANGLE_texture_compression_dxt3 "
			"GL_ANGLE_texture_compression_dxt5 "
			"GL_EXT_texture_filter_anisotropic "
			"GL_EXT_texture_format_BGRA8888";
	default:
		return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
	}
}

void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D();
			break;
		case GL_TEXTURE_EXTERNAL_OES:
			texture = context->getTextureExternal();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_MAG_FILTER:
			*params = (GLfloat)texture->getMagFilter();
			break;
		case GL_TEXTURE_MIN_FILTER:
			*params = (GLfloat)texture->getMinFilter();
			break;
		case GL_TEXTURE_WRAP_S:
			*params = (GLfloat)texture->getWrapS();
			break;
		case GL_TEXTURE_WRAP_T:
			*params = (GLfloat)texture->getWrapT();
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			*params = texture->getMaxAnisotropy();
			break;
		case GL_GENERATE_MIPMAP:
			*params = (GLfloat)texture->getGenerateMipmap();
			break;
		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
			*params = (GLfloat)1;
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D();
			break;
		case GL_TEXTURE_EXTERNAL_OES:
			texture = context->getTextureExternal();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_MAG_FILTER:
			*params = texture->getMagFilter();
			break;
		case GL_TEXTURE_MIN_FILTER:
			*params = texture->getMinFilter();
			break;
		case GL_TEXTURE_WRAP_S:
			*params = texture->getWrapS();
			break;
		case GL_TEXTURE_WRAP_T:
			*params = texture->getWrapT();
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			*params = (GLint)texture->getMaxAnisotropy();
			break;
		case GL_GENERATE_MIPMAP:
			*params = (GLint)texture->getGenerateMipmap();
			break;
		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
			*params = 1;
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
{
	UNIMPLEMENTED();
}

void GetTexEnviv(GLenum env, GLenum pname, GLint *params)
{
	UNIMPLEMENTED();
}

void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
{
	UNIMPLEMENTED();
}

void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
{
	UNIMPLEMENTED();
}

void Hint(GLenum target, GLenum mode)
{
	TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);

	switch(mode)
	{
	case GL_FASTEST:
	case GL_NICEST:
	case GL_DONT_CARE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(target)
		{
		case GL_GENERATE_MIPMAP_HINT:
			context->setGenerateMipmapHint(mode);
			break;
		case GL_PERSPECTIVE_CORRECTION_HINT:
			context->setPerspectiveCorrectionHint(mode);
			break;
		case GL_FOG_HINT:
			context->setFogHint(mode);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

GLboolean IsBuffer(GLuint buffer)
{
	TRACE("(GLuint buffer = %d)", buffer);

	es1::Context *context = es1::getContext();

	if(context && buffer)
	{
		es1::Buffer *bufferObject = context->getBuffer(buffer);

		if(bufferObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean IsEnabled(GLenum cap)
{
	TRACE("(GLenum cap = 0x%X)", cap);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(cap)
		{
		case GL_CULL_FACE:                return context->isCullFaceEnabled();              break;
		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();     break;
		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); break;
		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();        break;
		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();           break;
		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();           break;
		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();             break;
		case GL_BLEND:                    return context->isBlendEnabled();                 break;
		case GL_DITHER:                   return context->isDitherEnabled();                break;
		case GL_LIGHTING:                 return context->isLightingEnabled();              break;
		case GL_LIGHT0:                   return context->isLightEnabled(0);                break;
		case GL_LIGHT1:                   return context->isLightEnabled(1);                break;
		case GL_LIGHT2:                   return context->isLightEnabled(2);                break;
		case GL_LIGHT3:                   return context->isLightEnabled(3);                break;
		case GL_LIGHT4:                   return context->isLightEnabled(4);                break;
		case GL_LIGHT5:                   return context->isLightEnabled(5);                break;
		case GL_LIGHT6:                   return context->isLightEnabled(6);                break;
		case GL_LIGHT7:                   return context->isLightEnabled(7);                break;
		case GL_FOG:                      return context->isFogEnabled();                   break;
		case GL_TEXTURE_2D:               return context->isTexture2Denabled();             break;
		case GL_TEXTURE_EXTERNAL_OES:     return context->isTextureExternalEnabled();       break;
		case GL_ALPHA_TEST:               return context->isAlphaTestEnabled();             break;
		case GL_COLOR_LOGIC_OP:           return context->isColorLogicOpEnabled();          break;
		case GL_POINT_SMOOTH:             return context->isPointSmoothEnabled();           break;
		case GL_LINE_SMOOTH:              return context->isLineSmoothEnabled();            break;
		case GL_COLOR_MATERIAL:           return context->isColorMaterialEnabled();         break;
		case GL_NORMALIZE:                return context->isNormalizeEnabled();             break;
		case GL_RESCALE_NORMAL:           return context->isRescaleNormalEnabled();         break;
		case GL_VERTEX_ARRAY:             return context->isVertexArrayEnabled();           break;
		case GL_NORMAL_ARRAY:             return context->isNormalArrayEnabled();           break;
		case GL_COLOR_ARRAY:              return context->isColorArrayEnabled();            break;
		case GL_POINT_SIZE_ARRAY_OES:     return context->isPointSizeArrayEnabled();        break;
		case GL_TEXTURE_COORD_ARRAY:      return context->isTextureCoordArrayEnabled();     break;
		case GL_MULTISAMPLE:              return context->isMultisampleEnabled();           break;
		case GL_SAMPLE_ALPHA_TO_ONE:      return context->isSampleAlphaToOneEnabled();      break;
		case GL_CLIP_PLANE0:              return context->isClipPlaneEnabled(0);            break;
		case GL_CLIP_PLANE1:              return context->isClipPlaneEnabled(1);            break;
		case GL_CLIP_PLANE2:              return context->isClipPlaneEnabled(2);            break;
		case GL_CLIP_PLANE3:              return context->isClipPlaneEnabled(3);            break;
		case GL_CLIP_PLANE4:              return context->isClipPlaneEnabled(4);            break;
		case GL_CLIP_PLANE5:              return context->isClipPlaneEnabled(5);            break;
		case GL_POINT_SPRITE_OES:         return context->isPointSpriteEnabled();           break;
		default:
			return error(GL_INVALID_ENUM, GL_FALSE);
		}
	}

	return GL_FALSE;
}

GLboolean IsFramebufferOES(GLuint framebuffer)
{
	TRACE("(GLuint framebuffer = %d)", framebuffer);

	es1::Context *context = es1::getContext();

	if(context && framebuffer)
	{
		es1::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);

		if(framebufferObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean IsTexture(GLuint texture)
{
	TRACE("(GLuint texture = %d)", texture);

	es1::Context *context = es1::getContext();

	if(context && texture)
	{
		es1::Texture *textureObject = context->getTexture(texture);

		if(textureObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean IsRenderbufferOES(GLuint renderbuffer)
{
	TRACE("(GLuint renderbuffer = %d)", renderbuffer);

	es1::Context *context = es1::getContext();

	if(context && renderbuffer)
	{
		es1::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);

		if(renderbufferObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

void LightModelf(GLenum pname, GLfloat param)
{
	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_LIGHT_MODEL_TWO_SIDE:
			context->setLightModelTwoSide(param != 0.0f);
			break;
		case GL_LIGHT_MODEL_AMBIENT:
			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelfv() instead
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void LightModelfv(GLenum pname, const GLfloat *params)
{
	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_LIGHT_MODEL_AMBIENT:
			context->setGlobalAmbient(params[0], params[1], params[2], params[3]);
			break;
		case GL_LIGHT_MODEL_TWO_SIDE:
			context->setLightModelTwoSide(params[0] != 0.0f);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void LightModelx(GLenum pname, GLfixed param)
{
	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_LIGHT_MODEL_TWO_SIDE:
			context->setLightModelTwoSide(param != 0);
			break;
		case GL_LIGHT_MODEL_AMBIENT:
			return error(GL_INVALID_ENUM);   // Need four values, should call glLightModelxv() instead
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void LightModelxv(GLenum pname, const GLfixed *params)
{
	TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_LIGHT_MODEL_AMBIENT:
			context->setGlobalAmbient((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000, (float)params[3] / 0x10000);
			break;
		case GL_LIGHT_MODEL_TWO_SIDE:
			context->setLightModelTwoSide(params[0] != 0);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void Lightf(GLenum light, GLenum pname, GLfloat param)
{
	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", light, pname, param);

	int index = light - GL_LIGHT0;

	if(index < 0 || index >= es1::MAX_LIGHTS)
	{
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_SPOT_EXPONENT:
			if(param < 0.0f || param > 128.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setSpotLightExponent(index, param);
			break;
		case GL_SPOT_CUTOFF:
			if((param < 0.0f || param > 90.0f) && param != 180.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setSpotLightCutoff(index, param);
			break;
		case GL_CONSTANT_ATTENUATION:
			if(param < 0.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setLightAttenuationConstant(index, param);
			break;
		case GL_LINEAR_ATTENUATION:
			if(param < 0.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setLightAttenuationLinear(index, param);
			break;
		case GL_QUADRATIC_ATTENUATION:
			if(param < 0.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setLightAttenuationQuadratic(index, param);
			break;
		case GL_AMBIENT:
		case GL_DIFFUSE:
		case GL_SPECULAR:
		case GL_POSITION:
		case GL_SPOT_DIRECTION:
			return error(GL_INVALID_ENUM);   // Need four values, should call glLightfv() instead
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void Lightfv(GLenum light, GLenum pname, const GLfloat *params)
{
	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);

	es1::Context *context = es1::getContext();

	if(context)
	{
		int index = light - GL_LIGHT0;

		if(index < 0 || index > es1::MAX_LIGHTS)
		{
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_AMBIENT:               context->setLightAmbient(index, params[0], params[1], params[2], params[3]);  break;
		case GL_DIFFUSE:               context->setLightDiffuse(index, params[0], params[1], params[2], params[3]);  break;
		case GL_SPECULAR:              context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break;
		case GL_POSITION:              context->setLightPosition(index, params[0], params[1], params[2], params[3]); break;
		case GL_SPOT_DIRECTION:        context->setLightDirection(index, params[0], params[1], params[2]);           break;
		case GL_SPOT_EXPONENT:
			if(params[0] < 0.0f || params[0] > 128.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setSpotLightExponent(index, params[0]);
			break;
		case GL_SPOT_CUTOFF:
			if((params[0] < 0.0f || params[0] > 90.0f) && params[0] != 180.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setSpotLightCutoff(index, params[0]);
			break;
		case GL_CONSTANT_ATTENUATION:
			if(params[0] < 0.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setLightAttenuationConstant(index, params[0]);
			break;
		case GL_LINEAR_ATTENUATION:
			if(params[0] < 0.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setLightAttenuationLinear(index, params[0]);
			break;
		case GL_QUADRATIC_ATTENUATION:
			if(params[0] < 0.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setLightAttenuationQuadratic(index, params[0]);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void Lightx(GLenum light, GLenum pname, GLfixed param)
{
	UNIMPLEMENTED();
}

void Lightxv(GLenum light, GLenum pname, const GLfixed *params)
{
	UNIMPLEMENTED();
}

void LineWidth(GLfloat width)
{
	TRACE("(GLfloat width = %f)", width);

	if(width <= 0.0f)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setLineWidth(width);
	}
}

void LineWidthx(GLfixed width)
{
	LineWidth((float)width / 0x10000);
}

void LoadIdentity(void)
{
	TRACE("()");

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->loadIdentity();
	}
}

void LoadMatrixf(const GLfloat *m)
{
	TRACE("(const GLfloat *m)");

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->load(m);
	}
}

void LoadMatrixx(const GLfixed *m)
{
	GLfloat matrix[16] =
	{
		(float)m[0] / 0x10000,  (float)m[1] / 0x10000,  (float)m[2] / 0x10000,  (float)m[3] / 0x10000,
		(float)m[4] / 0x10000,  (float)m[5] / 0x10000,  (float)m[6] / 0x10000,  (float)m[7] / 0x10000,
		(float)m[8] / 0x10000,  (float)m[9] / 0x10000,  (float)m[10] / 0x10000, (float)m[11] / 0x10000,
		(float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
	};

	LoadMatrixf(matrix);
}

void LogicOp(GLenum opcode)
{
	TRACE("(GLenum opcode = 0x%X)", opcode);

	switch(opcode)
	{
	case GL_CLEAR:
	case GL_SET:
	case GL_COPY:
	case GL_COPY_INVERTED:
	case GL_NOOP:
	case GL_INVERT:
	case GL_AND:
	case GL_NAND:
	case GL_OR:
	case GL_NOR:
	case GL_XOR:
	case GL_EQUIV:
	case GL_AND_REVERSE:
	case GL_AND_INVERTED:
	case GL_OR_REVERSE:
	case GL_OR_INVERTED:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setLogicalOperation(opcode);
	}
}

void Materialf(GLenum face, GLenum pname, GLfloat param)
{
	TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", face, pname, param);

	if(face != GL_FRONT_AND_BACK)
	{
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_SHININESS:
			if(param < 0.0f || param > 128.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setMaterialShininess(param);
			break;
		case GL_AMBIENT:
		case GL_DIFFUSE:
		case GL_AMBIENT_AND_DIFFUSE:
		case GL_SPECULAR:
		case GL_EMISSION:
			return error(GL_INVALID_ENUM);   // Need four values, should call glMaterialfv() instead
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void Materialfv(GLenum face, GLenum pname, const GLfloat *params)
{
	TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat params)", face, pname);

	if(face != GL_FRONT_AND_BACK)
	{
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_AMBIENT:
			context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
			break;
		case GL_DIFFUSE:
			context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
			break;
		case GL_AMBIENT_AND_DIFFUSE:
			context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
			context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
			break;
		case GL_SPECULAR:
			context->setMaterialSpecular(params[0], params[1], params[2], params[3]);
			break;
		case GL_EMISSION:
			context->setMaterialEmission(params[0], params[1], params[2], params[3]);
			break;
		case GL_SHININESS:
			context->setMaterialShininess(params[0]);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void Materialx(GLenum face, GLenum pname, GLfixed param)
{
	UNIMPLEMENTED();
}

void Materialxv(GLenum face, GLenum pname, const GLfixed *params)
{
	UNIMPLEMENTED();
}

void MatrixMode(GLenum mode)
{
	TRACE("(GLenum mode = 0x%X)", mode);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setMatrixMode(mode);
	}
}

void MultMatrixf(const GLfloat *m)
{
	TRACE("(const GLfloat *m)");

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->multiply(m);
	}
}

void MultMatrixx(const GLfixed *m)
{
	GLfloat matrix[16] =
	{
		(float)m[0] / 0x10000,  (float)m[1] / 0x10000,  (float)m[2] / 0x10000,  (float)m[3] / 0x10000,
		(float)m[4] / 0x10000,  (float)m[5] / 0x10000,  (float)m[6] / 0x10000,  (float)m[7] / 0x10000,
		(float)m[8] / 0x10000,  (float)m[9] / 0x10000,  (float)m[10] / 0x10000, (float)m[11] / 0x10000,
		(float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
	};

	MultMatrixf(matrix);
}

void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
{
	TRACE("(GLenum target = 0x%X, GLfloat s = %f, GLfloat t = %f, GLfloat r = %f, GLfloat q = %f)", target, s, t, r, q);

	switch(target)
	{
	case GL_TEXTURE0:
	case GL_TEXTURE1:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setVertexAttrib(sw::TexCoord0 + (target - GL_TEXTURE0), s, t, r, q);
	}
}

void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
{
	UNIMPLEMENTED();
}

void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
{
	TRACE("(GLfloat nx, GLfloat ny, GLfloat nz)", nx, ny, nz);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
	}
}

void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz)
{
	UNIMPLEMENTED();
}

void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
{
	TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);

	VertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);
}

void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
{
	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);

	if(left == right || bottom == top || zNear == zFar)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->ortho(left, right, bottom, top, zNear, zFar);
	}
}

void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
{
	Orthof((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);
}

void PixelStorei(GLenum pname, GLint param)
{
	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_UNPACK_ALIGNMENT:
			if(param != 1 && param != 2 && param != 4 && param != 8)
			{
				return error(GL_INVALID_VALUE);
			}

			context->setUnpackAlignment(param);
			break;
		case GL_PACK_ALIGNMENT:
			if(param != 1 && param != 2 && param != 4 && param != 8)
			{
				return error(GL_INVALID_VALUE);
			}

			context->setPackAlignment(param);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void PointParameterf(GLenum pname, GLfloat param)
{
	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_POINT_SIZE_MIN:
			if(param < 0.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPointSizeMin(param);
			break;
		case GL_POINT_SIZE_MAX:
			if(param < 0.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPointSizeMax(param);
			break;
		case GL_POINT_FADE_THRESHOLD_SIZE:
			if(param < 0.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPointFadeThresholdSize(param);
			break;
		case GL_POINT_DISTANCE_ATTENUATION:
			return error(GL_INVALID_ENUM);   // Needs three values, should call glPointParameterfv() instead
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void PointParameterfv(GLenum pname, const GLfloat *params)
{
	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_POINT_SIZE_MIN:
			if(params[0] < 0.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPointSizeMin(params[0]);
			break;
		case GL_POINT_SIZE_MAX:
			if(params[0] < 0.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPointSizeMax(params[0]);
			break;
		case GL_POINT_DISTANCE_ATTENUATION:
			context->setPointDistanceAttenuation(params[0], params[1], params[2]);
			break;
		case GL_POINT_FADE_THRESHOLD_SIZE:
			if(params[0] < 0.0f)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPointFadeThresholdSize(params[0]);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void PointParameterx(GLenum pname, GLfixed param)
{
	TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_POINT_SIZE_MIN:
			if(param < 0)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPointSizeMin((float)param / 0x10000);
			break;
		case GL_POINT_SIZE_MAX:
			if(param < 0)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPointSizeMax((float)param / 0x10000);
			break;
		case GL_POINT_FADE_THRESHOLD_SIZE:
			if(param < 0)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPointFadeThresholdSize((float)param / 0x10000);
			break;
		case GL_POINT_DISTANCE_ATTENUATION:
			return error(GL_INVALID_ENUM);   // Needs three parameters, should call glPointParameterxv() instead
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void PointParameterxv(GLenum pname, const GLfixed *params)
{
	TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_POINT_SIZE_MIN:
			if(params[0] < 0)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPointSizeMin((float)params[0] / 0x10000);
			break;
		case GL_POINT_SIZE_MAX:
			if(params[0] < 0)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPointSizeMax((float)params[0] / 0x10000);
			break;
		case GL_POINT_DISTANCE_ATTENUATION:
			context->setPointDistanceAttenuation((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000);
			break;
		case GL_POINT_FADE_THRESHOLD_SIZE:
			if(params[0] < 0)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPointFadeThresholdSize((float)params[0] / 0x10000);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void PointSize(GLfloat size)
{
	TRACE("(GLfloat size = %f)", size);

	if(size <= 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setVertexAttrib(sw::PointSize, size, size, size, size);
	}
}

void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
{
	TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);

	switch(type)
	{
	case GL_FIXED:
	case GL_FLOAT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	VertexAttribPointer(sw::PointSize, 1, type, true, stride, pointer);
}

void PointSizex(GLfixed size)
{
	PointSize((float)size / 0x10000);
}

void PolygonOffset(GLfloat factor, GLfloat units)
{
	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setPolygonOffsetParams(factor, units);
	}
}

void PolygonOffsetx(GLfixed factor, GLfixed units)
{
	PolygonOffset((float)factor / 0x10000, (float)units / 0x10000);
}

void PopMatrix(void)
{
	TRACE("()");

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->popMatrix();
	}
}

void PushMatrix(void)
{
	TRACE("()");

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->pushMatrix();
	}
}

void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
{
	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
	      "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
	      x, y, width, height, format, type,  pixels);

	if(width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->readPixels(x, y, width, height, format, type, nullptr, pixels);
	}
}

void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
	TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
	      target, internalformat, width, height);

	switch(target)
	{
	case GL_RENDERBUFFER_OES:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(!es1::IsColorRenderable(internalformat) && !es1::IsDepthRenderable(internalformat) && !es1::IsStencilRenderable(internalformat))
	{
		return error(GL_INVALID_ENUM);
	}

	if(width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		if(width > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
		   height > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
		{
			return error(GL_INVALID_VALUE);
		}

		GLuint handle = context->getRenderbufferName();
		if(handle == 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		switch(internalformat)
		{
		case GL_RGBA4_OES:
		case GL_RGB5_A1_OES:
		case GL_RGB565_OES:
		case GL_RGB8_OES:
		case GL_RGBA8_OES:
			context->setRenderbufferStorage(new es1::Colorbuffer(width, height, internalformat, 0));
			break;
		case GL_DEPTH_COMPONENT16_OES:
			context->setRenderbufferStorage(new es1::Depthbuffer(width, height, internalformat,  0));
			break;
		case GL_STENCIL_INDEX8_OES:
			context->setRenderbufferStorage(new es1::Stencilbuffer(width, height, 0));
			break;
		case GL_DEPTH24_STENCIL8_OES:
			context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, internalformat, 0));
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{
	TRACE("(GLfloat angle = %f, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", angle, x, y, z);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->rotate(angle, x, y, z);
	}
}

void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
{
	Rotatef((float)angle / 0x10000, (float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
}

void SampleCoverage(GLclampf value, GLboolean invert)
{
	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);

	es1::Context* context = es1::getContext();

	if(context)
	{
		context->setSampleCoverageParams(es1::clamp01(value), invert != GL_FALSE);
	}
}

void SampleCoveragex(GLclampx value, GLboolean invert)
{
	SampleCoverage((float)value / 0x10000, invert);
}

void Scalef(GLfloat x, GLfloat y, GLfloat z)
{
	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->scale(x, y, z);
	}
}

void Scalex(GLfixed x, GLfixed y, GLfixed z)
{
	Scalef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
}

void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);

	if(width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context* context = es1::getContext();

	if(context)
	{
		context->setScissorParams(x, y, width, height);
	}
}

void ShadeModel(GLenum mode)
{
	switch(mode)
	{
	case GL_FLAT:
	case GL_SMOOTH:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setShadeModel(mode);
	}
}

void StencilFunc(GLenum func, GLint ref, GLuint mask)
{
	TRACE("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)",  func, ref, mask);

	switch(func)
	{
	case GL_NEVER:
	case GL_ALWAYS:
	case GL_LESS:
	case GL_LEQUAL:
	case GL_EQUAL:
	case GL_GEQUAL:
	case GL_GREATER:
	case GL_NOTEQUAL:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setStencilParams(func, ref, mask);
	}
}

void StencilMask(GLuint mask)
{
	TRACE("(GLuint mask = %d)", mask);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setStencilWritemask(mask);
	}
}

void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
{
	TRACE("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", fail, zfail, zpass);

	switch(fail)
	{
	case GL_ZERO:
	case GL_KEEP:
	case GL_REPLACE:
	case GL_INCR:
	case GL_DECR:
	case GL_INVERT:
	case GL_INCR_WRAP_OES:
	case GL_DECR_WRAP_OES:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(zfail)
	{
	case GL_ZERO:
	case GL_KEEP:
	case GL_REPLACE:
	case GL_INCR:
	case GL_DECR:
	case GL_INVERT:
	case GL_INCR_WRAP_OES:
	case GL_DECR_WRAP_OES:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(zpass)
	{
	case GL_ZERO:
	case GL_KEEP:
	case GL_REPLACE:
	case GL_INCR:
	case GL_DECR:
	case GL_INVERT:
	case GL_INCR_WRAP_OES:
	case GL_DECR_WRAP_OES:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setStencilOperations(fail, zfail, zpass);
	}
}

void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);

	if(size < 2 || size > 4)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		GLenum texture = context->getClientActiveTexture();
		VertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
	}
}

void TexEnvi(GLenum target, GLenum pname, GLint param);

void TexEnvf(GLenum target, GLenum pname, GLfloat param)
{
	TexEnvi(target, pname, (GLint)param);
}

void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params)", target, pname);

	es1::Context *context = es1::getContext();

	if(context)
	{
		GLint iParam = (GLint)roundf(params[0]);

		switch(target)
		{
		case GL_POINT_SPRITE_OES:
			UNIMPLEMENTED();
			break;
		case GL_TEXTURE_ENV:
			switch(pname)
			{
			case GL_TEXTURE_ENV_MODE:
				switch(iParam)
				{
				case GL_REPLACE:
				case GL_MODULATE:
				case GL_DECAL:
				case GL_BLEND:
				case GL_ADD:
				case GL_COMBINE:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setTextureEnvMode(iParam);
				break;
			case GL_TEXTURE_ENV_COLOR:
				context->setTextureEnvColor(clamp01(params[0]), clamp01(params[1]), clamp01(params[2]), clamp01(params[3]));
				break;
			case GL_COMBINE_RGB:
				switch(iParam)
				{
				case GL_REPLACE:
				case GL_MODULATE:
				case GL_ADD:
				case GL_ADD_SIGNED:
				case GL_INTERPOLATE:
				case GL_SUBTRACT:
				case GL_DOT3_RGB:
				case GL_DOT3_RGBA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setCombineRGB(iParam);
				break;
			case GL_COMBINE_ALPHA:
				switch(iParam)
				{
				case GL_REPLACE:
				case GL_MODULATE:
				case GL_ADD:
				case GL_ADD_SIGNED:
				case GL_INTERPOLATE:
				case GL_SUBTRACT:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setCombineAlpha(iParam);
				break;
			case GL_RGB_SCALE:
				if(iParam != 1 && iParam != 2 && iParam != 4)
				{
					return error(GL_INVALID_VALUE);
				}
				if(iParam != 1) UNIMPLEMENTED();
				break;
			case GL_ALPHA_SCALE:
				if(iParam != 1 && iParam != 2 && iParam != 4)
				{
					return error(GL_INVALID_VALUE);
				}
				if(iParam != 1) UNIMPLEMENTED();
				break;
			case GL_OPERAND0_RGB:
				switch(iParam)
				{
				case GL_SRC_COLOR:
				case GL_ONE_MINUS_SRC_COLOR:
				case GL_SRC_ALPHA:
				case GL_ONE_MINUS_SRC_ALPHA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setOperand0RGB(iParam);
				break;
			case GL_OPERAND1_RGB:
				switch(iParam)
				{
				case GL_SRC_COLOR:
				case GL_ONE_MINUS_SRC_COLOR:
				case GL_SRC_ALPHA:
				case GL_ONE_MINUS_SRC_ALPHA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setOperand1RGB(iParam);
				break;
			case GL_OPERAND2_RGB:
				switch(iParam)
				{
				case GL_SRC_COLOR:
				case GL_ONE_MINUS_SRC_COLOR:
				case GL_SRC_ALPHA:
				case GL_ONE_MINUS_SRC_ALPHA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setOperand2RGB(iParam);
				break;
			case GL_OPERAND0_ALPHA:
				switch(iParam)
				{
				case GL_SRC_ALPHA:
				case GL_ONE_MINUS_SRC_ALPHA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setOperand0Alpha(iParam);
				break;
			case GL_OPERAND1_ALPHA:
				switch(iParam)
				{
				case GL_SRC_ALPHA:
				case GL_ONE_MINUS_SRC_ALPHA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setOperand1Alpha(iParam);
				break;
			case GL_OPERAND2_ALPHA:
				switch(iParam)
				{
				case GL_SRC_ALPHA:
				case GL_ONE_MINUS_SRC_ALPHA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setOperand2Alpha(iParam);
				break;
			case GL_SRC0_RGB:
				switch(iParam)
				{
				case GL_TEXTURE:
				case GL_CONSTANT:
				case GL_PRIMARY_COLOR:
				case GL_PREVIOUS:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setSrc0RGB(iParam);
				break;
			case GL_SRC1_RGB:
				switch(iParam)
				{
				case GL_TEXTURE:
				case GL_CONSTANT:
				case GL_PRIMARY_COLOR:
				case GL_PREVIOUS:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setSrc1RGB(iParam);
				break;
			case GL_SRC2_RGB:
				switch(iParam)
				{
				case GL_TEXTURE:
				case GL_CONSTANT:
				case GL_PRIMARY_COLOR:
				case GL_PREVIOUS:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setSrc2RGB(iParam);
				break;
			case GL_SRC0_ALPHA:
				switch(iParam)
				{
				case GL_TEXTURE:
				case GL_CONSTANT:
				case GL_PRIMARY_COLOR:
				case GL_PREVIOUS:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setSrc0Alpha(iParam);
				break;
			case GL_SRC1_ALPHA:
				switch(iParam)
				{
				case GL_TEXTURE:
				case GL_CONSTANT:
				case GL_PRIMARY_COLOR:
				case GL_PREVIOUS:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setSrc1Alpha(iParam);
				break;
			case GL_SRC2_ALPHA:
				switch(iParam)
				{
				case GL_TEXTURE:
				case GL_CONSTANT:
				case GL_PRIMARY_COLOR:
				case GL_PREVIOUS:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setSrc2Alpha(iParam);
				break;
			default:
				return error(GL_INVALID_ENUM);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void TexEnvi(GLenum target, GLenum pname, GLint param)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(target)
		{
		case GL_POINT_SPRITE_OES:
			UNIMPLEMENTED();
			break;
		case GL_TEXTURE_ENV:
			switch(pname)
			{
			case GL_TEXTURE_ENV_MODE:
				switch((GLenum)param)
				{
				case GL_REPLACE:
				case GL_MODULATE:
				case GL_DECAL:
				case GL_BLEND:
				case GL_ADD:
				case GL_COMBINE:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setTextureEnvMode((GLenum)param);
				break;
			case GL_TEXTURE_ENV_COLOR:
				return error(GL_INVALID_ENUM);   // Needs four values, should call glTexEnviv() instead
				break;
			case GL_COMBINE_RGB:
				switch((GLenum)param)
				{
				case GL_REPLACE:
				case GL_MODULATE:
				case GL_ADD:
				case GL_ADD_SIGNED:
				case GL_INTERPOLATE:
				case GL_SUBTRACT:
				case GL_DOT3_RGB:
				case GL_DOT3_RGBA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setCombineRGB((GLenum)param);
				break;
			case GL_COMBINE_ALPHA:
				switch((GLenum)param)
				{
				case GL_REPLACE:
				case GL_MODULATE:
				case GL_ADD:
				case GL_ADD_SIGNED:
				case GL_INTERPOLATE:
				case GL_SUBTRACT:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setCombineAlpha((GLenum)param);
				break;
			case GL_RGB_SCALE:
				if(param != 1 && param != 2 && param != 4)
				{
					return error(GL_INVALID_VALUE);
				}
				if(param != 1) UNIMPLEMENTED();
				break;
			case GL_ALPHA_SCALE:
				if(param != 1 && param != 2 && param != 4)
				{
					return error(GL_INVALID_VALUE);
				}
				if(param != 1) UNIMPLEMENTED();
				break;
			case GL_OPERAND0_RGB:
				switch((GLenum)param)
				{
				case GL_SRC_COLOR:
				case GL_ONE_MINUS_SRC_COLOR:
				case GL_SRC_ALPHA:
				case GL_ONE_MINUS_SRC_ALPHA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setOperand0RGB((GLenum)param);
				break;
			case GL_OPERAND1_RGB:
				switch((GLenum)param)
				{
				case GL_SRC_COLOR:
				case GL_ONE_MINUS_SRC_COLOR:
				case GL_SRC_ALPHA:
				case GL_ONE_MINUS_SRC_ALPHA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setOperand1RGB((GLenum)param);
				break;
			case GL_OPERAND2_RGB:
				switch((GLenum)param)
				{
				case GL_SRC_COLOR:
				case GL_ONE_MINUS_SRC_COLOR:
				case GL_SRC_ALPHA:
				case GL_ONE_MINUS_SRC_ALPHA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setOperand2RGB((GLenum)param);
				break;
			case GL_OPERAND0_ALPHA:
				switch((GLenum)param)
				{
				case GL_SRC_ALPHA:
				case GL_ONE_MINUS_SRC_ALPHA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setOperand0Alpha((GLenum)param);
				break;
			case GL_OPERAND1_ALPHA:
				switch((GLenum)param)
				{
				case GL_SRC_ALPHA:
				case GL_ONE_MINUS_SRC_ALPHA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setOperand1Alpha((GLenum)param);
				break;
			case GL_OPERAND2_ALPHA:
				switch((GLenum)param)
				{
				case GL_SRC_ALPHA:
				case GL_ONE_MINUS_SRC_ALPHA:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setOperand2Alpha((GLenum)param);
				break;
			case GL_SRC0_RGB:
				switch((GLenum)param)
				{
				case GL_TEXTURE:
				case GL_CONSTANT:
				case GL_PRIMARY_COLOR:
				case GL_PREVIOUS:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setSrc0RGB((GLenum)param);
				break;
			case GL_SRC1_RGB:
				switch((GLenum)param)
				{
				case GL_TEXTURE:
				case GL_CONSTANT:
				case GL_PRIMARY_COLOR:
				case GL_PREVIOUS:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setSrc1RGB((GLenum)param);
				break;
			case GL_SRC2_RGB:
				switch((GLenum)param)
				{
				case GL_TEXTURE:
				case GL_CONSTANT:
				case GL_PRIMARY_COLOR:
				case GL_PREVIOUS:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setSrc2RGB((GLenum)param);
				break;
			case GL_SRC0_ALPHA:
				switch((GLenum)param)
				{
				case GL_TEXTURE:
				case GL_CONSTANT:
				case GL_PRIMARY_COLOR:
				case GL_PREVIOUS:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setSrc0Alpha((GLenum)param);
				break;
			case GL_SRC1_ALPHA:
				switch((GLenum)param)
				{
				case GL_TEXTURE:
				case GL_CONSTANT:
				case GL_PRIMARY_COLOR:
				case GL_PREVIOUS:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setSrc1Alpha((GLenum)param);
				break;
			case GL_SRC2_ALPHA:
				switch((GLenum)param)
				{
				case GL_TEXTURE:
				case GL_CONSTANT:
				case GL_PRIMARY_COLOR:
				case GL_PREVIOUS:
					break;
				default:
					error(GL_INVALID_ENUM);
				}

				context->setSrc2Alpha((GLenum)param);
				break;
			default:
				return error(GL_INVALID_ENUM);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void TexEnvx(GLenum target, GLenum pname, GLfixed param)
{
	TexEnvi(target, pname, (GLint)param);
}

void TexEnviv(GLenum target, GLenum pname, const GLint *params)
{
	UNIMPLEMENTED();
}

void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
{
	UNIMPLEMENTED();
}

void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
                GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
	      "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",
	      target, level, internalformat, width, height, border, format, type, pixels);

	if(!validImageSize(level, width, height))
	{
		return error(GL_INVALID_VALUE);
	}

	if(internalformat != (GLint)format)
	{
		return error(GL_INVALID_OPERATION);
	}

	switch(format)
	{
	case GL_ALPHA:
	case GL_LUMINANCE:
	case GL_LUMINANCE_ALPHA:
		switch(type)
		{
		case GL_UNSIGNED_BYTE:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
		break;
	case GL_RGB:
		switch(type)
		{
		case GL_UNSIGNED_BYTE:
		case GL_UNSIGNED_SHORT_5_6_5:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
		break;
	case GL_RGBA:
		switch(type)
		{
		case GL_UNSIGNED_BYTE:
		case GL_UNSIGNED_SHORT_4_4_4_4:
		case GL_UNSIGNED_SHORT_5_5_5_1:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
		break;
	case GL_BGRA_EXT:
		switch(type)
		{
		case GL_UNSIGNED_BYTE:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
		break;
	case GL_ETC1_RGB8_OES:
	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
		return error(GL_INVALID_OPERATION);
	case GL_DEPTH_STENCIL_OES:
		switch(type)
		{
		case GL_UNSIGNED_INT_24_8_OES:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
		break;
	default:
		return error(GL_INVALID_VALUE);
	}

	if(border != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	GLint sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type);

	es1::Context *context = es1::getContext();

	if(context)
	{
		switch(target)
		{
		case GL_TEXTURE_2D:
			if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
			   height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(target == GL_TEXTURE_2D)
		{
			es1::Texture2D *texture = context->getTexture2D();

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			texture->setImage(level, width, height, sizedInternalFormat, format, type, context->getUnpackAlignment(), pixels);
		}
		else UNREACHABLE(target);
	}
}

void TexParameterf(GLenum target, GLenum pname, GLfloat param)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D();
			break;
		case GL_TEXTURE_EXTERNAL_OES:
			texture = context->getTextureExternal();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_WRAP_S:
			if(!texture->setWrapS((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_WRAP_T:
			if(!texture->setWrapT((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MIN_FILTER:
			if(!texture->setMinFilter((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MAG_FILTER:
			if(!texture->setMagFilter((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			if(!texture->setMaxAnisotropy(param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_GENERATE_MIPMAP:
			texture->setGenerateMipmap((GLboolean)param);
			break;
		case GL_TEXTURE_CROP_RECT_OES:
			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameterfv() instead
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
{
	TexParameterf(target, pname, *params);
}

void TexParameteri(GLenum target, GLenum pname, GLint param)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D();
			break;
		case GL_TEXTURE_EXTERNAL_OES:
			texture = context->getTextureExternal();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_WRAP_S:
			if(!texture->setWrapS((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_WRAP_T:
			if(!texture->setWrapT((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MIN_FILTER:
			if(!texture->setMinFilter((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MAG_FILTER:
			if(!texture->setMagFilter((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			if(!texture->setMaxAnisotropy((GLfloat)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_GENERATE_MIPMAP:
			texture->setGenerateMipmap((GLboolean)param);
			break;
		case GL_TEXTURE_CROP_RECT_OES:
			return error(GL_INVALID_ENUM);   // Needs four values, should call glTexParameteriv() instead
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %p)", target, pname, params);

	switch(pname)
	{
	case GL_TEXTURE_CROP_RECT_OES:
		break;
	default:
		return TexParameteri(target, pname, params[0]);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_CROP_RECT_OES:
			texture->setCropRect(params[0], params[1], params[2], params[3]);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void TexParameterx(GLenum target, GLenum pname, GLfixed param)
{
	TexParameteri(target, pname, (GLint)param);
}

void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
{
	UNIMPLEMENTED();
}

void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                   GLenum format, GLenum type, const GLvoid* pixels)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
	      "const GLvoid* pixels = %p)",
	      target, level, xoffset, yoffset, width, height, format, type, pixels);

	if(!es1::IsTextureTarget(target))
	{
		return error(GL_INVALID_ENUM);
	}

	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
	{
		return error(GL_INVALID_VALUE);
	}

	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
	{
		return error(GL_INVALID_VALUE);
	}

	if(width == 0 || height == 0 || !pixels)
	{
		return;
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		if(target == GL_TEXTURE_2D)
		{
			es1::Texture2D *texture = context->getTexture2D();

			GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture);
			if(validationError != GL_NO_ERROR)
			{
				return error(validationError);
			}

			texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
		}
		else UNREACHABLE(target);
	}
}

void Translatef(GLfloat x, GLfloat y, GLfloat z)
{
	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->translate(x, y, z);
	}
}

void Translatex(GLfixed x, GLfixed y, GLfixed z)
{
	Translatef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
}

void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);

	if(size < 2 || size > 4)
	{
		return error(GL_INVALID_VALUE);
	}

	VertexAttribPointer(sw::Position, size, type, false, stride, pointer);
}

void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);

	if(width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->setViewportParams(x, y, width, height);
	}
}

void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
{
	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);

	switch(target)
	{
	case GL_TEXTURE_2D:
	case GL_TEXTURE_EXTERNAL_OES:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		es1::Texture2D *texture = nullptr;

		switch(target)
		{
		case GL_TEXTURE_2D:           texture = context->getTexture2D();       break;
		case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
		default:                      UNREACHABLE(target);
		}

		if(!texture)
		{
			return error(GL_INVALID_OPERATION);
		}

		egl::Image *eglImage = context->getSharedImage(image);

		if(!eglImage)
		{
			return error(GL_INVALID_OPERATION);
		}

		texture->setSharedImage(eglImage);
	}
}

void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
{
	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);

	UNIMPLEMENTED();
}

void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
{
	UNIMPLEMENTED();
}

void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
{
	TRACE("(GLint x = %d, GLint y = %d, GLint z = %d, GLint width = %d, GLint height = %d)", x, y, z, width, height);

	if(width <= 0 || height <= 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->drawTexture((GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)width, (GLfloat)height);
	}
}

void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
{
	UNIMPLEMENTED();
}

void DrawTexsvOES(const GLshort *coords)
{
	UNIMPLEMENTED();
}

void DrawTexivOES(const GLint *coords)
{
	UNIMPLEMENTED();
}

void DrawTexxvOES(const GLfixed *coords)
{
	UNIMPLEMENTED();
}

void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
{
	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat width = %f, GLfloat height = %f)", x, y, z, width, height);

	if(width <= 0 || height <= 0)
	{
		return error(GL_INVALID_VALUE);
	}

	es1::Context *context = es1::getContext();

	if(context)
	{
		context->drawTexture(x, y, z, width, height);
	}
}

void DrawTexfvOES(const GLfloat *coords)
{
	UNIMPLEMENTED();
}

}

extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname)
{
	struct Function
	{
		const char *name;
		__eglMustCastToProperFunctionPointerType address;
	};

	struct CompareFunctor
	{
		bool operator()(const Function &a, const Function &b) const
		{
			return strcmp(a.name, b.name) < 0;
		}
	};

	// This array must be kept sorted with respect to strcmp(), so that binary search works correctly.
	// The Unix command "LC_COLLATE=C sort" will generate the correct order.
	static const Function glFunctions[] =
	{
		#define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}

		FUNCTION(glActiveTexture),
		FUNCTION(glAlphaFunc),
		FUNCTION(glAlphaFuncx),
		FUNCTION(glBindBuffer),
		FUNCTION(glBindFramebufferOES),
		FUNCTION(glBindRenderbufferOES),
		FUNCTION(glBindTexture),
		FUNCTION(glBlendEquationOES),
		FUNCTION(glBlendEquationSeparateOES),
		FUNCTION(glBlendFunc),
		FUNCTION(glBlendFuncSeparateOES),
		FUNCTION(glBufferData),
		FUNCTION(glBufferSubData),
		FUNCTION(glCheckFramebufferStatusOES),
		FUNCTION(glClear),
		FUNCTION(glClearColor),
		FUNCTION(glClearColorx),
		FUNCTION(glClearDepthf),
		FUNCTION(glClearDepthx),
		FUNCTION(glClearStencil),
		FUNCTION(glClientActiveTexture),
		FUNCTION(glClipPlanef),
		FUNCTION(glClipPlanex),
		FUNCTION(glColor4f),
		FUNCTION(glColor4ub),
		FUNCTION(glColor4x),
		FUNCTION(glColorMask),
		FUNCTION(glColorPointer),
		FUNCTION(glCompressedTexImage2D),
		FUNCTION(glCompressedTexSubImage2D),
		FUNCTION(glCopyTexImage2D),
		FUNCTION(glCopyTexSubImage2D),
		FUNCTION(glCullFace),
		FUNCTION(glDeleteBuffers),
		FUNCTION(glDeleteFramebuffersOES),
		FUNCTION(glDeleteRenderbuffersOES),
		FUNCTION(glDeleteTextures),
		FUNCTION(glDepthFunc),
		FUNCTION(glDepthMask),
		FUNCTION(glDepthRangef),
		FUNCTION(glDepthRangex),
		FUNCTION(glDisable),
		FUNCTION(glDisableClientState),
		FUNCTION(glDrawArrays),
		FUNCTION(glDrawElements),
		FUNCTION(glDrawTexfOES),
		FUNCTION(glDrawTexfvOES),
		FUNCTION(glDrawTexiOES),
		FUNCTION(glDrawTexivOES),
		FUNCTION(glDrawTexsOES),
		FUNCTION(glDrawTexsvOES),
		FUNCTION(glDrawTexxOES),
		FUNCTION(glDrawTexxvOES),
		FUNCTION(glEGLImageTargetRenderbufferStorageOES),
		FUNCTION(glEGLImageTargetTexture2DOES),
		FUNCTION(glEnable),
		FUNCTION(glEnableClientState),
		FUNCTION(glFinish),
		FUNCTION(glFlush),
		FUNCTION(glFogf),
		FUNCTION(glFogfv),
		FUNCTION(glFogx),
		FUNCTION(glFogxv),
		FUNCTION(glFramebufferRenderbufferOES),
		FUNCTION(glFramebufferTexture2DOES),
		FUNCTION(glFrontFace),
		FUNCTION(glFrustumf),
		FUNCTION(glFrustumx),
		FUNCTION(glGenBuffers),
		FUNCTION(glGenFramebuffersOES),
		FUNCTION(glGenRenderbuffersOES),
		FUNCTION(glGenTextures),
		FUNCTION(glGenerateMipmapOES),
		FUNCTION(glGetBooleanv),
		FUNCTION(glGetBufferParameteriv),
		FUNCTION(glGetClipPlanef),
		FUNCTION(glGetClipPlanex),
		FUNCTION(glGetError),
		FUNCTION(glGetFixedv),
		FUNCTION(glGetFloatv),
		FUNCTION(glGetFramebufferAttachmentParameterivOES),
		FUNCTION(glGetIntegerv),
		FUNCTION(glGetLightfv),
		FUNCTION(glGetLightxv),
		FUNCTION(glGetMaterialfv),
		FUNCTION(glGetMaterialxv),
		FUNCTION(glGetPointerv),
		FUNCTION(glGetRenderbufferParameterivOES),
		FUNCTION(glGetString),
		FUNCTION(glGetTexEnvfv),
		FUNCTION(glGetTexEnviv),
		FUNCTION(glGetTexEnvxv),
		FUNCTION(glGetTexParameterfv),
		FUNCTION(glGetTexParameteriv),
		FUNCTION(glGetTexParameterxv),
		FUNCTION(glHint),
		FUNCTION(glIsBuffer),
		FUNCTION(glIsEnabled),
		FUNCTION(glIsFramebufferOES),
		FUNCTION(glIsRenderbufferOES),
		FUNCTION(glIsTexture),
		FUNCTION(glLightModelf),
		FUNCTION(glLightModelfv),
		FUNCTION(glLightModelx),
		FUNCTION(glLightModelxv),
		FUNCTION(glLightf),
		FUNCTION(glLightfv),
		FUNCTION(glLightx),
		FUNCTION(glLightxv),
		FUNCTION(glLineWidth),
		FUNCTION(glLineWidthx),
		FUNCTION(glLoadIdentity),
		FUNCTION(glLoadMatrixf),
		FUNCTION(glLoadMatrixx),
		FUNCTION(glLogicOp),
		FUNCTION(glMaterialf),
		FUNCTION(glMaterialfv),
		FUNCTION(glMaterialx),
		FUNCTION(glMaterialxv),
		FUNCTION(glMatrixMode),
		FUNCTION(glMultMatrixf),
		FUNCTION(glMultMatrixx),
		FUNCTION(glMultiTexCoord4f),
		FUNCTION(glMultiTexCoord4x),
		FUNCTION(glNormal3f),
		FUNCTION(glNormal3x),
		FUNCTION(glNormalPointer),
		FUNCTION(glOrthof),
		FUNCTION(glOrthox),
		FUNCTION(glPixelStorei),
		FUNCTION(glPointParameterf),
		FUNCTION(glPointParameterfv),
		FUNCTION(glPointParameterx),
		FUNCTION(glPointParameterxv),
		FUNCTION(glPointSize),
		FUNCTION(glPointSizePointerOES),
		FUNCTION(glPointSizex),
		FUNCTION(glPolygonOffset),
		FUNCTION(glPolygonOffsetx),
		FUNCTION(glPopMatrix),
		FUNCTION(glPushMatrix),
		FUNCTION(glReadPixels),
		FUNCTION(glRenderbufferStorageOES),
		FUNCTION(glRotatef),
		FUNCTION(glRotatex),
		FUNCTION(glSampleCoverage),
		FUNCTION(glSampleCoveragex),
		FUNCTION(glScalef),
		FUNCTION(glScalex),
		FUNCTION(glScissor),
		FUNCTION(glShadeModel),
		FUNCTION(glStencilFunc),
		FUNCTION(glStencilMask),
		FUNCTION(glStencilOp),
		FUNCTION(glTexCoordPointer),
		FUNCTION(glTexEnvf),
		FUNCTION(glTexEnvfv),
		FUNCTION(glTexEnvi),
		FUNCTION(glTexEnviv),
		FUNCTION(glTexEnvx),
		FUNCTION(glTexEnvxv),
		FUNCTION(glTexImage2D),
		FUNCTION(glTexParameterf),
		FUNCTION(glTexParameterfv),
		FUNCTION(glTexParameteri),
		FUNCTION(glTexParameteriv),
		FUNCTION(glTexParameterx),
		FUNCTION(glTexParameterxv),
		FUNCTION(glTexSubImage2D),
		FUNCTION(glTranslatef),
		FUNCTION(glTranslatex),
		FUNCTION(glVertexPointer),
		FUNCTION(glViewport),

		#undef FUNCTION
	};

	static const size_t numFunctions = sizeof glFunctions / sizeof(Function);
	static const Function *const glFunctionsEnd = glFunctions + numFunctions;

	Function needle;
	needle.name = procname;

	if(procname && strncmp("gl", procname, 2) == 0)
	{
		const Function *result = std::lower_bound(glFunctions, glFunctionsEnd, needle, CompareFunctor());
		if(result != glFunctionsEnd && strcmp(procname, result->name) == 0)
		{
			return (__eglMustCastToProperFunctionPointerType)result->address;
		}
	}

	return nullptr;
}
