diff --git a/CMakeLists.txt b/CMakeLists.txt
index e526d33..38b43a0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -47,9 +47,6 @@
 set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release MinSizeRel RelWithDebInfo)
 
 option(BUILD_EGL "Build the EGL library" 1)
-if(WIN32)
-    option(BUILD_GL32 "Build the OpenGL32 library" 1)
-endif()
 option(BUILD_GLESv2 "Build the OpenGL ES 2 library" 1)
 option(BUILD_GLES_CM "Build the OpenGL ES 1.1 library" 1)
 option(BUILD_VULKAN "Build the Vulkan library" 1)
@@ -1839,16 +1836,6 @@
     ${CMAKE_SOURCE_DIR}/include/*.h
 )
 
-file(GLOB_RECURSE GL32_LIST
-    ${OPENGL_DIR}/libGL/*.cpp
-    ${OPENGL_DIR}/libGL/*.h
-    ${OPENGL_DIR}/libGL/*.hpp
-    ${OPENGL_DIR}/common/*.cpp
-    ${OPENGL_DIR}/common/*.h
-    ${OPENGL_DIR}/common/*.hpp
-    ${CMAKE_SOURCE_DIR}/include/GL/*.h
-)
-
 file(GLOB_RECURSE GLES2_LIST
     ${OPENGL_DIR}/libGLESv2/*.cpp
     ${OPENGL_DIR}/libGLESv2/*.h
@@ -1905,7 +1892,6 @@
     )
     list(APPEND OPENGL_COMPILER_LIST ${OPENGL_COMPILER_DIR}/ossource_win.cpp)
     list(APPEND EGL_LIST ${OPENGL_DIR}/libEGL/libEGL.rc)
-    list(APPEND GL32_LIST ${OPENGL_DIR}/libGL/libGL.rc)
     list(APPEND GLES2_LIST ${OPENGL_DIR}/libGLESv2/libGLESv2.rc)
     list(APPEND GLES_CM_LIST ${OPENGL_DIR}/libGLES_CM/libGLES_CM.rc)
 elseif(LINUX)
@@ -2013,18 +1999,6 @@
     )
 endif()
 
-if(BUILD_GL32)
-    add_library(libGL SHARED ${GL32_LIST})
-    set_target_properties(libGL PROPERTIES
-        INCLUDE_DIRECTORIES "${OPENGL_INCLUDE_DIR}"
-        FOLDER "OpenGL"
-        COMPILE_DEFINITIONS "GL_GLEXT_PROTOTYPES"
-        PREFIX ""
-    )
-    set_shared_library_export_map(libGL ${SOURCE_DIR}/OpenGL/libGL)
-    target_link_libraries(libGL SwiftShader ${Reactor} GLCompiler ${OS_LIBS})
-endif()
-
 if(BUILD_GLESv2)
     add_library(libGLESv2 SHARED ${GLES2_LIST})
     set_target_properties(libGLESv2 PROPERTIES
diff --git a/SwiftShader.sln b/SwiftShader.sln
index 5a11a15..990830b 100644
--- a/SwiftShader.sln
+++ b/SwiftShader.sln
@@ -206,13 +206,6 @@
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{B7E24D8E-6BE9-4DEF-A8B9-6A6E60CA60E9}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libGL", "src\OpenGL\libGL\libGL.vcxproj", "{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OGLSimpleCube", "tests\OGLSimpleCube\OGLSimpleCube.vcxproj", "{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}"
-	ProjectSection(ProjectDependencies) = postProject
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67} = {3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D3D9", "src\D3D9\D3D9.vcxproj", "{F18D5ABF-CA3A-4B74-BDB2-4A1957C86F18}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OGLES2ChameleonMan", "third_party\PowerVR_SDK\Examples\Advanced\ChameleonMan\OGLES2\Build\WindowsVC2010\OGLES2ChameleonMan.vcxproj", "{9CF4408B-9B08-481F-95DA-3DF0846DABE4}"
@@ -613,30 +606,6 @@
 		{235B1D85-E6B6-45E2-BA5D-5C60396428FF}.Release|Win32.Build.0 = Release|Win32
 		{235B1D85-E6B6-45E2-BA5D-5C60396428FF}.Release|x64.ActiveCfg = Release|x64
 		{235B1D85-E6B6-45E2-BA5D-5C60396428FF}.Release|x64.Build.0 = Release|x64
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}.Debug|Win32.ActiveCfg = Debug|Win32
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}.Debug|Win32.Build.0 = Debug|Win32
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}.Debug|x64.ActiveCfg = Debug|x64
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}.Debug|x64.Build.0 = Debug|x64
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}.Profile|Win32.ActiveCfg = Profile|Win32
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}.Profile|Win32.Build.0 = Profile|Win32
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}.Profile|x64.ActiveCfg = Profile|x64
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}.Profile|x64.Build.0 = Profile|x64
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}.Release|Win32.ActiveCfg = Release|Win32
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}.Release|Win32.Build.0 = Release|Win32
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}.Release|x64.ActiveCfg = Release|x64
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}.Release|x64.Build.0 = Release|x64
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}.Debug|Win32.ActiveCfg = Debug|Win32
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}.Debug|Win32.Build.0 = Debug|Win32
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}.Debug|x64.ActiveCfg = Debug|x64
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}.Debug|x64.Build.0 = Debug|x64
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}.Profile|Win32.ActiveCfg = Release|Win32
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}.Profile|Win32.Build.0 = Release|Win32
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}.Profile|x64.ActiveCfg = Release|x64
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}.Profile|x64.Build.0 = Release|x64
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}.Release|Win32.ActiveCfg = Release|Win32
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}.Release|Win32.Build.0 = Release|Win32
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}.Release|x64.ActiveCfg = Release|x64
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}.Release|x64.Build.0 = Release|x64
 		{F18D5ABF-CA3A-4B74-BDB2-4A1957C86F18}.Debug|Win32.ActiveCfg = Debug|Win32
 		{F18D5ABF-CA3A-4B74-BDB2-4A1957C86F18}.Debug|Win32.Build.0 = Debug|Win32
 		{F18D5ABF-CA3A-4B74-BDB2-4A1957C86F18}.Debug|x64.ActiveCfg = Debug|x64
@@ -846,8 +815,6 @@
 		{92940255-AB4B-42FB-A2C4-0FAB19C3C48A} = {D33114D7-E582-4D61-B27D-FAB0297C43FF}
 		{235B1D85-E6B6-45E2-BA5D-5C60396428FF} = {D33114D7-E582-4D61-B27D-FAB0297C43FF}
 		{B7E24D8E-6BE9-4DEF-A8B9-6A6E60CA60E9} = {ED25C308-5BDB-43A7-BED6-C2C059FC2D7D}
-		{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67} = {D33114D7-E582-4D61-B27D-FAB0297C43FF}
-		{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747} = {ED25C308-5BDB-43A7-BED6-C2C059FC2D7D}
 		{9CF4408B-9B08-481F-95DA-3DF0846DABE4} = {ED25C308-5BDB-43A7-BED6-C2C059FC2D7D}
 		{9DAFEE32-19F6-4410-AA09-2B564FB86F62} = {ED25C308-5BDB-43A7-BED6-C2C059FC2D7D}
 		{AB1EB229-D86C-41B3-8E20-7A7E1FF5DDF5} = {ED25C308-5BDB-43A7-BED6-C2C059FC2D7D}
diff --git a/src/OpenGL/libGL/Buffer.cpp b/src/OpenGL/libGL/Buffer.cpp
deleted file mode 100644
index 19942f8..0000000
--- a/src/OpenGL/libGL/Buffer.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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.
-
-// Buffer.cpp: Implements the Buffer class, representing storage of vertex and/or
-// index data. Implements GL buffer objects and related functionality.
-
-#include "Buffer.h"
-
-#include "main.h"
-#include "VertexDataManager.h"
-#include "IndexDataManager.h"
-
-namespace gl
-{
-
-Buffer::Buffer(GLuint name) : NamedObject(name)
-{
-	mContents = 0;
-	mSize = 0;
-	mUsage = GL_DYNAMIC_DRAW;
-}
-
-Buffer::~Buffer()
-{
-	if(mContents)
-	{
-		mContents->destruct();
-	}
-}
-
-void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
-{
-	if(mContents)
-	{
-		mContents->destruct();
-		mContents = 0;
-	}
-
-	mSize = size;
-	mUsage = usage;
-
-	if(size > 0)
-	{
-		const int padding = 1024;   // For SIMD processing of vertices
-		mContents = new sw::Resource(size + padding);
-
-		if(!mContents)
-		{
-			return error(GL_OUT_OF_MEMORY);
-		}
-
-		if(data)
-		{
-			memcpy((void*)mContents->data(), data, size);
-		}
-	}
-}
-
-void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
-{
-	if(mContents)
-	{
-		char *buffer = (char*)mContents->lock(sw::PUBLIC);
-		memcpy(buffer + offset, data, size);
-		mContents->unlock();
-	}
-}
-
-sw::Resource *Buffer::getResource()
-{
-	return mContents;
-}
-
-}
diff --git a/src/OpenGL/libGL/Buffer.h b/src/OpenGL/libGL/Buffer.h
deleted file mode 100644
index db9c9ce..0000000
--- a/src/OpenGL/libGL/Buffer.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.
-
-// Buffer.h: Defines the Buffer class, representing storage of vertex and/or
-// index data. Implements GL buffer objects and related functionality.
-
-#ifndef LIBGL_BUFFER_H_
-#define LIBGL_BUFFER_H_
-
-#include "common/Object.hpp"
-#include "Common/Resource.hpp"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-#include <cstddef>
-#include <vector>
-
-namespace gl
-{
-class Buffer : public NamedObject
-{
-public:
-	explicit Buffer(GLuint name);
-
-	virtual ~Buffer();
-
-	void bufferData(const void *data, GLsizeiptr size, GLenum usage);
-	void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
-
-	const void *data() { return mContents ? mContents->data() : 0; }
-	size_t size() const { return mSize; }
-	GLenum usage() const { return mUsage; }
-
-	sw::Resource *getResource();
-
-private:
-	sw::Resource *mContents;
-	size_t mSize;
-	GLenum mUsage;
-};
-
-}
-
-#endif   // LIBGL_BUFFER_H_
diff --git a/src/OpenGL/libGL/Context.cpp b/src/OpenGL/libGL/Context.cpp
deleted file mode 100644
index 37f9703..0000000
--- a/src/OpenGL/libGL/Context.cpp
+++ /dev/null
@@ -1,3610 +0,0 @@
-// 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.
-
-// Context.cpp: Implements the gl::Context class, managing all GL state and performing
-// rendering operations.
-
-#include "Context.h"
-
-#include "main.h"
-#include "mathutil.h"
-#include "utilities.h"
-#include "ResourceManager.h"
-#include "Buffer.h"
-#include "Fence.h"
-#include "Framebuffer.h"
-#include "Program.h"
-#include "Query.h"
-#include "Renderbuffer.h"
-#include "Shader.h"
-#include "Texture.h"
-#include "VertexDataManager.h"
-#include "IndexDataManager.h"
-#include "Display.h"
-#include "Surface.h"
-#include "Common/Half.hpp"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-namespace gl
-{
-Context::Context(const Context *shareContext)
-	: modelView(32),
-	  projection(2)
-{
-	sw::Context *context = new sw::Context();
-	device = new gl::Device(context);
-
-	setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-
-	mState.depthClearValue = 1.0f;
-	mState.stencilClearValue = 0;
-
-	mState.cullFaceEnabled = false;
-	mState.cullMode = GL_BACK;
-	mState.frontFace = GL_CCW;
-	mState.depthTestEnabled = false;
-	mState.depthFunc = GL_LESS;
-	mState.blendEnabled = false;
-	mState.sourceBlendRGB = GL_ONE;
-	mState.sourceBlendAlpha = GL_ONE;
-	mState.destBlendRGB = GL_ZERO;
-	mState.destBlendAlpha = GL_ZERO;
-	mState.blendEquationRGB = GL_FUNC_ADD;
-	mState.blendEquationAlpha = GL_FUNC_ADD;
-	mState.blendColor.red = 0;
-	mState.blendColor.green = 0;
-	mState.blendColor.blue = 0;
-	mState.blendColor.alpha = 0;
-	mState.stencilTestEnabled = false;
-	mState.stencilFunc = GL_ALWAYS;
-	mState.stencilRef = 0;
-	mState.stencilMask = -1;
-	mState.stencilWritemask = -1;
-	mState.stencilBackFunc = GL_ALWAYS;
-	mState.stencilBackRef = 0;
-	mState.stencilBackMask = - 1;
-	mState.stencilBackWritemask = -1;
-	mState.stencilFail = GL_KEEP;
-	mState.stencilPassDepthFail = GL_KEEP;
-	mState.stencilPassDepthPass = GL_KEEP;
-	mState.stencilBackFail = GL_KEEP;
-	mState.stencilBackPassDepthFail = GL_KEEP;
-	mState.stencilBackPassDepthPass = GL_KEEP;
-	mState.polygonOffsetFillEnabled = false;
-	mState.polygonOffsetFactor = 0.0f;
-	mState.polygonOffsetUnits = 0.0f;
-	mState.sampleAlphaToCoverageEnabled = false;
-	mState.sampleCoverageEnabled = false;
-	mState.sampleCoverageValue = 1.0f;
-	mState.sampleCoverageInvert = false;
-	mState.scissorTestEnabled = false;
-	mState.ditherEnabled = true;
-	mState.generateMipmapHint = GL_DONT_CARE;
-	mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
-	mState.colorLogicOpEnabled = false;
-	mState.logicalOperation = GL_COPY;
-
-	mState.lineWidth = 1.0f;
-
-	mState.viewportX = 0;
-	mState.viewportY = 0;
-	mState.viewportWidth = 0;
-	mState.viewportHeight = 0;
-	mState.zNear = 0.0f;
-	mState.zFar = 1.0f;
-
-	mState.scissorX = 0;
-	mState.scissorY = 0;
-	mState.scissorWidth = 0;
-	mState.scissorHeight = 0;
-
-	mState.colorMaskRed = true;
-	mState.colorMaskGreen = true;
-	mState.colorMaskBlue = true;
-	mState.colorMaskAlpha = true;
-	mState.depthMask = true;
-
-	if(shareContext)
-	{
-		mResourceManager = shareContext->mResourceManager;
-		mResourceManager->addRef();
-	}
-	else
-	{
-		mResourceManager = new ResourceManager();
-	}
-
-	// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
-	// and cube map texture state vectors respectively associated with them.
-	// In order that access to these initial textures not be lost, they are treated as texture
-	// objects all of whose names are 0.
-
-	mTexture2DZero = new Texture2D(0);
-	mProxyTexture2DZero = new Texture2D(0);
-	mTextureCubeMapZero = new TextureCubeMap(0);
-
-	mState.activeSampler = 0;
-	bindArrayBuffer(0);
-	bindElementArrayBuffer(0);
-	bindTextureCubeMap(0);
-	bindTexture2D(0);
-	bindReadFramebuffer(0);
-	bindDrawFramebuffer(0);
-	bindRenderbuffer(0);
-
-	mState.currentProgram = 0;
-
-	mState.packAlignment = 4;
-	mState.unpackAlignment = 4;
-
-	mVertexDataManager = nullptr;
-	mIndexDataManager = nullptr;
-
-	mInvalidEnum = false;
-	mInvalidValue = false;
-	mInvalidOperation = false;
-	mOutOfMemory = false;
-	mInvalidFramebufferOperation = false;
-
-	mHasBeenCurrent = false;
-
-	markAllStateDirty();
-
-	matrixMode = GL_MODELVIEW;
-
-	listMode = 0;
-	//memset(displayList, 0, sizeof(displayList));
-	listIndex = 0;
-	list = 0;
-	firstFreeIndex = 1;
-
-	clientTexture = GL_TEXTURE0;
-
-	drawing = false;
-	drawMode = 0;   // FIXME
-
-	mState.vertexAttribute[sw::Color0].mCurrentValue[0] = 1.0f;
-	mState.vertexAttribute[sw::Color0].mCurrentValue[1] = 1.0f;
-	mState.vertexAttribute[sw::Color0].mCurrentValue[2] = 1.0f;
-	mState.vertexAttribute[sw::Color0].mCurrentValue[3] = 1.0f;
-	mState.vertexAttribute[sw::Normal].mCurrentValue[0] = 0.0f;
-	mState.vertexAttribute[sw::Normal].mCurrentValue[1] = 0.0f;
-	mState.vertexAttribute[sw::Normal].mCurrentValue[2] = 1.0f;
-	mState.vertexAttribute[sw::Normal].mCurrentValue[3] = 0.0f;
-	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0] = 0.0f;
-	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1] = 0.0f;
-	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2] = 0.0f;
-	mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3] = 1.0f;
-	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0] = 0.0f;
-	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1] = 0.0f;
-	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2] = 0.0f;
-	mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3] = 1.0f;
-
-	for(int i = 0; i < 8; i++)
-	{
-		envEnable[i] = true;
-	}
-}
-
-Context::~Context()
-{
-	if(mState.currentProgram != 0)
-	{
-		Program *programObject = mResourceManager->getProgram(mState.currentProgram);
-		if(programObject)
-		{
-			programObject->release();
-		}
-		mState.currentProgram = 0;
-	}
-
-	while(!mFramebufferNameSpace.empty())
-	{
-		deleteFramebuffer(mFramebufferNameSpace.firstName());
-	}
-
-	while(!mFenceNameSpace.empty())
-	{
-		deleteFence(mFenceNameSpace.firstName());
-	}
-
-	while(!mQueryNameSpace.empty())
-	{
-		deleteQuery(mQueryNameSpace.firstName());
-	}
-
-	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
-	{
-		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
-		{
-			mState.samplerTexture[type][sampler] = nullptr;
-		}
-	}
-
-	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-	{
-		mState.vertexAttribute[i].mBoundBuffer = nullptr;
-	}
-
-	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
-	{
-		mState.activeQuery[i] = nullptr;
-	}
-
-	mState.arrayBuffer = nullptr;
-	mState.elementArrayBuffer = nullptr;
-	mState.renderbuffer = nullptr;
-
-	mTexture2DZero = nullptr;
-	mProxyTexture2DZero = nullptr;
-	mTextureCubeMapZero = nullptr;
-
-	delete mVertexDataManager;
-	delete mIndexDataManager;
-
-	mResourceManager->release();
-	delete device;
-}
-
-void Context::makeCurrent(Surface *surface)
-{
-	if(!mHasBeenCurrent)
-	{
-		mVertexDataManager = new VertexDataManager(this);
-		mIndexDataManager = new IndexDataManager();
-
-		mState.viewportX = 0;
-		mState.viewportY = 0;
-		mState.viewportWidth = surface->getWidth();
-		mState.viewportHeight = surface->getHeight();
-
-		mState.scissorX = 0;
-		mState.scissorY = 0;
-		mState.scissorWidth = surface->getWidth();
-		mState.scissorHeight = surface->getHeight();
-
-		mHasBeenCurrent = true;
-	}
-
-	// Wrap the existing resources into GL objects and assign them to the '0' names
-	Image *defaultRenderTarget = surface->getRenderTarget();
-	Image *depthStencil = surface->getDepthStencil();
-
-	Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
-	DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
-	Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
-
-	setFramebufferZero(framebufferZero);
-
-	if(defaultRenderTarget)
-	{
-		defaultRenderTarget->release();
-	}
-
-	if(depthStencil)
-	{
-		depthStencil->release();
-	}
-
-	markAllStateDirty();
-}
-
-// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
-void Context::markAllStateDirty()
-{
-	mAppliedProgramSerial = 0;
-
-	mDepthStateDirty = true;
-	mMaskStateDirty = true;
-	mBlendStateDirty = true;
-	mStencilStateDirty = true;
-	mPolygonOffsetStateDirty = true;
-	mSampleStateDirty = true;
-	mDitherStateDirty = true;
-	mFrontFaceDirty = true;
-	mColorLogicOperatorDirty = true;
-}
-
-void Context::setClearColor(float red, float green, float blue, float alpha)
-{
-	mState.colorClearValue.red = red;
-	mState.colorClearValue.green = green;
-	mState.colorClearValue.blue = blue;
-	mState.colorClearValue.alpha = alpha;
-}
-
-void Context::setClearDepth(float depth)
-{
-	mState.depthClearValue = depth;
-}
-
-void Context::setClearStencil(int stencil)
-{
-	mState.stencilClearValue = stencil;
-}
-
-void Context::setCullFaceEnabled(bool enabled)
-{
-	mState.cullFaceEnabled = enabled;
-}
-
-bool Context::isCullFaceEnabled() const
-{
-	return mState.cullFaceEnabled;
-}
-
-void Context::setCullMode(GLenum mode)
-{
-   mState.cullMode = mode;
-}
-
-void Context::setFrontFace(GLenum front)
-{
-	if(mState.frontFace != front)
-	{
-		mState.frontFace = front;
-		mFrontFaceDirty = true;
-	}
-}
-
-void Context::setDepthTestEnabled(bool enabled)
-{
-	if(mState.depthTestEnabled != enabled)
-	{
-		mState.depthTestEnabled = enabled;
-		mDepthStateDirty = true;
-	}
-}
-
-bool Context::isDepthTestEnabled() const
-{
-	return mState.depthTestEnabled;
-}
-
-void Context::setDepthFunc(GLenum depthFunc)
-{
-	if(mState.depthFunc != depthFunc)
-	{
-		mState.depthFunc = depthFunc;
-		mDepthStateDirty = true;
-	}
-}
-
-void Context::setDepthRange(float zNear, float zFar)
-{
-	mState.zNear = zNear;
-	mState.zFar = zFar;
-}
-
-void Context::setBlendEnabled(bool enabled)
-{
-	if(mState.blendEnabled != enabled)
-	{
-		mState.blendEnabled = enabled;
-		mBlendStateDirty = true;
-	}
-}
-
-bool Context::isBlendEnabled() const
-{
-	return mState.blendEnabled;
-}
-
-void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
-{
-	if(mState.sourceBlendRGB != sourceRGB ||
-	   mState.sourceBlendAlpha != sourceAlpha ||
-	   mState.destBlendRGB != destRGB ||
-	   mState.destBlendAlpha != destAlpha)
-	{
-		mState.sourceBlendRGB = sourceRGB;
-		mState.destBlendRGB = destRGB;
-		mState.sourceBlendAlpha = sourceAlpha;
-		mState.destBlendAlpha = destAlpha;
-		mBlendStateDirty = true;
-	}
-}
-
-void Context::setBlendColor(float red, float green, float blue, float alpha)
-{
-	if(mState.blendColor.red != red ||
-	   mState.blendColor.green != green ||
-	   mState.blendColor.blue != blue ||
-	   mState.blendColor.alpha != alpha)
-	{
-		mState.blendColor.red = red;
-		mState.blendColor.green = green;
-		mState.blendColor.blue = blue;
-		mState.blendColor.alpha = alpha;
-		mBlendStateDirty = true;
-	}
-}
-
-void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
-{
-	if(mState.blendEquationRGB != rgbEquation ||
-	   mState.blendEquationAlpha != alphaEquation)
-	{
-		mState.blendEquationRGB = rgbEquation;
-		mState.blendEquationAlpha = alphaEquation;
-		mBlendStateDirty = true;
-	}
-}
-
-void Context::setStencilTestEnabled(bool enabled)
-{
-	if(mState.stencilTestEnabled != enabled)
-	{
-		mState.stencilTestEnabled = enabled;
-		mStencilStateDirty = true;
-	}
-}
-
-bool Context::isStencilTestEnabled() const
-{
-	return mState.stencilTestEnabled;
-}
-
-void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
-{
-	if(mState.stencilFunc != stencilFunc ||
-	   mState.stencilRef != stencilRef ||
-	   mState.stencilMask != stencilMask)
-	{
-		mState.stencilFunc = stencilFunc;
-		mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
-		mState.stencilMask = stencilMask;
-		mStencilStateDirty = true;
-	}
-}
-
-void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
-{
-	if(mState.stencilBackFunc != stencilBackFunc ||
-	   mState.stencilBackRef != stencilBackRef ||
-	   mState.stencilBackMask != stencilBackMask)
-	{
-		mState.stencilBackFunc = stencilBackFunc;
-		mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
-		mState.stencilBackMask = stencilBackMask;
-		mStencilStateDirty = true;
-	}
-}
-
-void Context::setStencilWritemask(GLuint stencilWritemask)
-{
-	if(mState.stencilWritemask != stencilWritemask)
-	{
-		mState.stencilWritemask = stencilWritemask;
-		mStencilStateDirty = true;
-	}
-}
-
-void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
-{
-	if(mState.stencilBackWritemask != stencilBackWritemask)
-	{
-		mState.stencilBackWritemask = stencilBackWritemask;
-		mStencilStateDirty = true;
-	}
-}
-
-void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
-{
-	if(mState.stencilFail != stencilFail ||
-	   mState.stencilPassDepthFail != stencilPassDepthFail ||
-	   mState.stencilPassDepthPass != stencilPassDepthPass)
-	{
-		mState.stencilFail = stencilFail;
-		mState.stencilPassDepthFail = stencilPassDepthFail;
-		mState.stencilPassDepthPass = stencilPassDepthPass;
-		mStencilStateDirty = true;
-	}
-}
-
-void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
-{
-	if(mState.stencilBackFail != stencilBackFail ||
-	   mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
-	   mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
-	{
-		mState.stencilBackFail = stencilBackFail;
-		mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
-		mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
-		mStencilStateDirty = true;
-	}
-}
-
-void Context::setPolygonOffsetFillEnabled(bool enabled)
-{
-	if(mState.polygonOffsetFillEnabled != enabled)
-	{
-		mState.polygonOffsetFillEnabled = enabled;
-		mPolygonOffsetStateDirty = true;
-	}
-}
-
-bool Context::isPolygonOffsetFillEnabled() const
-{
-	return mState.polygonOffsetFillEnabled;
-}
-
-void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
-{
-	if(mState.polygonOffsetFactor != factor ||
-	   mState.polygonOffsetUnits != units)
-	{
-		mState.polygonOffsetFactor = factor;
-		mState.polygonOffsetUnits = units;
-		mPolygonOffsetStateDirty = true;
-	}
-}
-
-void Context::setSampleAlphaToCoverageEnabled(bool enabled)
-{
-	if(mState.sampleAlphaToCoverageEnabled != enabled)
-	{
-		mState.sampleAlphaToCoverageEnabled = enabled;
-		mSampleStateDirty = true;
-	}
-}
-
-bool Context::isSampleAlphaToCoverageEnabled() const
-{
-	return mState.sampleAlphaToCoverageEnabled;
-}
-
-void Context::setSampleCoverageEnabled(bool enabled)
-{
-	if(mState.sampleCoverageEnabled != enabled)
-	{
-		mState.sampleCoverageEnabled = enabled;
-		mSampleStateDirty = true;
-	}
-}
-
-bool Context::isSampleCoverageEnabled() const
-{
-	return mState.sampleCoverageEnabled;
-}
-
-void Context::setSampleCoverageParams(GLclampf value, bool invert)
-{
-	if(mState.sampleCoverageValue != value ||
-		mState.sampleCoverageInvert != invert)
-	{
-		mState.sampleCoverageValue = value;
-		mState.sampleCoverageInvert = invert;
-		mSampleStateDirty = true;
-	}
-}
-
-void Context::setScissorTestEnabled(bool enabled)
-{
-	mState.scissorTestEnabled = enabled;
-}
-
-bool Context::isScissorTestEnabled() const
-{
-	return mState.scissorTestEnabled;
-}
-
-void Context::setDitherEnabled(bool enabled)
-{
-	if(mState.ditherEnabled != enabled)
-	{
-		mState.ditherEnabled = enabled;
-		mDitherStateDirty = true;
-	}
-}
-
-bool Context::isDitherEnabled() const
-{
-	return mState.ditherEnabled;
-}
-
-void Context::setLineWidth(GLfloat width)
-{
-	mState.lineWidth = width;
-	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
-}
-
-void Context::setGenerateMipmapHint(GLenum hint)
-{
-	mState.generateMipmapHint = hint;
-}
-
-void Context::setFragmentShaderDerivativeHint(GLenum hint)
-{
-	mState.fragmentShaderDerivativeHint = hint;
-	// TODO: Propagate the hint to shader translator so we can write
-	// ddx, ddx_coarse, or ddx_fine depending on the hint.
-	// Ignore for now. It is valid for implementations to ignore hint.
-}
-
-void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
-{
-	mState.viewportX = x;
-	mState.viewportY = y;
-	mState.viewportWidth = width;
-	mState.viewportHeight = height;
-}
-
-void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
-{
-	mState.scissorX = x;
-	mState.scissorY = y;
-	mState.scissorWidth = width;
-	mState.scissorHeight = height;
-}
-
-void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
-{
-	if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
-	   mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
-	{
-		mState.colorMaskRed = red;
-		mState.colorMaskGreen = green;
-		mState.colorMaskBlue = blue;
-		mState.colorMaskAlpha = alpha;
-		mMaskStateDirty = true;
-	}
-}
-
-void Context::setDepthMask(bool mask)
-{
-	if(mState.depthMask != mask)
-	{
-		mState.depthMask = mask;
-		mMaskStateDirty = true;
-	}
-}
-
-void Context::setActiveSampler(unsigned int active)
-{
-	mState.activeSampler = active;
-}
-
-GLuint Context::getReadFramebufferName() const
-{
-	return mState.readFramebuffer;
-}
-
-GLuint Context::getDrawFramebufferName() const
-{
-	return mState.drawFramebuffer;
-}
-
-GLuint Context::getRenderbufferName() const
-{
-	return mState.renderbuffer.name();
-}
-
-GLuint Context::getArrayBufferName() const
-{
-	return mState.arrayBuffer.name();
-}
-
-GLuint Context::getActiveQuery(GLenum target) const
-{
-	Query *queryObject = nullptr;
-
-	switch(target)
-	{
-	case GL_ANY_SAMPLES_PASSED:
-		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
-		break;
-	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
-		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
-		break;
-	default:
-		ASSERT(false);
-	}
-
-	if(queryObject)
-	{
-		return queryObject->name;
-	}
-
-	return 0;
-}
-
-void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
-{
-	mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
-}
-
-const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
-{
-	return mState.vertexAttribute[attribNum];
-}
-
-void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
-                                   GLsizei stride, const void *pointer)
-{
-	mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
-	mState.vertexAttribute[attribNum].mSize = size;
-	mState.vertexAttribute[attribNum].mType = type;
-	mState.vertexAttribute[attribNum].mNormalized = normalized;
-	mState.vertexAttribute[attribNum].mStride = stride;
-	mState.vertexAttribute[attribNum].mPointer = pointer;
-}
-
-const void *Context::getVertexAttribPointer(unsigned int attribNum) const
-{
-	return mState.vertexAttribute[attribNum].mPointer;
-}
-
-const VertexAttributeArray &Context::getVertexAttributes()
-{
-	return mState.vertexAttribute;
-}
-
-void Context::setPackAlignment(GLint alignment)
-{
-	mState.packAlignment = alignment;
-}
-
-GLint Context::getPackAlignment() const
-{
-	return mState.packAlignment;
-}
-
-void Context::setUnpackAlignment(GLint alignment)
-{
-	mState.unpackAlignment = alignment;
-}
-
-GLint Context::getUnpackAlignment() const
-{
-	return mState.unpackAlignment;
-}
-
-GLuint Context::createBuffer()
-{
-	return mResourceManager->createBuffer();
-}
-
-GLuint Context::createProgram()
-{
-	return mResourceManager->createProgram();
-}
-
-GLuint Context::createShader(GLenum type)
-{
-	return mResourceManager->createShader(type);
-}
-
-GLuint Context::createTexture()
-{
-	return mResourceManager->createTexture();
-}
-
-GLuint Context::createRenderbuffer()
-{
-	return mResourceManager->createRenderbuffer();
-}
-
-// Returns an unused framebuffer name
-GLuint Context::createFramebuffer()
-{
-	return mFramebufferNameSpace.allocate();
-}
-
-GLuint Context::createFence()
-{
-	return mFenceNameSpace.allocate(new Fence());
-}
-
-// Returns an unused query name
-GLuint Context::createQuery()
-{
-	return mQueryNameSpace.allocate();
-}
-
-void Context::deleteBuffer(GLuint buffer)
-{
-	if(mResourceManager->getBuffer(buffer))
-	{
-		detachBuffer(buffer);
-	}
-
-	mResourceManager->deleteBuffer(buffer);
-}
-
-void Context::deleteShader(GLuint shader)
-{
-	mResourceManager->deleteShader(shader);
-}
-
-void Context::deleteProgram(GLuint program)
-{
-	mResourceManager->deleteProgram(program);
-}
-
-void Context::deleteTexture(GLuint texture)
-{
-	if(mResourceManager->getTexture(texture))
-	{
-		detachTexture(texture);
-	}
-
-	mResourceManager->deleteTexture(texture);
-}
-
-void Context::deleteRenderbuffer(GLuint renderbuffer)
-{
-	if(mResourceManager->getRenderbuffer(renderbuffer))
-	{
-		detachRenderbuffer(renderbuffer);
-	}
-
-	mResourceManager->deleteRenderbuffer(renderbuffer);
-}
-
-void Context::deleteFramebuffer(GLuint framebuffer)
-{
-	Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
-
-	if(framebufferObject)
-	{
-		detachFramebuffer(framebuffer);
-
-		delete framebufferObject;
-	}
-}
-
-void Context::deleteFence(GLuint fence)
-{
-	Fence *fenceObject = mFenceNameSpace.remove(fence);
-
-	if(fenceObject)
-	{
-		delete fenceObject;
-	}
-}
-
-void Context::deleteQuery(GLuint query)
-{
-	Query *queryObject = mQueryNameSpace.remove(query);
-
-	if(queryObject)
-	{
-		queryObject->release();
-	}
-}
-
-Buffer *Context::getBuffer(GLuint handle)
-{
-	return mResourceManager->getBuffer(handle);
-}
-
-Shader *Context::getShader(GLuint handle)
-{
-	return mResourceManager->getShader(handle);
-}
-
-Program *Context::getProgram(GLuint handle)
-{
-	return mResourceManager->getProgram(handle);
-}
-
-Texture *Context::getTexture(GLuint handle)
-{
-	return mResourceManager->getTexture(handle);
-}
-
-Renderbuffer *Context::getRenderbuffer(GLuint handle)
-{
-	return mResourceManager->getRenderbuffer(handle);
-}
-
-Framebuffer *Context::getReadFramebuffer()
-{
-	return getFramebuffer(mState.readFramebuffer);
-}
-
-Framebuffer *Context::getDrawFramebuffer()
-{
-	return getFramebuffer(mState.drawFramebuffer);
-}
-
-void Context::bindArrayBuffer(unsigned int buffer)
-{
-	mResourceManager->checkBufferAllocation(buffer);
-
-	mState.arrayBuffer = getBuffer(buffer);
-}
-
-void Context::bindElementArrayBuffer(unsigned int buffer)
-{
-	mResourceManager->checkBufferAllocation(buffer);
-
-	mState.elementArrayBuffer = getBuffer(buffer);
-}
-
-void Context::bindTexture2D(GLuint texture)
-{
-	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
-
-	mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
-}
-
-void Context::bindTextureCubeMap(GLuint texture)
-{
-	mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
-
-	mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);
-}
-
-void Context::bindReadFramebuffer(GLuint framebuffer)
-{
-	if(!getFramebuffer(framebuffer))
-	{
-		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
-	}
-
-	mState.readFramebuffer = framebuffer;
-}
-
-void Context::bindDrawFramebuffer(GLuint framebuffer)
-{
-	if(!getFramebuffer(framebuffer))
-	{
-		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
-	}
-
-	mState.drawFramebuffer = framebuffer;
-}
-
-void Context::bindRenderbuffer(GLuint renderbuffer)
-{
-	mResourceManager->checkRenderbufferAllocation(renderbuffer);
-
-	mState.renderbuffer = getRenderbuffer(renderbuffer);
-}
-
-void Context::useProgram(GLuint program)
-{
-	GLuint priorProgram = mState.currentProgram;
-	mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
-
-	if(priorProgram != program)
-	{
-		Program *newProgram = mResourceManager->getProgram(program);
-		Program *oldProgram = mResourceManager->getProgram(priorProgram);
-
-		if(newProgram)
-		{
-			newProgram->addRef();
-		}
-
-		if(oldProgram)
-		{
-			oldProgram->release();
-		}
-	}
-}
-
-void Context::beginQuery(GLenum target, GLuint query)
-{
-	// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
-	// of zero, if the active query object name for <target> is non-zero (for the
-	// targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
-	// the active query for either target is non-zero), if <id> is the name of an
-	// existing query object whose type does not match <target>, or if <id> is the
-	// active query object name for any query type, the error INVALID_OPERATION is
-	// generated.
-
-	// Ensure no other queries are active
-	// NOTE: If other queries than occlusion are supported, we will need to check
-	// separately that:
-	//    a) The query ID passed is not the current active query for any target/type
-	//    b) There are no active queries for the requested target (and in the case
-	//       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
-	//       no query may be active for either if glBeginQuery targets either.
-	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
-	{
-		if(mState.activeQuery[i])
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-
-	QueryType qType;
-	switch(target)
-	{
-	case GL_ANY_SAMPLES_PASSED:
-		qType = QUERY_ANY_SAMPLES_PASSED;
-		break;
-	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
-		qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
-		break;
-	default:
-		ASSERT(false);
-	}
-
-	Query *queryObject = getQuery(query, true, target);
-
-	// Check that name was obtained with glGenQueries
-	if(!queryObject)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	// Check for type mismatch
-	if(queryObject->getType() != target)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	// Set query as active for specified target
-	mState.activeQuery[qType] = queryObject;
-
-	// Begin query
-	queryObject->begin();
-}
-
-void Context::endQuery(GLenum target)
-{
-	QueryType qType;
-
-	switch(target)
-	{
-	case GL_ANY_SAMPLES_PASSED:
-		qType = QUERY_ANY_SAMPLES_PASSED;
-		break;
-	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
-		qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
-		break;
-	default:
-		ASSERT(false);
-	}
-
-	Query *queryObject = mState.activeQuery[qType];
-
-	if(!queryObject)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	queryObject->end();
-
-	mState.activeQuery[qType] = nullptr;
-}
-
-void Context::setFramebufferZero(Framebuffer *buffer)
-{
-	delete mFramebufferNameSpace.remove(0);
-	mFramebufferNameSpace.insert(0, buffer);
-}
-
-void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
-{
-	Renderbuffer *renderbufferObject = mState.renderbuffer;
-	renderbufferObject->setStorage(renderbuffer);
-}
-
-Framebuffer *Context::getFramebuffer(unsigned int handle)
-{
-	return mFramebufferNameSpace.find(handle);
-}
-
-Fence *Context::getFence(unsigned int handle)
-{
-	return mFenceNameSpace.find(handle);
-}
-
-Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
-{
-	if(!mQueryNameSpace.isReserved(handle))
-	{
-		return nullptr;
-	}
-	else
-	{
-		Query *query = mQueryNameSpace.find(handle);
-		if(!query && create)
-		{
-			query = new Query(handle, type);
-			query->addRef();
-			mQueryNameSpace.insert(handle, query);
-		}
-
-		return query;
-	}
-}
-
-Buffer *Context::getArrayBuffer()
-{
-	return mState.arrayBuffer;
-}
-
-Buffer *Context::getElementArrayBuffer()
-{
-	return mState.elementArrayBuffer;
-}
-
-Program *Context::getCurrentProgram()
-{
-	return mResourceManager->getProgram(mState.currentProgram);
-}
-
-Texture2D *Context::getTexture2D(GLenum target)
-{
-	if(target == GL_TEXTURE_2D)
-	{
-		return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
-	}
-	else if(target == GL_PROXY_TEXTURE_2D)
-	{
-		return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, PROXY_TEXTURE_2D));
-	}
-	else UNREACHABLE(target);
-
-	return nullptr;
-}
-
-TextureCubeMap *Context::getTextureCubeMap()
-{
-	return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
-}
-
-Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
-{
-	GLuint texid = mState.samplerTexture[type][sampler].name();
-
-	if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
-	{
-		switch(type)
-		{
-		case TEXTURE_2D:       return mTexture2DZero;
-		case PROXY_TEXTURE_2D: return mProxyTexture2DZero;
-		case TEXTURE_CUBE:     return mTextureCubeMapZero;
-		default: UNREACHABLE(type);
-		}
-	}
-
-	return mState.samplerTexture[type][sampler];
-}
-
-bool Context::getBooleanv(GLenum pname, GLboolean *params)
-{
-	switch(pname)
-	{
-	case GL_SHADER_COMPILER:          *params = GL_TRUE;                             break;
-	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;         break;
-	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                    break;
-	case GL_COLOR_WRITEMASK:
-		params[0] = mState.colorMaskRed;
-		params[1] = mState.colorMaskGreen;
-		params[2] = mState.colorMaskBlue;
-		params[3] = mState.colorMaskAlpha;
-		break;
-	case GL_CULL_FACE:                *params = mState.cullFaceEnabled;              break;
-	case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;     break;
-	case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
-	case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;        break;
-	case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;           break;
-	case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;           break;
-	case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;             break;
-	case GL_BLEND:                    *params = mState.blendEnabled;                 break;
-	case GL_DITHER:                   *params = mState.ditherEnabled;                break;
-	default:
-		return false;
-	}
-
-	return true;
-}
-
-bool Context::getFloatv(GLenum pname, GLfloat *params)
-{
-	// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
-	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
-	// GetIntegerv as its native query function. As it would require conversion in any
-	// case, this should make no difference to the calling application.
-	switch(pname)
-	{
-	case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
-	case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
-	case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
-	case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
-	case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
-	case GL_ALIASED_LINE_WIDTH_RANGE:
-		params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
-		params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
-		break;
-	case GL_ALIASED_POINT_SIZE_RANGE:
-		params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
-		params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
-		break;
-	case GL_DEPTH_RANGE:
-		params[0] = mState.zNear;
-		params[1] = mState.zFar;
-		break;
-	case GL_COLOR_CLEAR_VALUE:
-		params[0] = mState.colorClearValue.red;
-		params[1] = mState.colorClearValue.green;
-		params[2] = mState.colorClearValue.blue;
-		params[3] = mState.colorClearValue.alpha;
-		break;
-	case GL_BLEND_COLOR:
-		params[0] = mState.blendColor.red;
-		params[1] = mState.blendColor.green;
-		params[2] = mState.blendColor.blue;
-		params[3] = mState.blendColor.alpha;
-		break;
-	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
-		*params = MAX_TEXTURE_MAX_ANISOTROPY;
-		break;
-	case GL_MODELVIEW_MATRIX:
-		for(int i = 0; i < 16; i++)
-		{
-			params[i] = modelView.current()[i % 4][i / 4];
-		}
-		break;
-	case GL_PROJECTION_MATRIX:
-		for(int i = 0; i < 16; i++)
-		{
-			params[i] = projection.current()[i % 4][i / 4];
-		}
-		break;
-	default:
-		return false;
-	}
-
-	return true;
-}
-
-bool Context::getIntegerv(GLenum pname, GLint *params)
-{
-	// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
-	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
-	// GetIntegerv as its native query function. As it would require conversion in any
-	// case, this should make no difference to the calling application. You may find it in
-	// Context::getFloatv.
-	switch(pname)
-	{
-	case GL_MAX_VERTEX_ATTRIBS:               *params = MAX_VERTEX_ATTRIBS;               break;
-	case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = MAX_VERTEX_UNIFORM_VECTORS;       break;
-	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:    *params = MAX_VERTEX_UNIFORM_VECTORS * 4;   break;   // FIXME: Verify
-	case GL_MAX_VARYING_VECTORS:              *params = MAX_VARYING_VECTORS;              break;
-	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
-	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;
-	case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = MAX_TEXTURE_IMAGE_UNITS;          break;
-	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = MAX_FRAGMENT_UNIFORM_VECTORS;     break;
-	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:  *params = MAX_VERTEX_UNIFORM_VECTORS * 4;   break;   // FIXME: Verify
-	case GL_MAX_RENDERBUFFER_SIZE:            *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break;
-	case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
-	case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
-	case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;
-	case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;
-//	case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
-	case GL_DRAW_FRAMEBUFFER_BINDING:         *params = mState.drawFramebuffer;               break;
-	case GL_READ_FRAMEBUFFER_BINDING:         *params = mState.readFramebuffer;               break;
-	case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.name();           break;
-	case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
-	case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
-	case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
-	case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
-	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:  *params = mState.fragmentShaderDerivativeHint; break;
-	case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
-	case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
-	case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
-	case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;
-	case GL_STENCIL_BACK_FUNC:                *params = mState.stencilBackFunc;               break;
-	case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                break;
-	case GL_STENCIL_BACK_VALUE_MASK:          *params = mState.stencilBackMask;               break;
-	case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
-	case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
-	case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
-	case GL_STENCIL_BACK_FAIL:                *params = mState.stencilBackFail;               break;
-	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.stencilBackPassDepthFail;      break;
-	case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.stencilBackPassDepthPass;      break;
-	case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
-	case GL_BLEND_SRC_RGB:                    *params = mState.sourceBlendRGB;                break;
-	case GL_BLEND_SRC_ALPHA:                  *params = mState.sourceBlendAlpha;              break;
-	case GL_BLEND_DST_RGB:                    *params = mState.destBlendRGB;                  break;
-	case GL_BLEND_DST_ALPHA:                  *params = mState.destBlendAlpha;                break;
-	case GL_BLEND_EQUATION_RGB:               *params = mState.blendEquationRGB;              break;
-	case GL_BLEND_EQUATION_ALPHA:             *params = mState.blendEquationAlpha;            break;
-	case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;
-	case GL_STENCIL_BACK_WRITEMASK:           *params = mState.stencilBackWritemask;          break;
-	case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
-	case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
-	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;      break;
-	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break;
-	case GL_MAX_ARRAY_TEXTURE_LAYERS:         *params = 0;                                    break;
-	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;       break;
-	case GL_MAX_SAMPLES:                      *params = IMPLEMENTATION_MAX_SAMPLES;           break;
-	case GL_SAMPLE_BUFFERS:
-	case GL_SAMPLES:
-		{
-			Framebuffer *framebuffer = getDrawFramebuffer();
-			int width, height, samples;
-
-			if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)
-			{
-				switch(pname)
-				{
-				case GL_SAMPLE_BUFFERS:
-					if(samples > 1)
-					{
-						*params = 1;
-					}
-					else
-					{
-						*params = 0;
-					}
-					break;
-				case GL_SAMPLES:
-					*params = samples;
-					break;
-				}
-			}
-			else
-			{
-				*params = 0;
-			}
-		}
-		break;
-	case GL_IMPLEMENTATION_COLOR_READ_TYPE:   *params = IMPLEMENTATION_COLOR_READ_TYPE;   break;
-	case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = IMPLEMENTATION_COLOR_READ_FORMAT; break;
-	case GL_MAX_VIEWPORT_DIMS:
-		{
-			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
-			params[0] = maxDimension;
-			params[1] = maxDimension;
-		}
-		break;
-	case GL_COMPRESSED_TEXTURE_FORMATS:
-		{
-			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
-			{
-				params[i] = compressedTextureFormats[i];
-			}
-		}
-		break;
-	case GL_VIEWPORT:
-		params[0] = mState.viewportX;
-		params[1] = mState.viewportY;
-		params[2] = mState.viewportWidth;
-		params[3] = mState.viewportHeight;
-		break;
-	case GL_SCISSOR_BOX:
-		params[0] = mState.scissorX;
-		params[1] = mState.scissorY;
-		params[2] = mState.scissorWidth;
-		params[3] = mState.scissorHeight;
-		break;
-	case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
-	case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
-	case GL_RED_BITS:
-	case GL_GREEN_BITS:
-	case GL_BLUE_BITS:
-	case GL_ALPHA_BITS:
-		{
-			Framebuffer *framebuffer = getDrawFramebuffer();
-			Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
-
-			if(colorbuffer)
-			{
-				switch(pname)
-				{
-				case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
-				case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
-				case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
-				case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
-				}
-			}
-			else
-			{
-				*params = 0;
-			}
-		}
-		break;
-	case GL_DEPTH_BITS:
-		{
-			Framebuffer *framebuffer = getDrawFramebuffer();
-			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
-
-			if(depthbuffer)
-			{
-				*params = depthbuffer->getDepthSize();
-			}
-			else
-			{
-				*params = 0;
-			}
-		}
-		break;
-	case GL_STENCIL_BITS:
-		{
-			Framebuffer *framebuffer = getDrawFramebuffer();
-			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
-
-			if(stencilbuffer)
-			{
-				*params = stencilbuffer->getStencilSize();
-			}
-			else
-			{
-				*params = 0;
-			}
-		}
-		break;
-	case GL_TEXTURE_BINDING_2D:
-		{
-			if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
-			{
-				error(GL_INVALID_OPERATION);
-				return false;
-			}
-
-			*params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
-		}
-		break;
-	case GL_TEXTURE_BINDING_CUBE_MAP:
-		{
-			if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
-			{
-				error(GL_INVALID_OPERATION);
-				return false;
-			}
-
-			*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
-		}
-		break;
-	default:
-		return false;
-	}
-
-	return true;
-}
-
-bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
-{
-	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
-	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
-	// to the fact that it is stored internally as a float, and so would require conversion
-	// if returned from Context::getIntegerv. Since this conversion is already implemented
-	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
-	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
-	// application.
-	switch(pname)
-	{
-	case GL_COMPRESSED_TEXTURE_FORMATS:
-		{
-			*type = GL_INT;
-			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
-		}
-		break;
-	case GL_SHADER_BINARY_FORMATS:
-		{
-			*type = GL_INT;
-			*numParams = 0;
-		}
-		break;
-	case GL_MAX_VERTEX_ATTRIBS:
-	case GL_MAX_VERTEX_UNIFORM_VECTORS:
-	case GL_MAX_VARYING_VECTORS:
-	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
-	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
-	case GL_MAX_TEXTURE_IMAGE_UNITS:
-	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
-	case GL_MAX_RENDERBUFFER_SIZE:
-	case GL_NUM_SHADER_BINARY_FORMATS:
-	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
-	case GL_ARRAY_BUFFER_BINDING:
-	case GL_FRAMEBUFFER_BINDING:
-	case GL_RENDERBUFFER_BINDING:
-	case GL_CURRENT_PROGRAM:
-	case GL_PACK_ALIGNMENT:
-	case GL_UNPACK_ALIGNMENT:
-	case GL_GENERATE_MIPMAP_HINT:
-	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
-	case GL_RED_BITS:
-	case GL_GREEN_BITS:
-	case GL_BLUE_BITS:
-	case GL_ALPHA_BITS:
-	case GL_DEPTH_BITS:
-	case GL_STENCIL_BITS:
-	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
-	case GL_CULL_FACE_MODE:
-	case GL_FRONT_FACE:
-	case GL_ACTIVE_TEXTURE:
-	case GL_STENCIL_FUNC:
-	case GL_STENCIL_VALUE_MASK:
-	case GL_STENCIL_REF:
-	case GL_STENCIL_FAIL:
-	case GL_STENCIL_PASS_DEPTH_FAIL:
-	case GL_STENCIL_PASS_DEPTH_PASS:
-	case GL_STENCIL_BACK_FUNC:
-	case GL_STENCIL_BACK_VALUE_MASK:
-	case GL_STENCIL_BACK_REF:
-	case GL_STENCIL_BACK_FAIL:
-	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
-	case GL_STENCIL_BACK_PASS_DEPTH_PASS:
-	case GL_DEPTH_FUNC:
-	case GL_BLEND_SRC_RGB:
-	case GL_BLEND_SRC_ALPHA:
-	case GL_BLEND_DST_RGB:
-	case GL_BLEND_DST_ALPHA:
-	case GL_BLEND_EQUATION_RGB:
-	case GL_BLEND_EQUATION_ALPHA:
-	case GL_STENCIL_WRITEMASK:
-	case GL_STENCIL_BACK_WRITEMASK:
-	case GL_STENCIL_CLEAR_VALUE:
-	case GL_SUBPIXEL_BITS:
-	case GL_MAX_TEXTURE_SIZE:
-	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
-	case GL_SAMPLE_BUFFERS:
-	case GL_SAMPLES:
-	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
-	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
-	case GL_TEXTURE_BINDING_2D:
-	case GL_TEXTURE_BINDING_CUBE_MAP:
-	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
-	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
-	case GL_MAX_ARRAY_TEXTURE_LAYERS:
-		{
-			*type = GL_INT;
-			*numParams = 1;
-		}
-		break;
-	case GL_MAX_SAMPLES:
-		{
-			*type = GL_INT;
-			*numParams = 1;
-		}
-		break;
-	case GL_MAX_VIEWPORT_DIMS:
-		{
-			*type = GL_INT;
-			*numParams = 2;
-		}
-		break;
-	case GL_VIEWPORT:
-	case GL_SCISSOR_BOX:
-		{
-			*type = GL_INT;
-			*numParams = 4;
-		}
-		break;
-	case GL_SHADER_COMPILER:
-	case GL_SAMPLE_COVERAGE_INVERT:
-	case GL_DEPTH_WRITEMASK:
-	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
-	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
-	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
-	case GL_SAMPLE_COVERAGE:
-	case GL_SCISSOR_TEST:
-	case GL_STENCIL_TEST:
-	case GL_DEPTH_TEST:
-	case GL_BLEND:
-	case GL_DITHER:
-		{
-			*type = GL_BOOL;
-			*numParams = 1;
-		}
-		break;
-	case GL_COLOR_WRITEMASK:
-		{
-			*type = GL_BOOL;
-			*numParams = 4;
-		}
-		break;
-	case GL_POLYGON_OFFSET_FACTOR:
-	case GL_POLYGON_OFFSET_UNITS:
-	case GL_SAMPLE_COVERAGE_VALUE:
-	case GL_DEPTH_CLEAR_VALUE:
-	case GL_LINE_WIDTH:
-		{
-			*type = GL_FLOAT;
-			*numParams = 1;
-		}
-		break;
-	case GL_ALIASED_LINE_WIDTH_RANGE:
-	case GL_ALIASED_POINT_SIZE_RANGE:
-	case GL_DEPTH_RANGE:
-		{
-			*type = GL_FLOAT;
-			*numParams = 2;
-		}
-		break;
-	case GL_COLOR_CLEAR_VALUE:
-	case GL_BLEND_COLOR:
-		{
-			*type = GL_FLOAT;
-			*numParams = 4;
-		}
-		break;
-	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
-		*type = GL_FLOAT;
-		*numParams = 1;
-		break;
-	default:
-		return false;
-	}
-
-	return true;
-}
-
-// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
-bool Context::applyRenderTarget()
-{
-	Framebuffer *framebuffer = getDrawFramebuffer();
-	int width, height, samples;
-
-	if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)
-	{
-		return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
-	}
-
-	Image *renderTarget = framebuffer->getRenderTarget();
-	device->setRenderTarget(0, renderTarget);
-	if(renderTarget) renderTarget->release();
-
-	Image *depthStencil = framebuffer->getDepthStencil();
-	device->setDepthStencilSurface(depthStencil);
-	if(depthStencil) depthStencil->release();
-
-	Viewport viewport;
-	float zNear = clamp01(mState.zNear);
-	float zFar = clamp01(mState.zFar);
-
-	viewport.x0 = mState.viewportX;
-	viewport.y0 = mState.viewportY;
-	viewport.width = mState.viewportWidth;
-	viewport.height = mState.viewportHeight;
-	viewport.minZ = zNear;
-	viewport.maxZ = zFar;
-
-	device->setViewport(viewport);
-
-	if(mState.scissorTestEnabled)
-	{
-		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
-		scissor.clip(0, 0, width, height);
-
-		device->setScissorRect(scissor);
-		device->setScissorEnable(true);
-	}
-	else
-	{
-		device->setScissorEnable(false);
-	}
-
-	Program *program = getCurrentProgram();
-
-	if(program)
-	{
-		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
-		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
-		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
-		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
-	}
-
-	return true;
-}
-
-// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
-void Context::applyState(GLenum drawMode)
-{
-	Framebuffer *framebuffer = getDrawFramebuffer();
-	bool frontFaceCCW = (mState.frontFace == GL_CCW);
-
-	if(mState.cullFaceEnabled)
-	{
-		device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace), frontFaceCCW);
-	}
-	else
-	{
-		device->setCullMode(sw::CULL_NONE, frontFaceCCW);
-	}
-
-	if(mDepthStateDirty)
-	{
-		if(mState.depthTestEnabled)
-		{
-			device->setDepthBufferEnable(true);
-			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
-		}
-		else
-		{
-			device->setDepthBufferEnable(false);
-		}
-
-		mDepthStateDirty = false;
-	}
-
-	if(mBlendStateDirty)
-	{
-		if(mState.blendEnabled)
-		{
-			device->setAlphaBlendEnable(true);
-			device->setSeparateAlphaBlendEnable(true);
-
-			device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
-
-			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
-			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
-			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
-
-			device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
-			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
-			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
-		}
-		else
-		{
-			device->setAlphaBlendEnable(false);
-		}
-
-		mBlendStateDirty = false;
-	}
-
-	if(mColorLogicOperatorDirty)
-	{
-		if(mState.colorLogicOpEnabled)
-		{
-			device->setColorLogicOpEnabled(true);
-			device->setLogicalOperation(es2sw::ConvertLogicalOperation(mState.logicalOperation));
-		}
-		else
-		{
-			device->setColorLogicOpEnabled(false);
-		}
-
-		mColorLogicOperatorDirty = false;
-	}
-
-	if(mStencilStateDirty || mFrontFaceDirty)
-	{
-		if(mState.stencilTestEnabled && framebuffer->hasStencil())
-		{
-			device->setStencilEnable(true);
-			device->setTwoSidedStencil(true);
-
-			if(mState.stencilWritemask != mState.stencilBackWritemask ||
-			   mState.stencilRef != mState.stencilBackRef ||
-			   mState.stencilMask != mState.stencilBackMask)
-			{
-				ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
-				return error(GL_INVALID_OPERATION);
-			}
-
-			// get the maximum size of the stencil ref
-			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
-			GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
-
-			if(mState.frontFace == GL_CCW)
-			{
-				device->setStencilWriteMask(mState.stencilWritemask);
-				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
-
-				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
-				device->setStencilMask(mState.stencilMask);
-
-				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
-				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
-				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
-
-				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
-				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
-
-				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
-				device->setStencilMaskCCW(mState.stencilBackMask);
-
-				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
-				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
-				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
-			}
-			else
-			{
-				device->setStencilWriteMaskCCW(mState.stencilWritemask);
-				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
-
-				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
-				device->setStencilMaskCCW(mState.stencilMask);
-
-				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
-				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
-				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
-
-				device->setStencilWriteMask(mState.stencilBackWritemask);
-				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
-
-				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
-				device->setStencilMask(mState.stencilBackMask);
-
-				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
-				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
-				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
-			}
-		}
-		else
-		{
-			device->setStencilEnable(false);
-		}
-
-		mStencilStateDirty = false;
-		mFrontFaceDirty = false;
-	}
-
-	if(mMaskStateDirty)
-	{
-		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
-		device->setDepthWriteEnable(mState.depthMask);
-
-		mMaskStateDirty = false;
-	}
-
-	if(mPolygonOffsetStateDirty)
-	{
-		if(mState.polygonOffsetFillEnabled)
-		{
-			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
-			if(depthbuffer)
-			{
-				device->setSlopeDepthBias(mState.polygonOffsetFactor);
-				float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
-				device->setDepthBias(depthBias);
-			}
-		}
-		else
-		{
-			device->setSlopeDepthBias(0);
-			device->setDepthBias(0);
-		}
-
-		mPolygonOffsetStateDirty = false;
-	}
-
-	if(mSampleStateDirty)
-	{
-		if(mState.sampleAlphaToCoverageEnabled)
-		{
-			device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
-		}
-		else
-		{
-			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
-		}
-
-		if(mState.sampleCoverageEnabled)
-		{
-			unsigned int mask = 0;
-			if(mState.sampleCoverageValue != 0)
-			{
-				int width, height, samples;
-				framebuffer->completeness(width, height, samples);
-
-				float threshold = 0.5f;
-
-				for(int i = 0; i < samples; i++)
-				{
-					mask <<= 1;
-
-					if((i + 1) * mState.sampleCoverageValue >= threshold)
-					{
-						threshold += 1.0f;
-						mask |= 1;
-					}
-				}
-			}
-
-			if(mState.sampleCoverageInvert)
-			{
-				mask = ~mask;
-			}
-
-			device->setMultiSampleMask(mask);
-		}
-		else
-		{
-			device->setMultiSampleMask(0xFFFFFFFF);
-		}
-
-		mSampleStateDirty = false;
-	}
-
-	if(mDitherStateDirty)
-	{
-	//	UNIMPLEMENTED();   // FIXME
-
-		mDitherStateDirty = false;
-	}
-}
-
-GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
-{
-	TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
-
-	GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
-	if(err != GL_NO_ERROR)
-	{
-		return err;
-	}
-
-	Program *program = getCurrentProgram();
-
-	device->resetInputStreams(false);
-
-	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-	{
-		if(program && program->getAttributeStream(i) == -1)
-		{
-			continue;
-		}
-
-		sw::Resource *resource = attributes[i].vertexBuffer;
-		const void *buffer = (char*)resource->data() + attributes[i].offset;
-
-		int stride = attributes[i].stride;
-
-		buffer = (char*)buffer + stride * base;
-
-		sw::Stream attribute(resource, buffer, stride);
-
-		attribute.type = attributes[i].type;
-		attribute.count = attributes[i].count;
-		attribute.normalized = attributes[i].normalized;
-
-		int stream = program ? program->getAttributeStream(i) : i;
-		device->setInputStream(stream, attribute);
-	}
-
-	return GL_NO_ERROR;
-}
-
-// Applies the indices and element array bindings
-GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
-{
-	GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
-
-	if(err == GL_NO_ERROR)
-	{
-		device->setIndexBuffer(indexInfo->indexBuffer);
-	}
-
-	return err;
-}
-
-// Applies the shaders and shader constants
-void Context::applyShaders()
-{
-	Program *programObject = getCurrentProgram();
-	if(!programObject)
-	{
-		device->setVertexShader(0);
-		device->setPixelShader(0);
-		return;
-	}
-	sw::VertexShader *vertexShader = programObject->getVertexShader();
-	sw::PixelShader *pixelShader = programObject->getPixelShader();
-
-	device->setVertexShader(vertexShader);
-	device->setPixelShader(pixelShader);
-
-	if(programObject->getSerial() != mAppliedProgramSerial)
-	{
-		programObject->dirtyAllUniforms();
-		mAppliedProgramSerial = programObject->getSerial();
-	}
-
-	programObject->applyUniforms();
-}
-
-void Context::applyTextures()
-{
-	applyTextures(sw::SAMPLER_PIXEL);
-	//applyTextures(sw::SAMPLER_VERTEX);
-}
-
-void Context::applyTextures(sw::SamplerType samplerType)
-{
-	Program *programObject = getCurrentProgram();
-
-	int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type
-
-	for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
-	{
-		int textureUnit = programObject ? programObject->getSamplerMapping(samplerType, samplerIndex) : samplerIndex;   // OpenGL texture image unit index
-
-		if(textureUnit != -1)
-		{
-			TextureType textureType = programObject ? programObject->getSamplerTextureType(samplerType, samplerIndex) : TEXTURE_2D;
-
-			Texture *texture = getSamplerTexture(textureUnit, textureType);
-
-			if(envEnable[samplerIndex] && texture->isSamplerComplete())
-			{
-				GLenum wrapS = texture->getWrapS();
-				GLenum wrapT = texture->getWrapT();
-				GLenum minFilter = texture->getMinFilter();
-				GLenum magFilter = texture->getMagFilter();
-				GLfloat maxAnisotropy = texture->getMaxAnisotropy();
-
-				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
-				device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
-
-				device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
-				device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
-				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
-
-				applyTexture(samplerType, samplerIndex, texture);
-
-				device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_MODULATE);
-				device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_TEXTURE);
-				device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
-				//device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
-
-				device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_MODULATE);
-				device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_TEXTURE);
-				device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
-				//device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
-
-				//device->setConstantColor(0, sw::Color<float>(0.0f, 0.0f, 0.0f, 0.0f));
-			}
-			else
-			{
-				applyTexture(samplerType, samplerIndex, nullptr);
-
-				device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);
-				device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
-				device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
-				//device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
-
-				device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);
-				device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
-				device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
-				//device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
-			}
-		}
-		else
-		{
-			applyTexture(samplerType, samplerIndex, nullptr);
-		}
-	}
-}
-
-void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
-{
-	Program *program = getCurrentProgram();
-	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
-	bool textureUsed = false;
-
-	if(type == sw::SAMPLER_PIXEL)
-	{
-		textureUsed = program ? program->getPixelShader()->usesSampler(index) : true;
-	}
-	else if(type == sw::SAMPLER_VERTEX)
-	{
-		textureUsed = program ? program->getVertexShader()->usesSampler(index) : false;
-	}
-	else UNREACHABLE(type);
-
-	sw::Resource *resource = nullptr;
-
-	if(baseTexture && textureUsed)
-	{
-		resource = baseTexture->getResource();
-	}
-
-	device->setTextureResource(sampler, resource);
-
-	if(baseTexture && textureUsed)
-	{
-		int topLevel = baseTexture->getTopLevel();
-
-		if(baseTexture->getTarget() == GL_TEXTURE_2D)
-		{
-			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
-
-			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
-			{
-				int surfaceLevel = mipmapLevel;
-
-				if(surfaceLevel < 0)
-				{
-					surfaceLevel = 0;
-				}
-				else if(surfaceLevel > topLevel)
-				{
-					surfaceLevel = topLevel;
-				}
-
-				Image *surface = texture->getImage(surfaceLevel);
-				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
-			}
-		}
-		else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)
-		{
-			for(int face = 0; face < 6; face++)
-			{
-				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
-
-				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
-				{
-					int surfaceLevel = mipmapLevel;
-
-					if(surfaceLevel < 0)
-					{
-						surfaceLevel = 0;
-					}
-					else if(surfaceLevel > topLevel)
-					{
-						surfaceLevel = topLevel;
-					}
-
-					Image *surface = cubeTexture->getImage(face, surfaceLevel);
-					device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
-				}
-			}
-		}
-		else UNIMPLEMENTED();
-	}
-	else
-	{
-		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
-	}
-}
-
-void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
-                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
-{
-	Framebuffer *framebuffer = getReadFramebuffer();
-	int framebufferWidth, framebufferHeight, framebufferSamples;
-
-	if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
-	{
-		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
-	}
-
-	if(getReadFramebufferName() != 0 && framebufferSamples != 0)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
-
-	// Sized query sanity check
-	if(bufSize)
-	{
-		int requiredSize = outputPitch * height;
-		if(requiredSize > *bufSize)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-
-	Image *renderTarget = framebuffer->getRenderTarget();
-
-	if(!renderTarget)
-	{
-		return error(GL_OUT_OF_MEMORY);
-	}
-
-	sw::Rect rect = {x, y, x + width, y + height};
-	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
-
-	unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
-	unsigned char *dest = (unsigned char*)pixels;
-	unsigned short *dest16 = (unsigned short*)pixels;
-	int inputPitch = (int)renderTarget->getPitch();
-
-	for(int j = 0; j < rect.y1 - rect.y0; j++)
-	{
-		if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
-		   format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
-		{
-			// Fast path for EXT_read_format_bgra, given an RGBA source buffer
-			// Note that buffers with no alpha go through the slow path below
-			memcpy(dest + j * outputPitch, source + j * inputPitch, (rect.x1 - rect.x0) * 4);
-		}
-		else
-		{
-			for(int i = 0; i < rect.x1 - rect.x0; i++)
-			{
-				float r;
-				float g;
-				float b;
-				float a;
-
-				switch(renderTarget->getInternalFormat())
-				{
-				case sw::FORMAT_R5G6B5:
-					{
-						unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch);
-
-						a = 1.0f;
-						b = (rgb & 0x001F) * (1.0f / 0x001F);
-						g = (rgb & 0x07E0) * (1.0f / 0x07E0);
-						r = (rgb & 0xF800) * (1.0f / 0xF800);
-					}
-					break;
-				case sw::FORMAT_A1R5G5B5:
-					{
-						unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch);
-
-						a = (argb & 0x8000) ? 1.0f : 0.0f;
-						b = (argb & 0x001F) * (1.0f / 0x001F);
-						g = (argb & 0x03E0) * (1.0f / 0x03E0);
-						r = (argb & 0x7C00) * (1.0f / 0x7C00);
-					}
-					break;
-				case sw::FORMAT_A8R8G8B8:
-					{
-						unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
-
-						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
-						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
-						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
-						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
-					}
-					break;
-				case sw::FORMAT_X8R8G8B8:
-					{
-						unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);
-
-						a = 1.0f;
-						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
-						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
-						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
-					}
-					break;
-				case sw::FORMAT_A2R10G10B10:
-					{
-						unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
-
-						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
-						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
-						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
-						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
-					}
-					break;
-				case sw::FORMAT_A32B32G32R32F:
-					{
-						r = *((float*)(source + 16 * i + j * inputPitch) + 0);
-						g = *((float*)(source + 16 * i + j * inputPitch) + 1);
-						b = *((float*)(source + 16 * i + j * inputPitch) + 2);
-						a = *((float*)(source + 16 * i + j * inputPitch) + 3);
-					}
-					break;
-				case sw::FORMAT_A16B16G16R16F:
-					{
-						r = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 0);
-						g = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 1);
-						b = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 2);
-						a = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 3);
-					}
-					break;
-				default:
-					UNIMPLEMENTED();   // FIXME
-					UNREACHABLE(renderTarget->getInternalFormat());
-				}
-
-				switch(format)
-				{
-				case GL_RGBA:
-					switch(type)
-					{
-					case GL_UNSIGNED_BYTE:
-						dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
-						dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
-						dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
-						dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
-						break;
-					default: UNREACHABLE(type);
-					}
-					break;
-				case GL_BGRA_EXT:
-					switch(type)
-					{
-					case GL_UNSIGNED_BYTE:
-						dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
-						dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
-						dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
-						dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
-						break;
-					case GL_UNSIGNED_SHORT_4_4_4_4_REV:
-						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
-						// this type is packed as follows:
-						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
-						//  --------------------------------------------------------------------------------
-						// |       4th         |        3rd         |        2nd        |   1st component   |
-						//  --------------------------------------------------------------------------------
-						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
-						dest16[i + j * outputPitch / sizeof(unsigned short)] =
-							((unsigned short)(15 * a + 0.5f) << 12)|
-							((unsigned short)(15 * r + 0.5f) << 8) |
-							((unsigned short)(15 * g + 0.5f) << 4) |
-							((unsigned short)(15 * b + 0.5f) << 0);
-						break;
-					case GL_UNSIGNED_SHORT_1_5_5_5_REV:
-						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
-						// this type is packed as follows:
-						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
-						//  --------------------------------------------------------------------------------
-						// | 4th |          3rd           |           2nd          |      1st component     |
-						//  --------------------------------------------------------------------------------
-						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
-						dest16[i + j * outputPitch / sizeof(unsigned short)] =
-							((unsigned short)(     a + 0.5f) << 15) |
-							((unsigned short)(31 * r + 0.5f) << 10) |
-							((unsigned short)(31 * g + 0.5f) << 5) |
-							((unsigned short)(31 * b + 0.5f) << 0);
-						break;
-					default: UNREACHABLE(type);
-					}
-					break;
-				case GL_RGB:   // IMPLEMENTATION_COLOR_READ_FORMAT
-					switch(type)
-					{
-					case GL_UNSIGNED_SHORT_5_6_5:   // IMPLEMENTATION_COLOR_READ_TYPE
-						dest16[i + j * outputPitch / sizeof(unsigned short)] =
-							((unsigned short)(31 * b + 0.5f) << 0) |
-							((unsigned short)(63 * g + 0.5f) << 5) |
-							((unsigned short)(31 * r + 0.5f) << 11);
-						break;
-					default: UNREACHABLE(type);
-					}
-					break;
-				default: UNREACHABLE(format);
-				}
-			}
-		}
-	}
-
-	renderTarget->unlock();
-	renderTarget->release();
-}
-
-void Context::clear(GLbitfield mask)
-{
-	Framebuffer *framebuffer = getDrawFramebuffer();
-
-	if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
-	{
-		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
-	}
-
-	if(!applyRenderTarget())
-	{
-		return;
-	}
-
-	float depth = clamp01(mState.depthClearValue);
-	int stencil = mState.stencilClearValue & 0x000000FF;
-
-	if(mask & GL_COLOR_BUFFER_BIT)
-	{
-		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
-		                        (mState.colorMaskGreen ? 0x2 : 0) |
-		                        (mState.colorMaskBlue ? 0x4 : 0) |
-		                        (mState.colorMaskAlpha ? 0x8 : 0);
-
-		if(rgbaMask != 0)
-		{
-			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
-		}
-	}
-
-	if(mask & GL_DEPTH_BUFFER_BIT)
-	{
-		if(mState.depthMask != 0)
-		{
-			device->clearDepth(depth);
-		}
-	}
-
-	if(mask & GL_STENCIL_BUFFER_BIT)
-	{
-		if(mState.stencilWritemask != 0)
-		{
-			device->clearStencil(stencil, mState.stencilWritemask);
-		}
-	}
-}
-
-void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
-{
-	if(!mState.currentProgram)
-	{
-		device->setProjectionMatrix(projection.current());
-		device->setViewMatrix(modelView.current());
-		device->setTextureMatrix(0, texture[0].current());
-		device->setTextureMatrix(1, texture[1].current());
-		device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false);
-		device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false);
-		device->setTexGen(0, sw::TEXGEN_NONE);
-		device->setTexGen(1, sw::TEXGEN_NONE);
-	}
-
-	PrimitiveType primitiveType;
-	int primitiveCount;
-
-	if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
-		return error(GL_INVALID_ENUM);
-
-	if(primitiveCount <= 0)
-	{
-		return;
-	}
-
-	if(!applyRenderTarget())
-	{
-		return;
-	}
-
-	applyState(mode);
-
-	GLenum err = applyVertexBuffer(0, first, count);
-	if(err != GL_NO_ERROR)
-	{
-		return error(err);
-	}
-
-	applyShaders();
-	applyTextures();
-
-	if(getCurrentProgram() && !getCurrentProgram()->validateSamplers(false))
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	if(!cullSkipsDraw(mode))
-	{
-		device->drawPrimitive(primitiveType, primitiveCount);
-	}
-}
-
-void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
-{
-	if(!mState.currentProgram)
-	{
-		return;
-	}
-
-	if(!indices && !mState.elementArrayBuffer)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	PrimitiveType primitiveType;
-	int primitiveCount;
-
-	if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
-		return error(GL_INVALID_ENUM);
-
-	if(primitiveCount <= 0)
-	{
-		return;
-	}
-
-	if(!applyRenderTarget())
-	{
-		return;
-	}
-
-	applyState(mode);
-
-	TranslatedIndexData indexInfo;
-	GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
-	if(err != GL_NO_ERROR)
-	{
-		return error(err);
-	}
-
-	GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
-	err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
-	if(err != GL_NO_ERROR)
-	{
-		return error(err);
-	}
-
-	applyShaders();
-	applyTextures();
-
-	if(!getCurrentProgram()->validateSamplers(false))
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	if(!cullSkipsDraw(mode))
-	{
-		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type));
-	}
-}
-
-void Context::finish()
-{
-	device->finish();
-}
-
-void Context::flush()
-{
-	// We don't queue anything without processing it as fast as possible
-}
-
-void Context::recordInvalidEnum()
-{
-	mInvalidEnum = true;
-}
-
-void Context::recordInvalidValue()
-{
-	mInvalidValue = true;
-}
-
-void Context::recordInvalidOperation()
-{
-	mInvalidOperation = true;
-}
-
-void Context::recordOutOfMemory()
-{
-	mOutOfMemory = true;
-}
-
-void Context::recordInvalidFramebufferOperation()
-{
-	mInvalidFramebufferOperation = true;
-}
-
-// Get one of the recorded errors and clear its flag, if any.
-GLenum Context::getError()
-{
-	if(mInvalidEnum)
-	{
-		mInvalidEnum = false;
-
-		return GL_INVALID_ENUM;
-	}
-
-	if(mInvalidValue)
-	{
-		mInvalidValue = false;
-
-		return GL_INVALID_VALUE;
-	}
-
-	if(mInvalidOperation)
-	{
-		mInvalidOperation = false;
-
-		return GL_INVALID_OPERATION;
-	}
-
-	if(mOutOfMemory)
-	{
-		mOutOfMemory = false;
-
-		return GL_OUT_OF_MEMORY;
-	}
-
-	if(mInvalidFramebufferOperation)
-	{
-		mInvalidFramebufferOperation = false;
-
-		return GL_INVALID_FRAMEBUFFER_OPERATION;
-	}
-
-	return GL_NO_ERROR;
-}
-
-int Context::getSupportedMultisampleCount(int requested)
-{
-	int supported = 0;
-
-	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
-	{
-		if(supported >= requested)
-		{
-			return supported;
-		}
-
-		supported = multisampleCount[i];
-	}
-
-	return supported;
-}
-
-void Context::detachBuffer(GLuint buffer)
-{
-	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
-	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
-
-	if(mState.arrayBuffer.name() == buffer)
-	{
-		mState.arrayBuffer = nullptr;
-	}
-
-	if(mState.elementArrayBuffer.name() == buffer)
-	{
-		mState.elementArrayBuffer = nullptr;
-	}
-
-	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
-	{
-		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
-		{
-			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
-		}
-	}
-}
-
-void Context::detachTexture(GLuint texture)
-{
-	// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
-	// rebound to texture object zero
-
-	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
-	{
-		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
-		{
-			if(mState.samplerTexture[type][sampler].name() == texture)
-			{
-				mState.samplerTexture[type][sampler] = nullptr;
-			}
-		}
-	}
-
-	// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
-	// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
-	// image was attached in the currently bound framebuffer.
-
-	Framebuffer *readFramebuffer = getReadFramebuffer();
-	Framebuffer *drawFramebuffer = getDrawFramebuffer();
-
-	if(readFramebuffer)
-	{
-		readFramebuffer->detachTexture(texture);
-	}
-
-	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
-	{
-		drawFramebuffer->detachTexture(texture);
-	}
-}
-
-void Context::detachFramebuffer(GLuint framebuffer)
-{
-	// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
-	// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
-
-	if(mState.readFramebuffer == framebuffer)
-	{
-		bindReadFramebuffer(0);
-	}
-
-	if(mState.drawFramebuffer == framebuffer)
-	{
-		bindDrawFramebuffer(0);
-	}
-}
-
-void Context::detachRenderbuffer(GLuint renderbuffer)
-{
-	// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
-	// had been executed with the target RENDERBUFFER and name of zero.
-
-	if(mState.renderbuffer.name() == renderbuffer)
-	{
-		bindRenderbuffer(0);
-	}
-
-	// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
-	// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
-	// point to which this image was attached in the currently bound framebuffer.
-
-	Framebuffer *readFramebuffer = getReadFramebuffer();
-	Framebuffer *drawFramebuffer = getDrawFramebuffer();
-
-	if(readFramebuffer)
-	{
-		readFramebuffer->detachRenderbuffer(renderbuffer);
-	}
-
-	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
-	{
-		drawFramebuffer->detachRenderbuffer(renderbuffer);
-	}
-}
-
-bool Context::cullSkipsDraw(GLenum drawMode)
-{
-	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
-}
-
-bool Context::isTriangleMode(GLenum drawMode)
-{
-	switch(drawMode)
-	{
-	case GL_TRIANGLES:
-	case GL_TRIANGLE_FAN:
-	case GL_TRIANGLE_STRIP:
-		return true;
-	case GL_POINTS:
-	case GL_LINES:
-	case GL_LINE_LOOP:
-	case GL_LINE_STRIP:
-		return false;
-	default: UNREACHABLE(drawMode);
-	}
-
-	return false;
-}
-
-void Context::setVertexAttrib(GLuint index, float x, float y, float z, float w)
-{
-	ASSERT(index < MAX_VERTEX_ATTRIBS);
-
-	mState.vertexAttribute[index].mCurrentValue[0] = x;
-	mState.vertexAttribute[index].mCurrentValue[1] = y;
-	mState.vertexAttribute[index].mCurrentValue[2] = z;
-	mState.vertexAttribute[index].mCurrentValue[3] = w;
-
-	mVertexDataManager->dirtyCurrentValue(index);
-}
-
-void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
-                              GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
-                              GLbitfield mask)
-{
-	Framebuffer *readFramebuffer = getReadFramebuffer();
-	Framebuffer *drawFramebuffer = getDrawFramebuffer();
-
-	int readBufferWidth, readBufferHeight, readBufferSamples;
-	int drawBufferWidth, drawBufferHeight, drawBufferSamples;
-
-	if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
-	   !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
-	{
-		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
-	}
-
-	if(drawBufferSamples > 1)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	sw::SliceRect sourceRect;
-	sw::SliceRect destRect;
-
-	if(srcX0 < srcX1)
-	{
-		sourceRect.x0 = srcX0;
-		sourceRect.x1 = srcX1;
-		destRect.x0 = dstX0;
-		destRect.x1 = dstX1;
-	}
-	else
-	{
-		sourceRect.x0 = srcX1;
-		destRect.x0 = dstX1;
-		sourceRect.x1 = srcX0;
-		destRect.x1 = dstX0;
-	}
-
-	if(srcY0 < srcY1)
-	{
-		sourceRect.y0 = srcY0;
-		destRect.y0 = dstY0;
-		sourceRect.y1 = srcY1;
-		destRect.y1 = dstY1;
-	}
-	else
-	{
-		sourceRect.y0 = srcY1;
-		destRect.y0 = dstY1;
-		sourceRect.y1 = srcY0;
-		destRect.y1 = dstY0;
-	}
-
-	sw::Rect sourceScissoredRect = sourceRect;
-	sw::Rect destScissoredRect = destRect;
-
-	if(mState.scissorTestEnabled)   // Only write to parts of the destination framebuffer which pass the scissor test
-	{
-		if(destRect.x0 < mState.scissorX)
-		{
-			int xDiff = mState.scissorX - destRect.x0;
-			destScissoredRect.x0 = mState.scissorX;
-			sourceScissoredRect.x0 += xDiff;
-		}
-
-		if(destRect.x1 > mState.scissorX + mState.scissorWidth)
-		{
-			int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);
-			destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;
-			sourceScissoredRect.x1 -= xDiff;
-		}
-
-		if(destRect.y0 < mState.scissorY)
-		{
-			int yDiff = mState.scissorY - destRect.y0;
-			destScissoredRect.y0 = mState.scissorY;
-			sourceScissoredRect.y0 += yDiff;
-		}
-
-		if(destRect.y1 > mState.scissorY + mState.scissorHeight)
-		{
-			int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);
-			destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;
-			sourceScissoredRect.y1 -= yDiff;
-		}
-	}
-
-	sw::Rect sourceTrimmedRect = sourceScissoredRect;
-	sw::Rect destTrimmedRect = destScissoredRect;
-
-	// The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
-	// the actual draw and read surfaces.
-	if(sourceTrimmedRect.x0 < 0)
-	{
-		int xDiff = 0 - sourceTrimmedRect.x0;
-		sourceTrimmedRect.x0 = 0;
-		destTrimmedRect.x0 += xDiff;
-	}
-
-	if(sourceTrimmedRect.x1 > readBufferWidth)
-	{
-		int xDiff = sourceTrimmedRect.x1 - readBufferWidth;
-		sourceTrimmedRect.x1 = readBufferWidth;
-		destTrimmedRect.x1 -= xDiff;
-	}
-
-	if(sourceTrimmedRect.y0 < 0)
-	{
-		int yDiff = 0 - sourceTrimmedRect.y0;
-		sourceTrimmedRect.y0 = 0;
-		destTrimmedRect.y0 += yDiff;
-	}
-
-	if(sourceTrimmedRect.y1 > readBufferHeight)
-	{
-		int yDiff = sourceTrimmedRect.y1 - readBufferHeight;
-		sourceTrimmedRect.y1 = readBufferHeight;
-		destTrimmedRect.y1 -= yDiff;
-	}
-
-	if(destTrimmedRect.x0 < 0)
-	{
-		int xDiff = 0 - destTrimmedRect.x0;
-		destTrimmedRect.x0 = 0;
-		sourceTrimmedRect.x0 += xDiff;
-	}
-
-	if(destTrimmedRect.x1 > drawBufferWidth)
-	{
-		int xDiff = destTrimmedRect.x1 - drawBufferWidth;
-		destTrimmedRect.x1 = drawBufferWidth;
-		sourceTrimmedRect.x1 -= xDiff;
-	}
-
-	if(destTrimmedRect.y0 < 0)
-	{
-		int yDiff = 0 - destTrimmedRect.y0;
-		destTrimmedRect.y0 = 0;
-		sourceTrimmedRect.y0 += yDiff;
-	}
-
-	if(destTrimmedRect.y1 > drawBufferHeight)
-	{
-		int yDiff = destTrimmedRect.y1 - drawBufferHeight;
-		destTrimmedRect.y1 = drawBufferHeight;
-		sourceTrimmedRect.y1 -= yDiff;
-	}
-
-	bool partialBufferCopy = false;
-
-	if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
-	   sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
-	   destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
-	   destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
-	   sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
-	{
-		partialBufferCopy = true;
-	}
-
-	bool blitRenderTarget = false;
-	bool blitDepthStencil = false;
-
-	if(mask & GL_COLOR_BUFFER_BIT)
-	{
-		const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
-		                           readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
-		const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
-		                           drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
-		if(!validReadType || !validDrawType ||
-		   readFramebuffer->getColorbuffer()->getInternalFormat() != drawFramebuffer->getColorbuffer()->getInternalFormat())
-		{
-			ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(partialBufferCopy && readBufferSamples > 1)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		blitRenderTarget = true;
-	}
-
-	if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
-	{
-		Renderbuffer *readDSBuffer = nullptr;
-		Renderbuffer *drawDSBuffer = nullptr;
-
-		// We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
-		// both a depth and stencil buffer, it will be the same buffer.
-
-		if(mask & GL_DEPTH_BUFFER_BIT)
-		{
-			if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
-			{
-				if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
-				   readFramebuffer->getDepthbuffer()->getInternalFormat() != drawFramebuffer->getDepthbuffer()->getInternalFormat())
-				{
-					return error(GL_INVALID_OPERATION);
-				}
-
-				blitDepthStencil = true;
-				readDSBuffer = readFramebuffer->getDepthbuffer();
-				drawDSBuffer = drawFramebuffer->getDepthbuffer();
-			}
-		}
-
-		if(mask & GL_STENCIL_BUFFER_BIT)
-		{
-			if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
-			{
-				if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
-				   readFramebuffer->getStencilbuffer()->getInternalFormat() != drawFramebuffer->getStencilbuffer()->getInternalFormat())
-				{
-					return error(GL_INVALID_OPERATION);
-				}
-
-				blitDepthStencil = true;
-				readDSBuffer = readFramebuffer->getStencilbuffer();
-				drawDSBuffer = drawFramebuffer->getStencilbuffer();
-			}
-		}
-
-		if(partialBufferCopy)
-		{
-			ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
-			return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted
-		}
-
-		if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
-		   (readDSBuffer && readDSBuffer->getSamples() > 1))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-
-	if(blitRenderTarget || blitDepthStencil)
-	{
-		if(blitRenderTarget)
-		{
-			Image *readRenderTarget = readFramebuffer->getRenderTarget();
-			Image *drawRenderTarget = drawFramebuffer->getRenderTarget();
-
-			bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
-
-			readRenderTarget->release();
-			drawRenderTarget->release();
-
-			if(!success)
-			{
-				ERR("BlitFramebufferANGLE failed.");
-				return;
-			}
-		}
-
-		if(blitDepthStencil)
-		{
-			bool success = device->stretchRect(readFramebuffer->getDepthStencil(), nullptr, drawFramebuffer->getDepthStencil(), nullptr, false);
-
-			if(!success)
-			{
-				ERR("BlitFramebufferANGLE failed.");
-				return;
-			}
-		}
-	}
-}
-
-void Context::setMatrixMode(GLenum mode)
-{
-	matrixMode = mode;
-}
-
-sw::MatrixStack &Context::currentMatrixStack()
-{
-	switch(matrixMode)
-	{
-	case GL_MODELVIEW:  return modelView;                     break;
-	case GL_PROJECTION: return projection;                    break;
-	case GL_TEXTURE:    return texture[mState.activeSampler]; break;
-	default:            UNREACHABLE(matrixMode); return modelView;      break;
-	}
-}
-
-void Context::loadIdentity()
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	currentMatrixStack().identity();
-}
-
-void Context::pushMatrix()
-{
-	//if(drawing)
-	//{
-	//    return error(GL_INVALID_OPERATION);
-	//}
-
-	if(!currentMatrixStack().push())
-	{
-		return error(GL_STACK_OVERFLOW);
-	}
-}
-
-void Context::popMatrix()
-{
-	//if(drawing)
-	//{
-	//    return error(GL_INVALID_OPERATION);
-	//}
-
-	if(!currentMatrixStack().pop())
-	{
-		return error(GL_STACK_OVERFLOW);
-	}
-}
-
-void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	currentMatrixStack().rotate(angle, x, y, z);
-}
-
-void Context::translate(GLfloat x, GLfloat y, GLfloat z)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	currentMatrixStack().translate(x, y, z);
-}
-
-void Context::scale(GLfloat x, GLfloat y, GLfloat z)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	currentMatrixStack().scale(x, y, z);
-}
-
-void Context::multiply(const GLdouble *m)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	currentMatrixStack().multiply(m);
-}
-
-void Context::multiply(const GLfloat *m)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	currentMatrixStack().multiply(m);
-}
-
-void Context::frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);
-}
-
-void Context::ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);
-}
-
-void Context::setLightingEnabled(bool enable)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	device->setLightingEnable(enable);
-}
-
-void Context::setFogEnabled(bool enable)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	device->setFogEnable(enable);
-}
-
-void Context::setAlphaTestEnabled(bool enable)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	device->setAlphaTestEnable(enable);
-}
-
-void Context::alphaFunc(GLenum func, GLclampf ref)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	switch(func)
-	{
-	case GL_NEVER:    device->setAlphaCompare(sw::ALPHA_NEVER);        break;
-	case GL_LESS:     device->setAlphaCompare(sw::ALPHA_LESS);         break;
-	case GL_EQUAL:    device->setAlphaCompare(sw::ALPHA_EQUAL);        break;
-	case GL_LEQUAL:   device->setAlphaCompare(sw::ALPHA_LESSEQUAL);    break;
-	case GL_GREATER:  device->setAlphaCompare(sw::ALPHA_GREATER);      break;
-	case GL_NOTEQUAL: device->setAlphaCompare(sw::ALPHA_NOTEQUAL);     break;
-	case GL_GEQUAL:   device->setAlphaCompare(sw::ALPHA_GREATEREQUAL); break;
-	case GL_ALWAYS:   device->setAlphaCompare(sw::ALPHA_ALWAYS);       break;
-	default: UNREACHABLE(func);
-	}
-
-	device->setAlphaReference(gl::clamp01(ref));
-}
-
-void Context::setTexture2DEnabled(bool enable)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	envEnable[mState.activeSampler] = enable;
-}
-
-void Context::setShadeModel(GLenum mode)
-{
-	//if(drawing)
-	//{
-	//    return error(GL_INVALID_OPERATION);
-	//}
-
-	switch(mode)
-	{
-	case GL_FLAT:   device->setShadingMode(sw::SHADING_FLAT);    break;
-	case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;
-	default: return error(GL_INVALID_ENUM);
-	}
-}
-
-void Context::setLightEnabled(int index, bool enable)
-{
-	device->setLightEnable(index, enable);
-}
-
-void Context::setNormalizeNormalsEnabled(bool enable)
-{
-	device->setNormalizeNormals(enable);
-}
-
-GLuint Context::genLists(GLsizei range)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION, 0);
-	}
-
-	int firstIndex = std::max(1u, firstFreeIndex);
-	for(; true; firstIndex++)
-	{
-		int empty = 0;
-		for(; empty < range; empty++)
-		{
-			if(displayList[firstIndex + empty] != 0)
-			{
-				break;
-			}
-		}
-
-		if(empty == range)
-		{
-			for(int i = firstIndex; i < firstIndex + range; i++)
-			{
-				displayList[i] = new DisplayList();
-			}
-
-			if(firstIndex == firstFreeIndex)
-			{
-				firstFreeIndex = firstIndex + range;
-			}
-
-			return firstIndex;
-		}
-	}
-
-	return 0;
-}
-
-void Context::newList(GLuint list, GLenum mode)
-{
-	if(drawing || listIndex != 0)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	ASSERT(!this->list);
-	this->list = new DisplayList();
-
-	listIndex = list;
-	listMode = mode;
-}
-
-void Context::endList()
-{
-	if(drawing || listIndex == 0)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	ASSERT(list);
-	delete displayList[listIndex];
-	displayList[listIndex] = list;
-	list = 0;
-
-	listIndex = 0;
-	listMode = 0;
-}
-
-void Context::callList(GLuint list)
-{
-	// As per GL specifications, if the list does not exist, it is ignored
-	if(displayList[list])
-	{
-		displayList[list]->call();
-	}
-}
-
-void Context::deleteList(GLuint list)
-{
-	delete displayList[list];
-	displayList[list] = 0;
-	displayList.erase(list);
-	firstFreeIndex = std::min(firstFreeIndex , list);
-}
-
-void Context::listCommand(Command *command)
-{
-	ASSERT(list);
-	list->list.push_back(command);
-
-	if(listMode == GL_COMPILE_AND_EXECUTE)
-	{
-		listMode = 0;
-		command->call();
-		listMode = GL_COMPILE_AND_EXECUTE;
-	}
-}
-
-void APIENTRY glVertexAttribArray(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);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
-		context->setVertexAttribArrayEnabled(index, ptr != 0);
-	}
-}
-
-void Context::captureAttribs()
-{
-	memcpy(clientAttribute, mState.vertexAttribute, sizeof(mState.vertexAttribute));
-}
-
-void Context::captureDrawArrays(GLenum mode, GLint first, GLsizei count)
-{
-	ASSERT(first == 0);   // FIXME: UNIMPLEMENTED!
-
-	for(GLuint i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-	{
-		GLint size = mState.vertexAttribute[i].mSize;
-		GLenum type = mState.vertexAttribute[i].mType;
-		GLboolean normalized = mState.vertexAttribute[i].mNormalized;
-		GLsizei stride = mState.vertexAttribute[i].mStride;
-		const GLvoid *pointer = mState.vertexAttribute[i].mPointer;
-
-		size_t length = count * mState.vertexAttribute[i].stride();
-
-		if(mState.vertexAttribute[i].mArrayEnabled)
-		{
-			ASSERT(pointer);   // FIXME: Add to condition?
-			const int padding = 1024;   // For SIMD processing of vertices   // FIXME: Still necessary?
-			void *buffer = new unsigned char[length + padding];
-			memcpy(buffer, pointer, length);
-
-			listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)buffer));
-		}
-		else
-		{
-			listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)0));
-		}
-	}
-}
-
-void Context::restoreAttribs()
-{
-	memcpy(mState.vertexAttribute, clientAttribute, sizeof(mState.vertexAttribute));
-}
-
-void Context::clientActiveTexture(GLenum texture)
-{
-	clientTexture = texture;
-}
-
-GLenum Context::getClientActiveTexture() const
-{
-	return clientTexture;
-}
-
-unsigned int Context::getActiveTexture() const
-{
-	return mState.activeSampler;
-}
-
-void Context::begin(GLenum mode)
-{
-	if(drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	drawing = true;
-	drawMode = mode;
-
-	vertex.clear();
-}
-
-void Context::position(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-	InVertex v;
-
-	v.P.x = x;
-	v.P.y = y;
-	v.P.z = z;
-	v.P.w = w;
-	v.C.x = mState.vertexAttribute[sw::Color0].mCurrentValue[0];
-	v.C.y = mState.vertexAttribute[sw::Color0].mCurrentValue[1];
-	v.C.z = mState.vertexAttribute[sw::Color0].mCurrentValue[2];
-	v.C.w = mState.vertexAttribute[sw::Color0].mCurrentValue[3];
-	v.N.x = mState.vertexAttribute[sw::Normal].mCurrentValue[0];
-	v.N.y = mState.vertexAttribute[sw::Normal].mCurrentValue[1];
-	v.N.z = mState.vertexAttribute[sw::Normal].mCurrentValue[2];
-	v.N.w = mState.vertexAttribute[sw::Normal].mCurrentValue[3];
-	v.T0.x = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0];
-	v.T0.y = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1];
-	v.T0.z = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2];
-	v.T0.w = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3];
-	v.T1.x = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0];
-	v.T1.y = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1];
-	v.T1.z = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2];
-	v.T1.w = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3];
-
-	vertex.push_back(v);
-}
-
-void Context::end()
-{
-	if(!drawing)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	device->setProjectionMatrix(projection.current());
-	device->setViewMatrix(modelView.current());
-	device->setTextureMatrix(0, texture[0].current());
-	device->setTextureMatrix(1, texture[1].current());
-	device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false);
-	device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false);
-
-	captureAttribs();
-
-	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-	{
-		mState.vertexAttribute[i].mArrayEnabled = false;
-	}
-
-	setVertexAttribState(sw::Position, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].P);
-	setVertexAttribState(sw::Normal, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].N);
-	setVertexAttribState(sw::Color0, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].C);
-	setVertexAttribState(sw::TexCoord0, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T0);
-	setVertexAttribState(sw::TexCoord1, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T1);
-
-	mState.vertexAttribute[sw::Position].mArrayEnabled = true;
-	mState.vertexAttribute[sw::Normal].mArrayEnabled = true;
-	mState.vertexAttribute[sw::Color0].mArrayEnabled = true;
-	mState.vertexAttribute[sw::TexCoord0].mArrayEnabled = true;
-	mState.vertexAttribute[sw::TexCoord1].mArrayEnabled = true;
-
-	applyState(drawMode);
-
-	GLenum err = applyVertexBuffer(0, 0, vertex.size());
-	if(err != GL_NO_ERROR)
-	{
-		return error(err);
-	}
-
-	applyTextures();
-
-	switch(drawMode)
-	{
-	case GL_POINTS:
-		UNIMPLEMENTED();
-		break;
-	case GL_LINES:
-		UNIMPLEMENTED();
-		break;
-	case GL_LINE_STRIP:
-		UNIMPLEMENTED();
-		break;
-	case GL_LINE_LOOP:
-		UNIMPLEMENTED();
-		break;
-	case GL_TRIANGLES:
-		UNIMPLEMENTED();
-		break;
-	case GL_TRIANGLE_STRIP:
-		device->drawPrimitive(DRAW_TRIANGLESTRIP, vertex.size() - 2);
-		break;
-	case GL_TRIANGLE_FAN:
-		UNIMPLEMENTED();
-		break;
-	case GL_QUADS:
-		UNIMPLEMENTED();
-		break;
-	case GL_QUAD_STRIP:
-		UNIMPLEMENTED();
-		break;
-	case GL_POLYGON:
-		UNIMPLEMENTED();
-		break;
-	default:
-		UNREACHABLE(drawMode);
-	}
-
-	restoreAttribs();
-
-	drawing = false;
-}
-
-void Context::setColorLogicOpEnabled(bool colorLogicOpEnabled)
-{
-	if(mState.colorLogicOpEnabled != colorLogicOpEnabled)
-	{
-		mState.colorLogicOpEnabled = colorLogicOpEnabled;
-		mColorLogicOperatorDirty = true;
-	}
-}
-
-bool Context::isColorLogicOpEnabled()
-{
-	return mState.colorLogicOpEnabled;
-}
-
-void Context::setLogicalOperation(GLenum logicalOperation)
-{
-	if(mState.logicalOperation != logicalOperation)
-	{
-		mState.logicalOperation = logicalOperation;
-		mColorLogicOperatorDirty = true;
-	}
-}
-
-void Context::setColorMaterialEnabled(bool enable)
-{
-	device->setColorVertexEnable(enable);
-}
-
-void Context::setColorMaterialMode(GLenum mode)
-{
-	switch(mode)
-	{
-	case GL_EMISSION:
-		device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
-		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
-		device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
-		device->setEmissiveMaterialSource(sw::MATERIAL_COLOR1);
-		break;
-	case GL_AMBIENT:
-		device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
-		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
-		device->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
-		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
-		break;
-	case GL_DIFFUSE:
-		device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
-		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
-		device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
-		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
-		break;
-	case GL_SPECULAR:
-		device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
-		device->setSpecularMaterialSource(sw::MATERIAL_COLOR1);
-		device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
-		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
-		break;
-	case GL_AMBIENT_AND_DIFFUSE:
-		device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
-		device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
-		device->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
-		device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
-		break;
-	default:
-		UNREACHABLE(mode);
-	}
-}
-
-Device *Context::getDevice()
-{
-	return device;
-}
-
-}
diff --git a/src/OpenGL/libGL/Context.h b/src/OpenGL/libGL/Context.h
deleted file mode 100644
index dbd0737..0000000
--- a/src/OpenGL/libGL/Context.h
+++ /dev/null
@@ -1,827 +0,0 @@
-// 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.
-
-// Context.h: Defines the Context class, managing all GL state and performing
-// rendering operations.
-
-#ifndef LIBGL_CONTEXT_H_
-#define LIBGL_CONTEXT_H_
-
-#include "ResourceManager.h"
-#include "common/NameSpace.hpp"
-#include "common/Object.hpp"
-#include "Image.hpp"
-#include "Renderer/Sampler.hpp"
-#include "Renderer/Vertex.hpp"
-#include "common/MatrixStack.hpp"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-#include <map>
-#include <list>
-#include <vector>
-
-namespace gl
-{
-	class Display;
-	class Surface;
-	class Config;
-
-	void APIENTRY glVertexAttribArray(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
-
-	class Command
-	{
-	public:
-		Command() {};
-		virtual ~Command() {};
-
-		virtual void call() = 0;
-	};
-
-	class Command0 : public Command
-	{
-	public:
-		Command0(void (APIENTRY *function)())
-			: function(function)
-		{
-		}
-
-		virtual void call()
-		{
-			function();
-		}
-
-		void (APIENTRY *function)();
-	};
-
-	template<typename A1>
-	class Command1 : public Command
-	{
-	public:
-		Command1(void (APIENTRY *function)(A1), A1 arg1)
-			: function(function)
-			, argument1(arg1)
-		{
-		}
-
-		virtual void call()
-		{
-			function(argument1);
-		}
-
-		void (APIENTRY *function)(A1);
-		A1 argument1;
-	};
-
-	template<typename A1, typename A2>
-	class Command2 : public Command
-	{
-	public:
-		Command2(void (APIENTRY *function)(A1, A2), A1 arg1, A2 arg2)
-			: function(function)
-			, argument1(arg1)
-			, argument2(arg2)
-		{
-		}
-
-		virtual void call()
-		{
-			function(argument1, argument2);
-		}
-
-		void (APIENTRY *function)(A1, A2);
-		A1 argument1;
-		A2 argument2;
-	};
-
-	template<typename A1, typename A2, typename A3>
-	class Command3 : public Command
-	{
-	public:
-		Command3(void (APIENTRY *function)(A1, A2, A3), A1 arg1, A2 arg2, A3 arg3)
-			: function(function)
-			, argument1(arg1)
-			, argument2(arg2)
-			, argument3(arg3)
-		{
-		}
-
-		virtual void call()
-		{
-			function(argument1, argument2, argument3);
-		}
-
-		void (APIENTRY *function)(A1, A2, A3);
-		A1 argument1;
-		A2 argument2;
-		A3 argument3;
-	};
-
-	template<typename A1, typename A2, typename A3, typename A4>
-	class Command4 : public Command
-	{
-	public:
-		Command4(void (APIENTRY *function)(A1, A2, A3, A4), A1 arg1, A2 arg2, A3 arg3, A4 arg4)
-			: function(function)
-			, argument1(arg1)
-			, argument2(arg2)
-			, argument3(arg3)
-			, argument4(arg4)
-		{
-		}
-
-		virtual void call()
-		{
-			function(argument1, argument2, argument3, argument4);
-		}
-
-		void (APIENTRY *function)(A1, A2, A3, A4);
-		A1 argument1;
-		A2 argument2;
-		A3 argument3;
-		A4 argument4;
-	};
-
-	template<typename A1, typename A2, typename A3, typename A4, typename A5>
-	class Command5 : public Command
-	{
-	public:
-		Command5(void (APIENTRY *function)(A1, A2, A3, A4, A5), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
-			: function(function)
-			, argument1(arg1)
-			, argument2(arg2)
-			, argument3(arg3)
-			, argument4(arg4)
-			, argument5(arg5)
-		{
-		}
-
-		virtual void call()
-		{
-			function(argument1, argument2, argument3, argument4, argument5);
-		}
-
-		void (APIENTRY *function)(A1, A2, A3, A4, A5);
-		A1 argument1;
-		A2 argument2;
-		A3 argument3;
-		A4 argument4;
-		A5 argument5;
-	};
-
-	template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
-	class Command6 : public Command
-	{
-	public:
-		Command6(void (APIENTRY *function)(A1, A2, A3, A4, A5, A6), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5, A6 arg6)
-			: function(function)
-			, argument1(arg1)
-			, argument2(arg2)
-			, argument3(arg3)
-			, argument4(arg4)
-			, argument5(arg5)
-			, argument6(arg6)
-		{
-		}
-
-		~Command6()
-		{
-			if(function == glVertexAttribArray)
-			{
-				delete[] argument6;
-			}
-		}
-
-		virtual void call()
-		{
-			function(argument1, argument2, argument3, argument4, argument5, argument6);
-		}
-
-		void (APIENTRY *function)(A1, A2, A3, A4, A5, A6);
-		A1 argument1;
-		A2 argument2;
-		A3 argument3;
-		A4 argument4;
-		A5 argument5;
-		A6 argument6;
-	};
-
-	inline Command0 *newCommand(void (APIENTRY *function)())
-	{
-		return new Command0(function);
-	}
-
-	template<typename A1>
-	Command1<A1> *newCommand(void (APIENTRY *function)(A1), A1 arg1)
-	{
-		return new Command1<A1>(function, arg1);
-	}
-
-	template<typename A1, typename A2>
-	Command2<A1, A2> *newCommand(void (APIENTRY *function)(A1, A2), A1 arg1, A2 arg2)
-	{
-		return new Command2<A1, A2>(function, arg1, arg2);
-	}
-
-	template<typename A1, typename A2, typename A3>
-	Command3<A1, A2, A3> *newCommand(void (APIENTRY *function)(A1, A2, A3), A1 arg1, A2 arg2, A3 arg3)
-	{
-		return new Command3<A1, A2, A3>(function, arg1, arg2, arg3);
-	}
-
-	template<typename A1, typename A2, typename A3, typename A4>
-	Command4<A1, A2, A3, A4> *newCommand(void (APIENTRY *function)(A1, A2, A3, A4), A1 arg1, A2 arg2, A3 arg3, A4 arg4)
-	{
-		return new Command4<A1, A2, A3, A4>(function, arg1, arg2, arg3, arg4);
-	}
-
-	template<typename A1, typename A2, typename A3, typename A4, typename A5>
-	Command5<A1, A2, A3, A4, A5> *newCommand(void (APIENTRY *function)(A1, A2, A3, A4, A5), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
-	{
-		return new Command5<A1, A2, A3, A4, A5>(function, arg1, arg2, arg3, arg4, arg5);
-	}
-
-	template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
-	Command6<A1, A2, A3, A4, A5, A6> *newCommand(void (APIENTRY *function)(A1, A2, A3, A4, A5, A6), A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5, A6 arg6)
-	{
-		return new Command6<A1, A2, A3, A4, A5, A6>(function, arg1, arg2, arg3, arg4, arg5, arg6);
-	}
-
-	class DisplayList
-	{
-	public:
-		DisplayList()
-		{
-		}
-
-		~DisplayList()
-		{
-			while(!list.empty())
-			{
-				delete list.back();
-				list.pop_back();
-			}
-		}
-
-		void call()
-		{
-			for(CommandList::iterator command = list.begin(); command != list.end(); command++)
-			{
-				(*command)->call();
-			}
-		}
-
-		typedef std::list<Command*> CommandList;
-		CommandList list;
-	};
-
-struct TranslatedAttribute;
-struct TranslatedIndexData;
-
-class Device;
-class Buffer;
-class Shader;
-class Program;
-class Texture;
-class Texture2D;
-class TextureCubeMap;
-class Framebuffer;
-class Renderbuffer;
-class RenderbufferStorage;
-class Colorbuffer;
-class Depthbuffer;
-class StreamingIndexBuffer;
-class Stencilbuffer;
-class DepthStencilbuffer;
-class VertexDataManager;
-class IndexDataManager;
-class Fence;
-class Query;
-
-enum
-{
-	MAX_VERTEX_ATTRIBS = 9,
-	MAX_UNIFORM_VECTORS = 256,   // Device limit
-	MAX_VERTEX_UNIFORM_VECTORS = sw::VERTEX_UNIFORM_VECTORS - 3,   // Reserve space for gl_DepthRange
-	MAX_VARYING_VECTORS = 10,
-	MAX_TEXTURE_IMAGE_UNITS = 2,
-	MAX_VERTEX_TEXTURE_IMAGE_UNITS = 1,
-	MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS,
-	MAX_FRAGMENT_UNIFORM_VECTORS = sw::FRAGMENT_UNIFORM_VECTORS - 3,    // Reserve space for gl_DepthRange
-	MAX_DRAW_BUFFERS = 1,
-
-	IMPLEMENTATION_COLOR_READ_FORMAT = GL_RGB,
-	IMPLEMENTATION_COLOR_READ_TYPE = GL_UNSIGNED_SHORT_5_6_5
-};
-
-const GLenum compressedTextureFormats[] =
-{
-	GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
-	GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
-	GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
-	GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
-};
-
-const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]);
-
-const GLint multisampleCount[] = {4, 2, 1};
-const GLint NUM_MULTISAMPLE_COUNTS = sizeof(multisampleCount) / sizeof(multisampleCount[0]);
-const GLint IMPLEMENTATION_MAX_SAMPLES = multisampleCount[0];
-
-const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;
-const float ALIASED_LINE_WIDTH_RANGE_MAX = 128.0f;
-const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f;
-const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f;
-const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f;
-
-enum QueryType
-{
-	QUERY_ANY_SAMPLES_PASSED,
-	QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE,
-
-	QUERY_TYPE_COUNT
-};
-
-struct Color
-{
-	float red;
-	float green;
-	float blue;
-	float alpha;
-};
-
-// Helper structure describing a single vertex attribute
-class VertexAttribute
-{
-public:
-	VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(nullptr), mArrayEnabled(false)
-	{
-		mCurrentValue[0] = 0.0f;
-		mCurrentValue[1] = 0.0f;
-		mCurrentValue[2] = 0.0f;
-		mCurrentValue[3] = 1.0f;
-	}
-
-	int typeSize() const
-	{
-		switch(mType)
-		{
-		case GL_BYTE:           return mSize * sizeof(GLbyte);
-		case GL_UNSIGNED_BYTE:  return mSize * sizeof(GLubyte);
-		case GL_SHORT:          return mSize * sizeof(GLshort);
-		case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);
-		case GL_FIXED:          return mSize * sizeof(GLfixed);
-		case GL_FLOAT:          return mSize * sizeof(GLfloat);
-		default: UNREACHABLE(mType); return mSize * sizeof(GLfloat);
-		}
-	}
-
-	GLsizei stride() const
-	{
-		return mStride ? mStride : typeSize();
-	}
-
-	// From glVertexAttribPointer
-	GLenum mType;
-	GLint mSize;
-	bool mNormalized;
-	GLsizei mStride;   // 0 means natural stride
-
-	union
-	{
-		const void *mPointer;
-		intptr_t mOffset;
-	};
-
-	BindingPointer<Buffer> mBoundBuffer;   // Captured when glVertexAttribPointer is called.
-
-	bool mArrayEnabled;   // From glEnable/DisableVertexAttribArray
-	float mCurrentValue[4];   // From glVertexAttrib
-};
-
-typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
-
-// Helper structure to store all raw state
-struct State
-{
-	Color colorClearValue;
-	GLclampf depthClearValue;
-	int stencilClearValue;
-
-	bool cullFaceEnabled;
-	GLenum cullMode;
-	GLenum frontFace;
-	bool depthTestEnabled;
-	GLenum depthFunc;
-	bool blendEnabled;
-	GLenum sourceBlendRGB;
-	GLenum destBlendRGB;
-	GLenum sourceBlendAlpha;
-	GLenum destBlendAlpha;
-	GLenum blendEquationRGB;
-	GLenum blendEquationAlpha;
-	Color blendColor;
-	bool stencilTestEnabled;
-	GLenum stencilFunc;
-	GLint stencilRef;
-	GLuint stencilMask;
-	GLenum stencilFail;
-	GLenum stencilPassDepthFail;
-	GLenum stencilPassDepthPass;
-	GLuint stencilWritemask;
-	GLenum stencilBackFunc;
-	GLint stencilBackRef;
-	GLuint stencilBackMask;
-	GLenum stencilBackFail;
-	GLenum stencilBackPassDepthFail;
-	GLenum stencilBackPassDepthPass;
-	GLuint stencilBackWritemask;
-	bool polygonOffsetFillEnabled;
-	GLfloat polygonOffsetFactor;
-	GLfloat polygonOffsetUnits;
-	bool sampleAlphaToCoverageEnabled;
-	bool sampleCoverageEnabled;
-	GLclampf sampleCoverageValue;
-	bool sampleCoverageInvert;
-	bool scissorTestEnabled;
-	bool ditherEnabled;
-	bool colorLogicOpEnabled;
-	GLenum logicalOperation;
-
-	GLfloat lineWidth;
-
-	GLenum generateMipmapHint;
-	GLenum fragmentShaderDerivativeHint;
-
-	GLint viewportX;
-	GLint viewportY;
-	GLsizei viewportWidth;
-	GLsizei viewportHeight;
-	float zNear;
-	float zFar;
-
-	GLint scissorX;
-	GLint scissorY;
-	GLsizei scissorWidth;
-	GLsizei scissorHeight;
-
-	bool colorMaskRed;
-	bool colorMaskGreen;
-	bool colorMaskBlue;
-	bool colorMaskAlpha;
-	bool depthMask;
-
-	unsigned int activeSampler;   // Active texture unit selector - GL_TEXTURE0
-	BindingPointer<Buffer> arrayBuffer;
-	BindingPointer<Buffer> elementArrayBuffer;
-	GLuint readFramebuffer;
-	GLuint drawFramebuffer;
-	BindingPointer<Renderbuffer> renderbuffer;
-	GLuint currentProgram;
-
-	VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
-	BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-	BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT];
-
-	GLint unpackAlignment;
-	GLint packAlignment;
-};
-
-class Context
-{
-public:
-	Context(const Context *shareContext);
-
-	~Context();
-
-	void makeCurrent(Surface *surface);
-
-	void markAllStateDirty();
-
-	// State manipulation
-	void setClearColor(float red, float green, float blue, float alpha);
-	void setClearDepth(float depth);
-	void setClearStencil(int stencil);
-
-	void setCullFaceEnabled(bool enabled);
-	bool isCullFaceEnabled() const;
-	void setCullMode(GLenum mode);
-	void setFrontFace(GLenum front);
-
-	void setDepthTestEnabled(bool enabled);
-	bool isDepthTestEnabled() const;
-	void setDepthFunc(GLenum depthFunc);
-	void setDepthRange(float zNear, float zFar);
-
-	void setBlendEnabled(bool enabled);
-	bool isBlendEnabled() const;
-	void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
-	void setBlendColor(float red, float green, float blue, float alpha);
-	void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
-
-	void setStencilTestEnabled(bool enabled);
-	bool isStencilTestEnabled() const;
-	void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
-	void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);
-	void setStencilWritemask(GLuint stencilWritemask);
-	void setStencilBackWritemask(GLuint stencilBackWritemask);
-	void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass);
-	void setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass);
-
-	void setPolygonOffsetFillEnabled(bool enabled);
-	bool isPolygonOffsetFillEnabled() const;
-	void setPolygonOffsetParams(GLfloat factor, GLfloat units);
-
-	void setSampleAlphaToCoverageEnabled(bool enabled);
-	bool isSampleAlphaToCoverageEnabled() const;
-	void setSampleCoverageEnabled(bool enabled);
-	bool isSampleCoverageEnabled() const;
-	void setSampleCoverageParams(GLclampf value, bool invert);
-
-	void setDitherEnabled(bool enabled);
-	bool isDitherEnabled() const;
-
-	void setLineWidth(GLfloat width);
-
-	void setGenerateMipmapHint(GLenum hint);
-	void setFragmentShaderDerivativeHint(GLenum hint);
-
-	void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
-
-	void setScissorTestEnabled(bool enabled);
-	bool isScissorTestEnabled() const;
-	void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
-
-	void setColorMask(bool red, bool green, bool blue, bool alpha);
-	void setDepthMask(bool mask);
-
-	void setActiveSampler(unsigned int active);
-
-	GLuint getReadFramebufferName() const;
-	GLuint getDrawFramebufferName() const;
-	GLuint getRenderbufferName() const;
-
-	GLuint getActiveQuery(GLenum target) const;
-
-	GLuint getArrayBufferName() const;
-
-	void setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled);
-	const VertexAttribute &getVertexAttribState(unsigned int attribNum);
-	void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
-	                          bool normalized, GLsizei stride, const void *pointer);
-	const void *getVertexAttribPointer(unsigned int attribNum) const;
-
-	const VertexAttributeArray &getVertexAttributes();
-
-	void setUnpackAlignment(GLint alignment);
-	GLint getUnpackAlignment() const;
-
-	void setPackAlignment(GLint alignment);
-	GLint getPackAlignment() const;
-
-	// These create  and destroy methods are merely pass-throughs to
-	// ResourceManager, which owns these object types
-	GLuint createBuffer();
-	GLuint createShader(GLenum type);
-	GLuint createProgram();
-	GLuint createTexture();
-	GLuint createRenderbuffer();
-
-	void deleteBuffer(GLuint buffer);
-	void deleteShader(GLuint shader);
-	void deleteProgram(GLuint program);
-	void deleteTexture(GLuint texture);
-	void deleteRenderbuffer(GLuint renderbuffer);
-
-	// Framebuffers are owned by the Context, so these methods do not pass through
-	GLuint createFramebuffer();
-	void deleteFramebuffer(GLuint framebuffer);
-
-	// Fences are owned by the Context
-	GLuint createFence();
-	void deleteFence(GLuint fence);
-
-	// Queries are owned by the Context
-	GLuint createQuery();
-	void deleteQuery(GLuint query);
-
-	void bindArrayBuffer(GLuint buffer);
-	void bindElementArrayBuffer(GLuint buffer);
-	void bindTexture2D(GLuint texture);
-	void bindTextureCubeMap(GLuint texture);
-	void bindReadFramebuffer(GLuint framebuffer);
-	void bindDrawFramebuffer(GLuint framebuffer);
-	void bindRenderbuffer(GLuint renderbuffer);
-	void useProgram(GLuint program);
-
-	void beginQuery(GLenum target, GLuint query);
-	void endQuery(GLenum target);
-
-	void setFramebufferZero(Framebuffer *framebuffer);
-
-	void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
-
-	void setVertexAttrib(GLuint index, float x, float y, float z, float w);
-
-	Buffer *getBuffer(GLuint handle);
-	Fence *getFence(GLuint handle);
-	Shader *getShader(GLuint handle);
-	Program *getProgram(GLuint handle);
-	Texture *getTexture(GLuint handle);
-	Framebuffer *getFramebuffer(GLuint handle);
-	Renderbuffer *getRenderbuffer(GLuint handle);
-	Query *getQuery(GLuint handle, bool create, GLenum type);
-
-	Buffer *getArrayBuffer();
-	Buffer *getElementArrayBuffer();
-	Program *getCurrentProgram();
-	Texture2D *getTexture2D(GLenum target);
-	TextureCubeMap *getTextureCubeMap();
-	Texture *getSamplerTexture(unsigned int sampler, TextureType type);
-	Framebuffer *getReadFramebuffer();
-	Framebuffer *getDrawFramebuffer();
-
-	bool getFloatv(GLenum pname, GLfloat *params);
-	bool getIntegerv(GLenum pname, GLint *params);
-	bool getBooleanv(GLenum pname, GLboolean *params);
-
-	bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
-
-	void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
-	void clear(GLbitfield mask);
-	void drawArrays(GLenum mode, GLint first, GLsizei count);
-	void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
-	void finish();
-	void flush();
-
-	void recordInvalidEnum();
-	void recordInvalidValue();
-	void recordInvalidOperation();
-	void recordOutOfMemory();
-	void recordInvalidFramebufferOperation();
-
-	GLenum getError();
-
-	static int getSupportedMultisampleCount(int requested);
-
-	void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
-	                     GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
-	                     GLbitfield mask);
-
-	void setMatrixMode(GLenum mode);
-	void loadIdentity();
-	void pushMatrix();
-	void popMatrix();
-	void rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
-	void translate(GLfloat x, GLfloat y, GLfloat z);
-	void scale(GLfloat x, GLfloat y, GLfloat z);
-	void multiply(const GLdouble *m);
-	void multiply(const GLfloat *m);
-	void frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
-	void ortho(double left, double right, double bottom, double top, double zNear, double zFar);   // FIXME: GLdouble
-
-	void setLightingEnabled(bool enabled);
-	void setFogEnabled(bool enabled);
-	void setAlphaTestEnabled(bool enabled);
-	void alphaFunc(GLenum func, GLclampf ref);
-	void setTexture2DEnabled(bool enabled);
-	void setShadeModel(GLenum mode);
-	void setLightEnabled(int index, bool enable);
-	void setNormalizeNormalsEnabled(bool enable);
-
-	GLuint genLists(GLsizei range);
-	void newList(GLuint list, GLenum mode);
-	void endList();
-	void callList(GLuint list);
-	void deleteList(GLuint list);
-	GLuint getListIndex() {return listIndex;}
-	GLenum getListMode() {return listMode;}
-	void listCommand(Command *command);
-
-	void captureAttribs();
-	void captureDrawArrays(GLenum mode, GLint first, GLsizei count);
-	void restoreAttribs();
-	void clientActiveTexture(GLenum texture);
-	GLenum getClientActiveTexture() const;
-	unsigned int getActiveTexture() const;
-
-	void begin(GLenum mode);
-	void position(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-	void end();
-
-	void setColorMaterialEnabled(bool enable);
-	void setColorMaterialMode(GLenum mode);
-
-	void setColorLogicOpEnabled(bool colorLogicOpEnabled);
-	bool isColorLogicOpEnabled();
-	void setLogicalOperation(GLenum logicalOperation);
-
-	Device *getDevice();
-
-private:
-	bool applyRenderTarget();
-	void applyState(GLenum drawMode);
-	GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count);
-	GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
-	void applyShaders();
-	void applyTextures();
-	void applyTextures(sw::SamplerType type);
-	void applyTexture(sw::SamplerType type, int sampler, Texture *texture);
-
-	void detachBuffer(GLuint buffer);
-	void detachTexture(GLuint texture);
-	void detachFramebuffer(GLuint framebuffer);
-	void detachRenderbuffer(GLuint renderbuffer);
-
-	bool cullSkipsDraw(GLenum drawMode);
-	bool isTriangleMode(GLenum drawMode);
-
-	State mState;
-
-	BindingPointer<Texture2D> mTexture2DZero;
-	BindingPointer<Texture2D> mProxyTexture2DZero;
-	BindingPointer<TextureCubeMap> mTextureCubeMapZero;
-
-	gl::NameSpace<Framebuffer> mFramebufferNameSpace;
-	gl::NameSpace<Fence, 0> mFenceNameSpace;
-	gl::NameSpace<Query> mQueryNameSpace;
-
-	VertexDataManager *mVertexDataManager;
-	IndexDataManager *mIndexDataManager;
-
-	// Recorded errors
-	bool mInvalidEnum;
-	bool mInvalidValue;
-	bool mInvalidOperation;
-	bool mOutOfMemory;
-	bool mInvalidFramebufferOperation;
-
-	bool mHasBeenCurrent;
-
-	unsigned int mAppliedProgramSerial;
-
-	// state caching flags
-	bool mDepthStateDirty;
-	bool mMaskStateDirty;
-	bool mPixelPackingStateDirty;
-	bool mBlendStateDirty;
-	bool mStencilStateDirty;
-	bool mPolygonOffsetStateDirty;
-	bool mSampleStateDirty;
-	bool mFrontFaceDirty;
-	bool mDitherStateDirty;
-	bool mColorLogicOperatorDirty;
-
-	Device *device;
-	ResourceManager *mResourceManager;
-
-	sw::MatrixStack &currentMatrixStack();
-	GLenum matrixMode;
-	sw::MatrixStack modelView;
-	sw::MatrixStack projection;
-	sw::MatrixStack texture[8];
-
-	GLenum listMode;
-	//std::map<GLuint, GLuint> listMap;
-	std::map<GLuint, DisplayList*> displayList;
-	DisplayList *list;
-	GLuint listIndex;
-	GLuint firstFreeIndex;
-
-	GLenum clientTexture;
-
-	bool drawing;
-	GLenum drawMode;
-
-	struct InVertex
-	{
-		sw::float4 P;    // Position
-		sw::float4 N;    // Normal
-		sw::float4 C;    // Color
-		sw::float4 T0;   // Texture coordinate
-		sw::float4 T1;
-	};
-
-	std::vector<InVertex> vertex;
-
-	VertexAttribute clientAttribute[MAX_VERTEX_ATTRIBS];
-
-	bool envEnable[8];
-};
-}
-
-#endif   // INCLUDE_CONTEXT_H_
diff --git a/src/OpenGL/libGL/Device.cpp b/src/OpenGL/libGL/Device.cpp
deleted file mode 100644
index fd9c205..0000000
--- a/src/OpenGL/libGL/Device.cpp
+++ /dev/null
@@ -1,777 +0,0 @@
-// 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.
-
-#include "Device.hpp"
-
-#include "Image.hpp"
-#include "Texture.h"
-
-#include "Renderer/Renderer.hpp"
-#include "Renderer/Clipper.hpp"
-#include "Shader/PixelShader.hpp"
-#include "Shader/VertexShader.hpp"
-#include "Main/Config.hpp"
-#include "Main/FrameBuffer.hpp"
-#include "Common/Math.hpp"
-#include "Common/Configurator.hpp"
-#include "Common/Memory.hpp"
-#include "Common/Timer.hpp"
-#include "../common/debug.h"
-
-namespace gl
-{
-	using namespace sw;
-
-	Device::Device(Context *context) : Renderer(context, OpenGL, true), context(context)
-	{
-		depthStencil = 0;
-		renderTarget = 0;
-
-		setDepthBufferEnable(true);
-		setFillMode(FILL_SOLID);
-		setShadingMode(SHADING_GOURAUD);
-		setDepthWriteEnable(true);
-		setAlphaTestEnable(false);
-		setSourceBlendFactor(BLEND_ONE);
-		setDestBlendFactor(BLEND_ZERO);
-		setCullMode(CULL_COUNTERCLOCKWISE, true);
-		setDepthCompare(DEPTH_LESSEQUAL);
-		setAlphaReference(0.0f);
-		setAlphaCompare(ALPHA_ALWAYS);
-		setAlphaBlendEnable(false);
-		setFogEnable(false);
-		setSpecularEnable(false);
-		setFogColor(0);
-		setPixelFogMode(FOG_NONE);
-		setFogStart(0.0f);
-		setFogEnd(1.0f);
-		setFogDensity(1.0f);
-		setRangeFogEnable(false);
-		setStencilEnable(false);
-		setStencilFailOperation(OPERATION_KEEP);
-		setStencilZFailOperation(OPERATION_KEEP);
-		setStencilPassOperation(OPERATION_KEEP);
-		setStencilCompare(STENCIL_ALWAYS);
-		setStencilReference(0);
-		setStencilMask(0xFFFFFFFF);
-		setStencilWriteMask(0xFFFFFFFF);
-		setVertexFogMode(FOG_NONE);
-		setClipFlags(0);
-		setPointSize(1.0f);
-		setPointSizeMin(0.125f);
-		setPointSizeMax(8192.0f);
-		setColorWriteMask(0, 0x0000000F);
-		setBlendOperation(BLENDOP_ADD);
-		scissorEnable = false;
-		setSlopeDepthBias(0.0f);
-		setTwoSidedStencil(false);
-		setStencilFailOperationCCW(OPERATION_KEEP);
-		setStencilZFailOperationCCW(OPERATION_KEEP);
-		setStencilPassOperationCCW(OPERATION_KEEP);
-		setStencilCompareCCW(STENCIL_ALWAYS);
-		setColorWriteMask(1, 0x0000000F);
-		setColorWriteMask(2, 0x0000000F);
-		setColorWriteMask(3, 0x0000000F);
-		setBlendConstant(0xFFFFFFFF);
-		setWriteSRGB(false);
-		setDepthBias(0.0f);
-		setSeparateAlphaBlendEnable(false);
-		setSourceBlendFactorAlpha(BLEND_ONE);
-		setDestBlendFactorAlpha(BLEND_ZERO);
-		setBlendOperationAlpha(BLENDOP_ADD);
-		setPointSpriteEnable(true);
-		setColorLogicOpEnabled(false);
-		setLogicalOperation(LOGICALOP_COPY);
-
-		for(int i = 0; i < 16; i++)
-		{
-			setAddressingModeU(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
-			setAddressingModeV(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
-			setAddressingModeW(sw::SAMPLER_PIXEL, i, ADDRESSING_WRAP);
-			setBorderColor(sw::SAMPLER_PIXEL, i, 0x00000000);
-			setTextureFilter(sw::SAMPLER_PIXEL, i, FILTER_POINT);
-			setMipmapFilter(sw::SAMPLER_PIXEL, i, MIPMAP_NONE);
-			setMipmapLOD(sw::SAMPLER_PIXEL, i, 0.0f);
-		}
-
-		for(int i = 0; i < 4; i++)
-		{
-			setAddressingModeU(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
-			setAddressingModeV(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
-			setAddressingModeW(sw::SAMPLER_VERTEX, i, ADDRESSING_WRAP);
-			setBorderColor(sw::SAMPLER_VERTEX, i, 0x00000000);
-			setTextureFilter(sw::SAMPLER_VERTEX, i, FILTER_POINT);
-			setMipmapFilter(sw::SAMPLER_VERTEX, i, MIPMAP_NONE);
-			setMipmapLOD(sw::SAMPLER_VERTEX, i, 0.0f);
-		}
-
-		for(int i = 0; i < 6; i++)
-		{
-			float plane[4] = {0, 0, 0, 0};
-
-			setClipPlane(i, plane);
-		}
-
-		pixelShader = 0;
-		vertexShader = 0;
-
-		pixelShaderDirty = true;
-		pixelShaderConstantsFDirty = 0;
-		vertexShaderDirty = true;
-		vertexShaderConstantsFDirty = 0;
-
-		for(int i = 0; i < FRAGMENT_UNIFORM_VECTORS; i++)
-		{
-			float zero[4] = {0, 0, 0, 0};
-
-			setPixelShaderConstantF(i, zero, 1);
-		}
-
-		for(int i = 0; i < VERTEX_UNIFORM_VECTORS; i++)
-		{
-			float zero[4] = {0, 0, 0, 0};
-
-			setVertexShaderConstantF(i, zero, 1);
-		}
-
-		setLightingEnable(false);
-
-		setGlobalAmbient(sw::Color<float>(0.2f, 0.2f, 0.2f, 1.0f));
-		setMaterialAmbient(sw::Color<float>(0.2f, 0.2f, 0.2f, 1.0f));
-		setMaterialDiffuse(sw::Color<float>(0.8f, 0.8f, 0.8f, 1.0f));
-		setMaterialSpecular(sw::Color<float>(0.0f, 0.0f, 0.0f, 1.0f));
-		setMaterialEmission(sw::Color<float>(0.0f, 0.0f, 0.0f, 1.0f));
-
-		for(int i = 0; i < 8; i++)
-		{
-			setLightEnable(i, false);
-			setLightAttenuation(i, 1.0f, 0.0f, 0.0f);
-		}
-
-		setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
-		setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
-		setAmbientMaterialSource(sw::MATERIAL_COLOR1);
-		setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
-	}
-
-	Device::~Device()
-	{
-		if(depthStencil)
-		{
-			depthStencil->release();
-			depthStencil = 0;
-		}
-
-		if(renderTarget)
-		{
-			renderTarget->release();
-			renderTarget = 0;
-		}
-
-		delete context;
-	}
-
-	// This object has to be mem aligned
-	void* Device::operator new(size_t size)
-	{
-		ASSERT(size == sizeof(Device)); // This operator can't be called from a derived class
-		return sw::allocate(sizeof(gl::Device), 16);
-	}
-
-	void Device::operator delete(void * mem)
-	{
-		sw::deallocate(mem);
-	}
-
-	void Device::clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask)
-	{
-		if(!renderTarget || !rgbaMask)
-		{
-			return;
-		}
-
-		sw::Rect clearRect = renderTarget->getRect();
-
-		if(scissorEnable)
-		{
-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
-		}
-
-		float rgba[4];
-		rgba[0] = red;
-		rgba[1] = green;
-		rgba[2] = blue;
-		rgba[3] = alpha;
-
-		clear(rgba, FORMAT_A32B32G32R32F, renderTarget, clearRect, rgbaMask);
-	}
-
-	void Device::clearDepth(float z)
-	{
-		if(!depthStencil)
-		{
-			return;
-		}
-
-		z = clamp01(z);
-		sw::Rect clearRect = depthStencil->getRect();
-
-		if(scissorEnable)
-		{
-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
-		}
-
-		depthStencil->clearDepth(z, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
-	}
-
-	void Device::clearStencil(unsigned int stencil, unsigned int mask)
-	{
-		if(!depthStencil)
-		{
-			return;
-		}
-
-		sw::Rect clearRect = depthStencil->getRect();
-
-		if(scissorEnable)
-		{
-			clearRect.clip(scissorRect.x0, scissorRect.y0, scissorRect.x1, scissorRect.y1);
-		}
-
-		depthStencil->clearStencil(stencil, mask, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
-	}
-
-	Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)
-	{
-		if(height > OUTLINE_RESOLUTION)
-		{
-			ERR("Invalid parameters: %dx%d", width, height);
-			return 0;
-		}
-
-		bool lockable = true;
-
-		switch(format)
-		{
-	//	case FORMAT_D15S1:
-		case FORMAT_D24S8:
-		case FORMAT_D24X8:
-	//	case FORMAT_D24X4S4:
-		case FORMAT_D24FS8:
-		case FORMAT_D32:
-		case FORMAT_D16:
-			lockable = false;
-			break;
-	//	case FORMAT_S8_LOCKABLE:
-	//	case FORMAT_D16_LOCKABLE:
-		case FORMAT_D32F_LOCKABLE:
-	//	case FORMAT_D32_LOCKABLE:
-		case FORMAT_DF24S8:
-		case FORMAT_DF16S8:
-			lockable = true;
-			break;
-		default:
-			UNREACHABLE(format);
-		}
-
-		Image *surface = new Image(0, width, height, format, multiSampleDepth, lockable, true);
-
-		if(!surface)
-		{
-			ERR("Out of memory");
-			return 0;
-		}
-
-		return surface;
-	}
-
-	Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable)
-	{
-		if(height > OUTLINE_RESOLUTION)
-		{
-			ERR("Invalid parameters: %dx%d", width, height);
-			return 0;
-		}
-
-		Image *surface = new Image(0, width, height, format, multiSampleDepth, lockable, true);
-
-		if(!surface)
-		{
-			ERR("Out of memory");
-			return 0;
-		}
-
-		return surface;
-	}
-
-	void Device::drawIndexedPrimitive(PrimitiveType type, unsigned int indexOffset, unsigned int primitiveCount, int indexSize)
-	{
-		if(!bindResources() || !primitiveCount)
-		{
-			return;
-		}
-
-		DrawType drawType;
-
-		if(indexSize == 4)
-		{
-			switch(type)
-			{
-			case DRAW_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST32;     break;
-			case DRAW_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST32;      break;
-			case DRAW_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP32;     break;
-			case DRAW_LINELOOP:      drawType = sw::DRAW_INDEXEDLINELOOP32;      break;
-			case DRAW_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST32;  break;
-			case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP32; break;
-			case DRAW_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN32;	  break;
-			default: UNREACHABLE(type);
-			}
-		}
-		else if(indexSize == 2)
-		{
-			switch(type)
-			{
-			case DRAW_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST16;     break;
-			case DRAW_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST16;      break;
-			case DRAW_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP16;     break;
-			case DRAW_LINELOOP:      drawType = sw::DRAW_INDEXEDLINELOOP16;      break;
-			case DRAW_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST16;  break;
-			case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP16; break;
-			case DRAW_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN16;   break;
-			default: UNREACHABLE(type);
-			}
-		}
-		else if(indexSize == 1)
-		{
-			switch(type)
-			{
-			case DRAW_POINTLIST:     drawType = sw::DRAW_INDEXEDPOINTLIST8;     break;
-			case DRAW_LINELIST:      drawType = sw::DRAW_INDEXEDLINELIST8;      break;
-			case DRAW_LINESTRIP:     drawType = sw::DRAW_INDEXEDLINESTRIP8;     break;
-			case DRAW_LINELOOP:      drawType = sw::DRAW_INDEXEDLINELOOP8;      break;
-			case DRAW_TRIANGLELIST:  drawType = sw::DRAW_INDEXEDTRIANGLELIST8;  break;
-			case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_INDEXEDTRIANGLESTRIP8; break;
-			case DRAW_TRIANGLEFAN:   drawType = sw::DRAW_INDEXEDTRIANGLEFAN8;   break;
-			default: UNREACHABLE(type);
-			}
-		}
-		else UNREACHABLE(indexSize);
-
-		draw(drawType, indexOffset, primitiveCount);
-	}
-
-	void Device::drawPrimitive(PrimitiveType primitiveType, unsigned int primitiveCount)
-	{
-		if(!bindResources() || !primitiveCount)
-		{
-			return;
-		}
-
-		setIndexBuffer(0);
-
-		DrawType drawType;
-
-		switch(primitiveType)
-		{
-		case DRAW_POINTLIST:     drawType = sw::DRAW_POINTLIST;     break;
-		case DRAW_LINELIST:      drawType = sw::DRAW_LINELIST;      break;
-		case DRAW_LINESTRIP:     drawType = sw::DRAW_LINESTRIP;     break;
-		case DRAW_LINELOOP:      drawType = sw::DRAW_LINELOOP;      break;
-		case DRAW_TRIANGLELIST:  drawType = sw::DRAW_TRIANGLELIST;  break;
-		case DRAW_TRIANGLESTRIP: drawType = sw::DRAW_TRIANGLESTRIP; break;
-		case DRAW_TRIANGLEFAN:   drawType = sw::DRAW_TRIANGLEFAN;   break;
-		case DRAW_QUADLIST:      drawType = sw::DRAW_QUADLIST;      break;
-		default: UNREACHABLE(primitiveType);
-		}
-
-		draw(drawType, 0, primitiveCount);
-	}
-
-	void Device::setDepthStencilSurface(Image *depthStencil)
-	{
-		if(this->depthStencil == depthStencil)
-		{
-			return;
-		}
-
-		if(depthStencil)
-		{
-			depthStencil->addRef();
-		}
-
-		if(this->depthStencil)
-		{
-			this->depthStencil->release();
-		}
-
-		this->depthStencil = depthStencil;
-
-		setDepthBuffer(depthStencil);
-		setStencilBuffer(depthStencil);
-	}
-
-	void Device::setPixelShader(PixelShader *pixelShader)
-	{
-		this->pixelShader = pixelShader;
-		pixelShaderDirty = true;
-	}
-
-	void Device::setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
-	{
-		for(unsigned int i = 0; i < count && startRegister + i < FRAGMENT_UNIFORM_VECTORS; i++)
-		{
-			pixelShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];
-			pixelShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];
-			pixelShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];
-			pixelShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];
-		}
-
-		pixelShaderConstantsFDirty = max(startRegister + count, pixelShaderConstantsFDirty);
-		pixelShaderDirty = true;   // Reload DEF constants
-	}
-
-	void Device::setScissorEnable(bool enable)
-	{
-		scissorEnable = enable;
-	}
-
-	void Device::setRenderTarget(int index, Image *renderTarget)
-	{
-		if(renderTarget)
-		{
-			renderTarget->addRef();
-		}
-
-		if(this->renderTarget)
-		{
-			this->renderTarget->release();
-		}
-
-		this->renderTarget = renderTarget;
-
-		Renderer::setRenderTarget(index, renderTarget);
-	}
-
-	void Device::setScissorRect(const sw::Rect &rect)
-	{
-		scissorRect = rect;
-	}
-
-	void Device::setVertexShader(VertexShader *vertexShader)
-	{
-		this->vertexShader = vertexShader;
-		vertexShaderDirty = true;
-	}
-
-	void Device::setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
-	{
-		for(unsigned int i = 0; i < count && startRegister + i < VERTEX_UNIFORM_VECTORS; i++)
-		{
-			vertexShaderConstantF[startRegister + i][0] = constantData[i * 4 + 0];
-			vertexShaderConstantF[startRegister + i][1] = constantData[i * 4 + 1];
-			vertexShaderConstantF[startRegister + i][2] = constantData[i * 4 + 2];
-			vertexShaderConstantF[startRegister + i][3] = constantData[i * 4 + 3];
-		}
-
-		vertexShaderConstantsFDirty = max(startRegister + count, vertexShaderConstantsFDirty);
-		vertexShaderDirty = true;   // Reload DEF constants
-	}
-
-	void Device::setViewport(const Viewport &viewport)
-	{
-		this->viewport = viewport;
-	}
-
-	bool Device::stretchRect(Image *source, const sw::SliceRect *sourceRect, Image *dest, const sw::SliceRect *destRect, bool filter)
-	{
-		if(!source || !dest || !validRectangle(sourceRect, source) || !validRectangle(destRect, dest))
-		{
-			ERR("Invalid parameters");
-			return false;
-		}
-
-		int sWidth = source->getWidth();
-		int sHeight = source->getHeight();
-		int dWidth = dest->getWidth();
-		int dHeight = dest->getHeight();
-
-		SliceRect sRect;
-		SliceRect dRect;
-
-		if(sourceRect)
-		{
-			sRect = *sourceRect;
-		}
-		else
-		{
-			sRect.y0 = 0;
-			sRect.x0 = 0;
-			sRect.y1 = sHeight;
-			sRect.x1 = sWidth;
-		}
-
-		if(destRect)
-		{
-			dRect = *destRect;
-		}
-		else
-		{
-			dRect.y0 = 0;
-			dRect.x0 = 0;
-			dRect.y1 = dHeight;
-			dRect.x1 = dWidth;
-		}
-
-		bool scaling = (sRect.x1 - sRect.x0 != dRect.x1 - dRect.x0) || (sRect.y1 - sRect.y0 != dRect.y1 - dRect.y0);
-		bool equalFormats = source->getInternalFormat() == dest->getInternalFormat();
-		bool depthStencil = Image::isDepth(source->getInternalFormat()) || Image::isStencil(source->getInternalFormat());
-		bool alpha0xFF = false;
-
-		if((source->getInternalFormat() == FORMAT_A8R8G8B8 && dest->getInternalFormat() == FORMAT_X8R8G8B8) ||
-		   (source->getInternalFormat() == FORMAT_X8R8G8B8 && dest->getInternalFormat() == FORMAT_A8R8G8B8))
-		{
-			equalFormats = true;
-			alpha0xFF = true;
-		}
-
-		if(depthStencil)   // Copy entirely, internally   // FIXME: Check
-		{
-			if(source->hasDepth())
-			{
-				sw::byte *sourceBuffer = (sw::byte*)source->lockInternal(0, 0, sRect.slice, LOCK_READONLY, PUBLIC);
-				sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, dRect.slice, LOCK_DISCARD, PUBLIC);
-
-				unsigned int width = source->getWidth();
-				unsigned int height = source->getHeight();
-				unsigned int pitch = source->getInternalPitchB();
-
-				for(unsigned int y = 0; y < height; y++)
-				{
-					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
-
-					sourceBuffer += pitch;
-					destBuffer += pitch;
-				}
-
-				source->unlockInternal();
-				dest->unlockInternal();
-			}
-
-			if(source->hasStencil())
-			{
-				sw::byte *sourceBuffer = (sw::byte*)source->lockStencil(0, 0, 0, PUBLIC);
-				sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, 0, 0, PUBLIC);
-
-				unsigned int width = source->getWidth();
-				unsigned int height = source->getHeight();
-				unsigned int pitch = source->getStencilPitchB();
-
-				for(unsigned int y = 0; y < height; y++)
-				{
-					memcpy(destBuffer, sourceBuffer, pitch);   // FIXME: Only copy width * bytes
-
-					sourceBuffer += pitch;
-					destBuffer += pitch;
-				}
-
-				source->unlockStencil();
-				dest->unlockStencil();
-			}
-		}
-		else if(!scaling && equalFormats)
-		{
-			unsigned char *sourceBytes = (unsigned char*)source->lockInternal(sRect.x0, sRect.y0, sRect.slice, LOCK_READONLY, PUBLIC);
-			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, LOCK_READWRITE, PUBLIC);
-			unsigned int sourcePitch = source->getInternalPitchB();
-			unsigned int destPitch = dest->getInternalPitchB();
-
-			unsigned int width = dRect.x1 - dRect.x0;
-			unsigned int height = dRect.y1 - dRect.y0;
-			unsigned int bytes = width * Image::bytes(source->getInternalFormat());
-
-			for(unsigned int y = 0; y < height; y++)
-			{
-				memcpy(destBytes, sourceBytes, bytes);
-
-				if(alpha0xFF)
-				{
-					for(unsigned int x = 0; x < width; x++)
-					{
-						destBytes[4 * x + 3] = 0xFF;
-					}
-				}
-
-				sourceBytes += sourcePitch;
-				destBytes += destPitch;
-			}
-
-			source->unlockInternal();
-			dest->unlockInternal();
-		}
-		else
-		{
-			sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice);
-			blit(source, sRectF, dest, dRect, scaling && filter);
-		}
-
-		return true;
-	}
-
-	bool Device::bindResources()
-	{
-		if(!bindViewport())
-		{
-			return false;   // Zero-area target region
-		}
-
-		bindShaderConstants();
-
-		return true;
-	}
-
-	void Device::bindShaderConstants()
-	{
-		if(pixelShaderDirty)
-		{
-			if(pixelShader)
-			{
-				if(pixelShaderConstantsFDirty)
-				{
-					Renderer::setPixelShaderConstantF(0, pixelShaderConstantF[0], pixelShaderConstantsFDirty);
-				}
-
-				Renderer::setPixelShader(pixelShader);   // Loads shader constants set with DEF
-				pixelShaderConstantsFDirty = pixelShader->dirtyConstantsF;   // Shader DEF'ed constants are dirty
-			}
-			else
-			{
-				setPixelShader(0);
-			}
-
-			pixelShaderDirty = false;
-		}
-
-		if(vertexShaderDirty)
-		{
-			if(vertexShader)
-			{
-				if(vertexShaderConstantsFDirty)
-				{
-					Renderer::setVertexShaderConstantF(0, vertexShaderConstantF[0], vertexShaderConstantsFDirty);
-				}
-
-				Renderer::setVertexShader(vertexShader);   // Loads shader constants set with DEF
-				vertexShaderConstantsFDirty = vertexShader->dirtyConstantsF;   // Shader DEF'ed constants are dirty
-			}
-			else
-			{
-				setVertexShader(0);
-			}
-
-			vertexShaderDirty = false;
-		}
-	}
-
-	bool Device::bindViewport()
-	{
-		if(viewport.width <= 0 || viewport.height <= 0)
-		{
-			return false;
-		}
-
-		if(scissorEnable)
-		{
-			if(scissorRect.x0 >= scissorRect.x1 || scissorRect.y0 >= scissorRect.y1)
-			{
-				return false;
-			}
-
-			sw::Rect scissor;
-			scissor.x0 = scissorRect.x0;
-			scissor.x1 = scissorRect.x1;
-			scissor.y0 = scissorRect.y0;
-			scissor.y1 = scissorRect.y1;
-
-			setScissor(scissor);
-		}
-		else
-		{
-			sw::Rect scissor;
-			scissor.x0 = viewport.x0;
-			scissor.x1 = viewport.x0 + viewport.width;
-			scissor.y0 = viewport.y0;
-			scissor.y1 = viewport.y0 + viewport.height;
-
-			if(renderTarget)
-			{
-				scissor.x0 = max(scissor.x0, 0);
-				scissor.x1 = min(scissor.x1, renderTarget->getWidth());
-				scissor.y0 = max(scissor.y0, 0);
-				scissor.y1 = min(scissor.y1, renderTarget->getHeight());
-			}
-
-			if(depthStencil)
-			{
-				scissor.x0 = max(scissor.x0, 0);
-				scissor.x1 = min(scissor.x1, depthStencil->getWidth());
-				scissor.y0 = max(scissor.y0, 0);
-				scissor.y1 = min(scissor.y1, depthStencil->getHeight());
-			}
-
-			setScissor(scissor);
-		}
-
-		sw::Viewport view;
-		view.x0 = (float)viewport.x0;
-		view.y0 = (float)viewport.y0;
-		view.width = (float)viewport.width;
-		view.height = (float)viewport.height;
-		view.minZ = viewport.minZ;
-		view.maxZ = viewport.maxZ;
-
-		Renderer::setViewport(view);
-
-		return true;
-	}
-
-	bool Device::validRectangle(const sw::Rect *rect, Image *surface)
-	{
-		if(!rect)
-		{
-			return true;
-		}
-
-		if(rect->x1 <= rect->x0 || rect->y1 <= rect->y0)
-		{
-			return false;
-		}
-
-		if(rect->x0 < 0 || rect->y0 < 0)
-		{
-			return false;
-		}
-
-		if(rect->x1 > (int)surface->getWidth() || rect->y1 > (int)surface->getHeight())
-		{
-			return false;
-		}
-
-		return true;
-	}
-
-	void Device::finish()
-	{
-		synchronize();
-	}
-}
diff --git a/src/OpenGL/libGL/Device.hpp b/src/OpenGL/libGL/Device.hpp
deleted file mode 100644
index b58d309..0000000
--- a/src/OpenGL/libGL/Device.hpp
+++ /dev/null
@@ -1,106 +0,0 @@
-// 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.
-
-#ifndef gl_Device_hpp
-#define gl_Device_hpp
-
-#include "Renderer/Renderer.hpp"
-
-namespace gl
-{
-	class Image;
-	class Texture;
-
-	enum PrimitiveType
-	{
-		DRAW_POINTLIST,
-		DRAW_LINELIST,
-		DRAW_LINESTRIP,
-		DRAW_LINELOOP,
-		DRAW_TRIANGLELIST,
-		DRAW_TRIANGLESTRIP,
-		DRAW_TRIANGLEFAN,
-		DRAW_QUADLIST
-	};
-
-	struct Viewport
-	{
-		int x0;
-		int y0;
-		unsigned int width;
-		unsigned int height;
-		float minZ;
-		float maxZ;
-	};
-
-	class Device : public sw::Renderer
-	{
-	public:
-		explicit Device(sw::Context *context);
-
-		virtual ~Device();
-
-		void *operator new(size_t size);
-		void operator delete(void * mem);
-
-		void clearColor(float red, float green, float blue, float alpha, unsigned int rgbaMask);
-		void clearDepth(float z);
-		void clearStencil(unsigned int stencil, unsigned int mask);
-		Image *createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
-		Image *createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable);
-		void drawIndexedPrimitive(PrimitiveType type, unsigned int indexOffset, unsigned int primitiveCount, int indexSize);
-		void drawPrimitive(PrimitiveType primitiveType, unsigned int primiveCount);
-		void setDepthStencilSurface(Image *newDepthStencil);
-		void setPixelShader(sw::PixelShader *shader);
-		void setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
-		void setScissorEnable(bool enable);
-		void setRenderTarget(int index, Image *renderTarget);
-		void setScissorRect(const sw::Rect &rect);
-		void setVertexShader(sw::VertexShader *shader);
-		void setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count);
-		void setViewport(const Viewport &viewport);
-
-		virtual bool stretchRect(Image *sourceSurface, const sw::SliceRect *sourceRect, Image *destSurface, const sw::SliceRect *destRect, bool filter);
-		virtual void finish();
-
-	private:
-		sw::Context *const context;
-
-		bool bindResources();
-		void bindShaderConstants();
-		bool bindViewport();   // Also adjusts for scissoring
-
-		bool validRectangle(const sw::Rect *rect, Image *surface);
-
-		Viewport viewport;
-		sw::Rect scissorRect;
-		bool scissorEnable;
-
-		sw::PixelShader *pixelShader;
-		sw::VertexShader *vertexShader;
-
-		bool pixelShaderDirty;
-		unsigned int pixelShaderConstantsFDirty;
-		bool vertexShaderDirty;
-		unsigned int vertexShaderConstantsFDirty;
-
-		float pixelShaderConstantF[sw::FRAGMENT_UNIFORM_VECTORS][4];
-		float vertexShaderConstantF[sw::VERTEX_UNIFORM_VECTORS][4];
-
-		Image *renderTarget;
-		Image *depthStencil;
-	};
-}
-
-#endif   // gl_Device_hpp
diff --git a/src/OpenGL/libGL/Display.cpp b/src/OpenGL/libGL/Display.cpp
deleted file mode 100644
index 8c0f425..0000000
--- a/src/OpenGL/libGL/Display.cpp
+++ /dev/null
@@ -1,250 +0,0 @@
-// 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.
-
-// Display.cpp: Implements the Display class, representing the abstract
-// display on which graphics are drawn.
-
-#include "Display.h"
-
-#include "main.h"
-#include "mathutil.h"
-#include "Device.hpp"
-#include "common/debug.h"
-
-#include <algorithm>
-#include <vector>
-#include <map>
-
-namespace gl
-{
-typedef std::map<NativeDisplayType, Display*> DisplayMap;
-DisplayMap displays;
-
-Display *Display::getDisplay(NativeDisplayType displayId)
-{
-	if(displays.find(displayId) != displays.end())
-	{
-		return displays[displayId];
-	}
-
-	// FIXME: Check if displayId is a valid display device context
-	Display *display = new Display(displayId);
-
-	displays[displayId] = display;
-	return display;
-}
-
-Display::Display(NativeDisplayType displayId) : displayId(displayId)
-{
-	mMinSwapInterval = 1;
-	mMaxSwapInterval = 0;
-}
-
-Display::~Display()
-{
-	terminate();
-
-	displays.erase(displayId);
-}
-
-static void cpuid(int registers[4], int info)
-{
-	#if defined(_WIN32)
-		__cpuid(registers, info);
-	#else
-		__asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
-	#endif
-}
-
-static bool detectSSE()
-{
-	#if defined(__APPLE__)
-		int SSE = false;
-		size_t length = sizeof(SSE);
-		sysctlbyname("hw.optional.sse", &SSE, &length, 0, 0);
-		return SSE;
-	#else
-		int registers[4];
-		cpuid(registers, 1);
-		return (registers[3] & 0x02000000) != 0;
-	#endif
-}
-
-bool Display::initialize()
-{
-	if(isInitialized())
-	{
-		return true;
-	}
-
-	if(!detectSSE())
-	{
-		 return false;
-	}
-
-	mMinSwapInterval = 0;
-	mMaxSwapInterval = 4;
-
-	if(!isInitialized())
-	{
-		terminate();
-
-		return false;
-	}
-
-	return true;
-}
-
-void Display::terminate()
-{
-	while(!mSurfaceSet.empty())
-	{
-		destroySurface(*mSurfaceSet.begin());
-	}
-
-	while(!mContextSet.empty())
-	{
-		destroyContext(*mContextSet.begin());
-	}
-}
-
-gl::Context *Display::createContext(const gl::Context *shareContext)
-{
-	gl::Context *context = new gl::Context(shareContext);
-	mContextSet.insert(context);
-
-	return context;
-}
-
-void Display::destroySurface(Surface *surface)
-{
-	delete surface;
-	mSurfaceSet.erase(surface);
-}
-
-void Display::destroyContext(gl::Context *context)
-{
-	delete context;
-
-	if(context == gl::getContext())
-	{
-		gl::makeCurrent(nullptr, nullptr, nullptr);
-	}
-
-	mContextSet.erase(context);
-}
-
-bool Display::isInitialized() const
-{
-	return mMinSwapInterval <= mMaxSwapInterval;
-}
-
-bool Display::isValidContext(gl::Context *context)
-{
-	return mContextSet.find(context) != mContextSet.end();
-}
-
-bool Display::isValidSurface(Surface *surface)
-{
-	return mSurfaceSet.find(surface) != mSurfaceSet.end();
-}
-
-bool Display::isValidWindow(NativeWindowType window)
-{
-	#if defined(_WIN32)
-		return IsWindow(window) == TRUE;
-	#else
-		XWindowAttributes windowAttributes;
-		Status status = XGetWindowAttributes(displayId, window, &windowAttributes);
-
-		return status == True;
-	#endif
-}
-
-GLint Display::getMinSwapInterval()
-{
-	return mMinSwapInterval;
-}
-
-GLint Display::getMaxSwapInterval()
-{
-	return mMaxSwapInterval;
-}
-
-Surface *Display::getPrimarySurface()
-{
-	if(mSurfaceSet.size() == 0)
-	{
-		Surface *surface = new Surface(this, WindowFromDC(displayId));
-
-		if(!surface->initialize())
-		{
-			delete surface;
-			return 0;
-		}
-
-		mSurfaceSet.insert(surface);
-
-		gl::setCurrentDrawSurface(surface);
-	}
-
-	return *mSurfaceSet.begin();
-}
-
-NativeDisplayType Display::getNativeDisplay() const
-{
-	return displayId;
-}
-
-DisplayMode Display::getDisplayMode() const
-{
-	DisplayMode displayMode = {0};
-
-	#if defined(_WIN32)
-		HDC deviceContext = GetDC(0);
-
-		displayMode.width = ::GetDeviceCaps(deviceContext, HORZRES);
-		displayMode.height = ::GetDeviceCaps(deviceContext, VERTRES);
-		unsigned int bpp = ::GetDeviceCaps(deviceContext, BITSPIXEL);
-
-		switch(bpp)
-		{
-		case 32: displayMode.format = sw::FORMAT_X8R8G8B8; break;
-		case 24: displayMode.format = sw::FORMAT_R8G8B8;   break;
-		case 16: displayMode.format = sw::FORMAT_R5G6B5;   break;
-		default:
-			ASSERT(false);   // Unexpected display mode color depth
-		}
-
-		ReleaseDC(0, deviceContext);
-	#else
-		Screen *screen = XDefaultScreenOfDisplay(displayId);
-		displayMode.width = XWidthOfScreen(screen);
-		displayMode.height = XHeightOfScreen(screen);
-		unsigned int bpp = XPlanesOfScreen(screen);
-
-		switch(bpp)
-		{
-		case 32: displayMode.format = sw::FORMAT_X8R8G8B8; break;
-		case 24: displayMode.format = sw::FORMAT_R8G8B8;   break;
-		case 16: displayMode.format = sw::FORMAT_R5G6B5;   break;
-		default:
-			ASSERT(false);   // Unexpected display mode color depth
-		}
-	#endif
-
-	return displayMode;
-}
-
-}
diff --git a/src/OpenGL/libGL/Display.h b/src/OpenGL/libGL/Display.h
deleted file mode 100644
index c3c26a4..0000000
--- a/src/OpenGL/libGL/Display.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// 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.
-
-// Display.h: Defines the Display class, representing the abstract
-// display on which graphics are drawn.
-
-#ifndef INCLUDE_DISPLAY_H_
-#define INCLUDE_DISPLAY_H_
-
-#include "Surface.h"
-#include "Context.h"
-#include "Device.hpp"
-
-#include <set>
-
-namespace gl
-{
-	struct DisplayMode
-	{
-		unsigned int width;
-		unsigned int height;
-		sw::Format format;
-	};
-
-	class Display
-	{
-	public:
-		~Display();
-
-		static Display *getDisplay(NativeDisplayType displayId);
-
-		bool initialize();
-		void terminate();
-
-		Context *createContext(const Context *shareContext);
-
-		void destroySurface(Surface *surface);
-		void destroyContext(Context *context);
-
-		bool isInitialized() const;
-		bool isValidContext(Context *context);
-		bool isValidSurface(Surface *surface);
-		bool isValidWindow(NativeWindowType window);
-
-		GLint getMinSwapInterval();
-		GLint getMaxSwapInterval();
-
-		virtual Surface *getPrimarySurface();
-
-		NativeDisplayType getNativeDisplay() const;
-
-	private:
-		Display(NativeDisplayType displayId);
-
-		DisplayMode getDisplayMode() const;
-
-		const NativeDisplayType displayId;
-
-		GLint mMaxSwapInterval;
-		GLint mMinSwapInterval;
-
-		typedef std::set<Surface*> SurfaceSet;
-		SurfaceSet mSurfaceSet;
-
-		typedef std::set<Context*> ContextSet;
-		ContextSet mContextSet;
-	};
-}
-
-#endif   // INCLUDE_DISPLAY_H_
diff --git a/src/OpenGL/libGL/Fence.cpp b/src/OpenGL/libGL/Fence.cpp
deleted file mode 100644
index a59013e..0000000
--- a/src/OpenGL/libGL/Fence.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-// 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.
-
-// Fence.cpp: Implements the Fence class, which supports the GL_NV_fence extension.
-
-#include "Fence.h"
-
-#include "main.h"
-#include "Common/Thread.hpp"
-
-namespace gl
-{
-
-Fence::Fence()
-{ 
-	mQuery = false;
-	mCondition = GL_NONE;
-	mStatus = GL_FALSE;
-}
-
-Fence::~Fence()
-{
-	mQuery = false;
-}
-
-GLboolean Fence::isFence()
-{
-	// GL_NV_fence spec:
-	// A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
-	return mQuery;
-}
-
-void Fence::setFence(GLenum condition)
-{
-	if(condition != GL_ALL_COMPLETED_NV)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	mQuery = true;
-	mCondition = condition;
-	mStatus = GL_FALSE;
-}
-
-GLboolean Fence::testFence()
-{
-	if(!mQuery)
-	{
-		return error(GL_INVALID_OPERATION, GL_TRUE);
-	}
-
-	// The current assumtion is that no matter where the fence is placed, it is
-	// done by the time it is tested, which is similar to Context::flush(), since
-	// we don't queue anything without processing it as fast as possible.
-	mStatus = GL_TRUE;
-
-	return mStatus;
-}
-
-void Fence::finishFence()
-{
-	if(!mQuery)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	while(!testFence())
-	{
-		sw::Thread::yield();
-	}
-}
-
-void Fence::getFenceiv(GLenum pname, GLint *params)
-{
-	if(!mQuery)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	switch(pname)
-	{
-	case GL_FENCE_STATUS_NV:
-		{
-			// GL_NV_fence spec:
-			// Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
-			// or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
-			if(mStatus)
-			{
-				params[0] = GL_TRUE;
-				return;
-			}
-
-			mStatus = testFence();
-
-			params[0] = mStatus;            
-			break;
-		}
-	case GL_FENCE_CONDITION_NV:
-		params[0] = mCondition;
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-		break;
-	}
-}
-
-}
diff --git a/src/OpenGL/libGL/Fence.h b/src/OpenGL/libGL/Fence.h
deleted file mode 100644
index f7270eb..0000000
--- a/src/OpenGL/libGL/Fence.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.
-
-// Fence.h: Defines the Fence class, which supports the GL_NV_fence extension.
-
-#ifndef LIBGL_FENCE_H_
-#define LIBGL_FENCE_H_
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-namespace gl
-{
-
-class Fence
-{
-public:
-	Fence();
-	virtual ~Fence();
-
-	GLboolean isFence();
-	void setFence(GLenum condition);
-	GLboolean testFence();
-	void finishFence();
-	void getFenceiv(GLenum pname, GLint *params);
-
-private:
-	bool mQuery;
-	GLenum mCondition;
-	GLboolean mStatus;
-};
-
-}
-
-#endif   // LIBGL_FENCE_H_
diff --git a/src/OpenGL/libGL/Framebuffer.cpp b/src/OpenGL/libGL/Framebuffer.cpp
deleted file mode 100644
index 1bef3fb..0000000
--- a/src/OpenGL/libGL/Framebuffer.cpp
+++ /dev/null
@@ -1,423 +0,0 @@
-// 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.
-
-// Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer
-// objects and related functionality.
-
-#include "Framebuffer.h"
-
-#include "main.h"
-#include "Renderbuffer.h"
-#include "Texture.h"
-#include "utilities.h"
-
-namespace gl
-{
-
-Framebuffer::Framebuffer()
-{
-	mColorbufferType = GL_NONE;
-	mDepthbufferType = GL_NONE;
-	mStencilbufferType = GL_NONE;
-}
-
-Framebuffer::~Framebuffer()
-{
-	mColorbufferPointer = nullptr;
-	mDepthbufferPointer = nullptr;
-	mStencilbufferPointer = nullptr;
-}
-
-Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
-{
-	Context *context = getContext();
-	Renderbuffer *buffer = nullptr;
-
-	if(type == GL_NONE)
-	{
-		buffer = nullptr;
-	}
-	else if(type == GL_RENDERBUFFER)
-	{
-		buffer = context->getRenderbuffer(handle);
-	}
-	else if(IsTextureTarget(type))
-	{
-		buffer = context->getTexture(handle)->getRenderbuffer(type);
-	}
-	else UNREACHABLE(type);
-
-	return buffer;
-}
-
-void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
-{
-	mColorbufferType = (colorbuffer != 0) ? type : GL_NONE;
-	mColorbufferPointer = lookupRenderbuffer(type, colorbuffer);
-}
-
-void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
-{
-	mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
-	mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer);
-}
-
-void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
-{
-	mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
-	mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer);
-}
-
-void Framebuffer::detachTexture(GLuint texture)
-{
-	if(mColorbufferPointer.name() == texture && IsTextureTarget(mColorbufferType))
-	{
-		mColorbufferType = GL_NONE;
-		mColorbufferPointer = nullptr;
-	}
-
-	if(mDepthbufferPointer.name() == texture && IsTextureTarget(mDepthbufferType))
-	{
-		mDepthbufferType = GL_NONE;
-		mDepthbufferPointer = nullptr;
-	}
-
-	if(mStencilbufferPointer.name() == texture && IsTextureTarget(mStencilbufferType))
-	{
-		mStencilbufferType = GL_NONE;
-		mStencilbufferPointer = nullptr;
-	}
-}
-
-void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
-{
-	if(mColorbufferPointer.name() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
-	{
-		mColorbufferType = GL_NONE;
-		mColorbufferPointer = nullptr;
-	}
-
-	if(mDepthbufferPointer.name() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
-	{
-		mDepthbufferType = GL_NONE;
-		mDepthbufferPointer = nullptr;
-	}
-
-	if(mStencilbufferPointer.name() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
-	{
-		mStencilbufferType = GL_NONE;
-		mStencilbufferPointer = nullptr;
-	}
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-Image *Framebuffer::getRenderTarget()
-{
-	Renderbuffer *colorbuffer = mColorbufferPointer;
-
-	if(colorbuffer)
-	{
-		return colorbuffer->getRenderTarget();
-	}
-
-	return nullptr;
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-Image *Framebuffer::getDepthStencil()
-{
-	Renderbuffer *depthstencilbuffer = mDepthbufferPointer;
-
-	if(!depthstencilbuffer)
-	{
-		depthstencilbuffer = mStencilbufferPointer;
-	}
-
-	if(depthstencilbuffer)
-	{
-		return depthstencilbuffer->getRenderTarget();
-	}
-
-	return nullptr;
-}
-
-Renderbuffer *Framebuffer::getColorbuffer()
-{
-	return mColorbufferPointer;
-}
-
-Renderbuffer *Framebuffer::getDepthbuffer()
-{
-	return mDepthbufferPointer;
-}
-
-Renderbuffer *Framebuffer::getStencilbuffer()
-{
-	return mStencilbufferPointer;
-}
-
-GLenum Framebuffer::getColorbufferType()
-{
-	return mColorbufferType;
-}
-
-GLenum Framebuffer::getDepthbufferType()
-{
-	return mDepthbufferType;
-}
-
-GLenum Framebuffer::getStencilbufferType()
-{
-	return mStencilbufferType;
-}
-
-GLuint Framebuffer::getColorbufferName()
-{
-	return mColorbufferPointer.name();
-}
-
-GLuint Framebuffer::getDepthbufferName()
-{
-	return mDepthbufferPointer.name();
-}
-
-GLuint Framebuffer::getStencilbufferName()
-{
-	return mStencilbufferPointer.name();
-}
-
-bool Framebuffer::hasStencil()
-{
-	if(mStencilbufferType != GL_NONE)
-	{
-		Renderbuffer *stencilbufferObject = getStencilbuffer();
-
-		if(stencilbufferObject)
-		{
-			return stencilbufferObject->getStencilSize() > 0;
-		}
-	}
-
-	return false;
-}
-
-GLenum Framebuffer::completeness()
-{
-	int width;
-	int height;
-	int samples;
-
-	return completeness(width, height, samples);
-}
-
-GLenum Framebuffer::completeness(int &width, int &height, int &samples)
-{
-	width = -1;
-	height = -1;
-	samples = -1;
-
-	if(mColorbufferType != GL_NONE)
-	{
-		Renderbuffer *colorbuffer = getColorbuffer();
-
-		if(!colorbuffer)
-		{
-			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-		}
-
-		if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
-		{
-			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-		}
-
-		if(mColorbufferType == GL_RENDERBUFFER)
-		{
-			if(!gl::IsColorRenderable(colorbuffer->getFormat()))
-			{
-				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-			}
-		}
-		else if(IsTextureTarget(mColorbufferType))
-		{
-			GLenum format = colorbuffer->getFormat();
-
-			if(IsCompressed(format) ||
-			   format == GL_ALPHA ||
-			   format == GL_LUMINANCE ||
-			   format == GL_LUMINANCE_ALPHA)
-			{
-				return GL_FRAMEBUFFER_UNSUPPORTED;
-			}
-
-			if(gl::IsDepthTexture(format) || gl::IsStencilTexture(format))
-			{
-				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-			}
-		}
-		else
-		{
-			UNREACHABLE(mColorbufferType);
-			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-		}
-
-		width = colorbuffer->getWidth();
-		height = colorbuffer->getHeight();
-		samples = colorbuffer->getSamples();
-	}
-
-	Renderbuffer *depthbuffer = nullptr;
-	Renderbuffer *stencilbuffer = nullptr;
-
-	if(mDepthbufferType != GL_NONE)
-	{
-		depthbuffer = getDepthbuffer();
-
-		if(!depthbuffer)
-		{
-			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-		}
-
-		if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
-		{
-			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-		}
-
-		if(mDepthbufferType == GL_RENDERBUFFER)
-		{
-			if(!gl::IsDepthRenderable(depthbuffer->getFormat()))
-			{
-				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-			}
-		}
-		else if(IsTextureTarget(mDepthbufferType))
-		{
-			if(!gl::IsDepthTexture(depthbuffer->getFormat()))
-			{
-				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-			}
-		}
-		else
-		{
-			UNREACHABLE(mDepthbufferType);
-			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-		}
-
-		if(width == -1 || height == -1)
-		{
-			width = depthbuffer->getWidth();
-			height = depthbuffer->getHeight();
-			samples = depthbuffer->getSamples();
-		}
-		else if(width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
-		{
-			return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT;
-		}
-		else if(samples != depthbuffer->getSamples())
-		{
-			return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
-		}
-	}
-
-	if(mStencilbufferType != GL_NONE)
-	{
-		stencilbuffer = getStencilbuffer();
-
-		if(!stencilbuffer)
-		{
-			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-		}
-
-		if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
-		{
-			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-		}
-
-		if(mStencilbufferType == GL_RENDERBUFFER)
-		{
-			if(!gl::IsStencilRenderable(stencilbuffer->getFormat()))
-			{
-				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-			}
-		}
-		else if(IsTextureTarget(mStencilbufferType))
-		{
-			GLenum internalformat = stencilbuffer->getFormat();
-
-			if(!gl::IsStencilTexture(internalformat))
-			{
-				return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-			}
-		}
-		else
-		{
-			UNREACHABLE(mStencilbufferType);
-			return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-		}
-
-		if(width == -1 || height == -1)
-		{
-			width = stencilbuffer->getWidth();
-			height = stencilbuffer->getHeight();
-			samples = stencilbuffer->getSamples();
-		}
-		else if(width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
-		{
-			return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT;
-		}
-		else if(samples != stencilbuffer->getSamples())
-		{
-			return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
-		}
-	}
-
-	// If we have both a depth and stencil buffer, they must refer to the same object
-	// since we only support packed_depth_stencil and not separate depth and stencil
-	if(depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
-	{
-		return GL_FRAMEBUFFER_UNSUPPORTED;
-	}
-
-	// We need to have at least one attachment to be complete
-	if(width == -1 || height == -1)
-	{
-		return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
-	}
-
-	return GL_FRAMEBUFFER_COMPLETE;
-}
-
-DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
-{
-	mColorbufferPointer = new Renderbuffer(0, colorbuffer);
-
-	Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
-	mDepthbufferPointer = depthStencilRenderbuffer;
-	mStencilbufferPointer = depthStencilRenderbuffer;
-
-	mColorbufferType = GL_RENDERBUFFER;
-	mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
-	mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
-}
-
-GLenum DefaultFramebuffer::completeness()
-{
-	// The default framebuffer should always be complete
-	ASSERT(Framebuffer::completeness() == GL_FRAMEBUFFER_COMPLETE);
-
-	return GL_FRAMEBUFFER_COMPLETE;
-}
-
-}
diff --git a/src/OpenGL/libGL/Framebuffer.h b/src/OpenGL/libGL/Framebuffer.h
deleted file mode 100644
index 06dc8fe..0000000
--- a/src/OpenGL/libGL/Framebuffer.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// 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.
-
-// Framebuffer.h: Defines the Framebuffer class. Implements GL framebuffer
-// objects and related functionality.
-
-#ifndef LIBGL_FRAMEBUFFER_H_
-#define LIBGL_FRAMEBUFFER_H_
-
-#include "common/Object.hpp"
-#include "Image.hpp"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-namespace gl
-{
-class Renderbuffer;
-class Colorbuffer;
-class Depthbuffer;
-class Stencilbuffer;
-class DepthStencilbuffer;
-
-class Framebuffer
-{
-public:
-	Framebuffer();
-
-	virtual ~Framebuffer();
-
-	void setColorbuffer(GLenum type, GLuint colorbuffer);
-	void setDepthbuffer(GLenum type, GLuint depthbuffer);
-	void setStencilbuffer(GLenum type, GLuint stencilbuffer);
-
-	void detachTexture(GLuint texture);
-	void detachRenderbuffer(GLuint renderbuffer);
-
-	Image *getRenderTarget();
-	Image *getDepthStencil();
-
-	Renderbuffer *getColorbuffer();
-	Renderbuffer *getDepthbuffer();
-	Renderbuffer *getStencilbuffer();
-
-	GLenum getColorbufferType();
-	GLenum getDepthbufferType();
-	GLenum getStencilbufferType();
-
-	GLuint getColorbufferName();
-	GLuint getDepthbufferName();
-	GLuint getStencilbufferName();
-
-	bool hasStencil();
-
-	virtual GLenum completeness();
-	GLenum completeness(int &width, int &height, int &samples);
-
-protected:
-	GLenum mColorbufferType;
-	BindingPointer<Renderbuffer> mColorbufferPointer;
-
-	GLenum mDepthbufferType;
-	BindingPointer<Renderbuffer> mDepthbufferPointer;
-
-	GLenum mStencilbufferType;
-	BindingPointer<Renderbuffer> mStencilbufferPointer;
-
-private:
-	Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;
-};
-
-class DefaultFramebuffer : public Framebuffer
-{
-public:
-	DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
-
-	virtual GLenum completeness();
-};
-
-}
-
-#endif   // LIBGL_FRAMEBUFFER_H_
diff --git a/src/OpenGL/libGL/Image.cpp b/src/OpenGL/libGL/Image.cpp
deleted file mode 100644
index b86b689..0000000
--- a/src/OpenGL/libGL/Image.cpp
+++ /dev/null
@@ -1,716 +0,0 @@
-// 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.
-
-#include "Image.hpp"
-
-#include "Texture.h"
-#include "utilities.h"
-#include "../common/debug.h"
-#include "Common/Thread.hpp"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-namespace gl
-{
-	static sw::Resource *getParentResource(Texture *texture)
-	{
-		if(texture)
-		{
-			return texture->getResource();
-		}
-
-		return nullptr;
-	}
-
-	Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type)
-		: sw::Surface(getParentResource(parentTexture), width, height, 1, 0, 1, selectInternalFormat(format, type), true, true)
-		, parentTexture(parentTexture), width(width), height(height), format(format), type(type)
-		, internalFormat(selectInternalFormat(format, type)), multiSampleDepth(1)
-	{
-		referenceCount = 1;
-	}
-
-	Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable, bool renderTarget)
-		: sw::Surface(getParentResource(parentTexture), width, height, 1, 0, multiSampleDepth, internalFormat, lockable, renderTarget)
-		, parentTexture(parentTexture), width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), multiSampleDepth(multiSampleDepth)
-	{
-		referenceCount = 1;
-	}
-
-	Image::~Image()
-	{
-		ASSERT(referenceCount == 0);
-	}
-
-	void *Image::lock(unsigned int left, unsigned int top, sw::Lock lock)
-	{
-		return lockExternal(left, top, 0, lock, sw::PUBLIC);
-	}
-
-	unsigned int Image::getPitch() const
-	{
-		return getExternalPitchB();
-	}
-
-	void Image::unlock()
-	{
-		unlockExternal();
-	}
-
-	void *Image::lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)
-	{
-		return Surface::lockInternal(x, y, z, lock, client);
-	}
-
-	void Image::unlockInternal()
-	{
-		Surface::unlockInternal();
-	}
-
-	int Image::getWidth()
-	{
-		return width;
-	}
-
-	int Image::getHeight()
-	{
-		return height;
-	}
-
-	GLenum Image::getFormat()
-	{
-		return format;
-	}
-
-	GLenum Image::getType()
-	{
-		return type;
-	}
-
-	sw::Format Image::getInternalFormat()
-	{
-		return internalFormat;
-	}
-
-	int Image::getMultiSampleDepth()
-	{
-		return multiSampleDepth;
-	}
-
-	void Image::addRef()
-	{
-		if(parentTexture)
-		{
-			return parentTexture->addRef();
-		}
-
-		sw::atomicIncrement(&referenceCount);
-	}
-
-	void Image::release()
-	{
-		if(parentTexture)
-		{
-			return parentTexture->release();
-		}
-
-		if(referenceCount > 0)
-		{
-			sw::atomicDecrement(&referenceCount);
-		}
-
-		if(referenceCount == 0)
-		{
-			delete this;
-		}
-	}
-
-	void Image::unbind()
-	{
-		parentTexture = nullptr;
-
-		release();
-	}
-
-	sw::Format Image::selectInternalFormat(GLenum format, GLenum type)
-	{
-		if(type == GL_NONE && format == GL_NONE)
-		{
-			return sw::FORMAT_NULL;
-		}
-		else if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
-		        format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
-		{
-			return sw::FORMAT_DXT1;
-		}
-		else if(format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
-		{
-			return sw::FORMAT_DXT3;
-		}
-		else if(format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
-		{
-			return sw::FORMAT_DXT5;
-		}
-		else if(type == GL_FLOAT)
-		{
-			return sw::FORMAT_A32B32G32R32F;
-		}
-		else if(type == GL_HALF_FLOAT)
-		{
-			return sw::FORMAT_A16B16G16R16F;
-		}
-		else if(type == GL_UNSIGNED_BYTE)
-		{
-			if(format == GL_LUMINANCE)
-			{
-				return sw::FORMAT_L8;
-			}
-			else if(format == GL_LUMINANCE_ALPHA)
-			{
-				return sw::FORMAT_A8L8;
-			}
-			else if(format == GL_RGBA || format == GL_BGRA_EXT)
-			{
-				return sw::FORMAT_A8R8G8B8;
-			}
-			else if(format == GL_RGB)
-			{
-				return sw::FORMAT_X8R8G8B8;
-			}
-			else if(format == GL_ALPHA)
-			{
-				return sw::FORMAT_A8;
-			}
-			else UNREACHABLE(format);
-		}
-		else if(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT)
-		{
-			if(format == GL_DEPTH_COMPONENT)
-			{
-				return sw::FORMAT_D32FS8_TEXTURE;
-			}
-			else UNREACHABLE(format);
-		}
-		else if(type == GL_UNSIGNED_INT_24_8_EXT)
-		{
-			if(format == GL_DEPTH_STENCIL_EXT)
-			{
-				return sw::FORMAT_D32FS8_TEXTURE;
-			}
-			else UNREACHABLE(format);
-		}
-		else if(type == GL_UNSIGNED_SHORT_4_4_4_4)
-		{
-			return sw::FORMAT_A8R8G8B8;
-		}
-		else if(type == GL_UNSIGNED_SHORT_5_5_5_1)
-		{
-			return sw::FORMAT_A8R8G8B8;
-		}
-		else if(type == GL_UNSIGNED_SHORT_5_6_5)
-		{
-			return sw::FORMAT_R5G6B5;
-		}
-		else if(type == GL_UNSIGNED_INT_8_8_8_8_REV)
-		{
-			return sw::FORMAT_A8R8G8B8;
-		}
-
-		else UNREACHABLE(type);
-
-		return sw::FORMAT_A8R8G8B8;
-	}
-
-	void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input)
-	{
-		GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
-		void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
-
-		if(buffer)
-		{
-			switch(type)
-			{
-			case GL_UNSIGNED_BYTE:
-			case GL_UNSIGNED_INT_8_8_8_8_REV:
-				switch(format)
-				{
-				case GL_ALPHA:
-					loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_LUMINANCE:
-					loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_LUMINANCE_ALPHA:
-					loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_RGB:
-					loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_RGBA:
-					loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_BGRA_EXT:
-					loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				default: UNREACHABLE(format);
-				}
-				break;
-			case GL_UNSIGNED_SHORT_5_6_5:
-				switch(format)
-				{
-				case GL_RGB:
-					loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				default: UNREACHABLE(format);
-				}
-				break;
-			case GL_UNSIGNED_SHORT_4_4_4_4:
-				switch(format)
-				{
-				case GL_RGBA:
-					loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				default: UNREACHABLE(format);
-				}
-				break;
-			case GL_UNSIGNED_SHORT_5_5_5_1:
-				switch(format)
-				{
-				case GL_RGBA:
-					loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				default: UNREACHABLE(format);
-				}
-				break;
-			case GL_FLOAT:
-				switch(format)
-				{
-				// float textures are converted to RGBA, not BGRA
-				case GL_ALPHA:
-					loadAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_LUMINANCE:
-					loadLuminanceFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_LUMINANCE_ALPHA:
-					loadLuminanceAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_RGB:
-					loadRGBFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_RGBA:
-					loadRGBAFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				default: UNREACHABLE(format);
-				}
-				break;
-			case GL_HALF_FLOAT:
-				switch(format)
-				{
-				// float textures are converted to RGBA, not BGRA
-				case GL_ALPHA:
-					loadAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_LUMINANCE:
-					loadLuminanceHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_LUMINANCE_ALPHA:
-					loadLuminanceAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_RGB:
-					loadRGBHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				case GL_RGBA:
-					loadRGBAHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-					break;
-				default: UNREACHABLE(format);
-				}
-				break;
-			case GL_UNSIGNED_SHORT:
-				loadD16ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-				break;
-			case GL_UNSIGNED_INT:
-				loadD32ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-				break;
-			case GL_UNSIGNED_INT_24_8_EXT:
-				loadD24S8ImageData(xoffset, yoffset, width, height, inputPitch, input, buffer);
-				break;
-			default: UNREACHABLE(type);
-			}
-		}
-
-		unlock();
-	}
-
-	void Image::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
-			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset;
-
-			memcpy(dest, source, width);
-		}
-	}
-
-	void Image::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
-
-			for(int x = 0; x < width; x++)
-			{
-				dest[4 * x + 0] = 0;
-				dest[4 * x + 1] = 0;
-				dest[4 * x + 2] = 0;
-				dest[4 * x + 3] = source[x];
-			}
-		}
-	}
-
-	void Image::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
-
-			for(int x = 0; x < width; x++)
-			{
-				dest[4 * x + 0] = 0;
-				dest[4 * x + 1] = 0;
-				dest[4 * x + 2] = 0;
-				dest[4 * x + 3] = source[x];
-			}
-		}
-	}
-
-	void Image::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
-			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset;
-
-			memcpy(dest, source, width);
-		}
-	}
-
-	void Image::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
-
-			for(int x = 0; x < width; x++)
-			{
-				dest[4 * x + 0] = source[x];
-				dest[4 * x + 1] = source[x];
-				dest[4 * x + 2] = source[x];
-				dest[4 * x + 3] = 1.0f;
-			}
-		}
-	}
-
-	void Image::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
-
-			for(int x = 0; x < width; x++)
-			{
-				dest[4 * x + 0] = source[x];
-				dest[4 * x + 1] = source[x];
-				dest[4 * x + 2] = source[x];
-				dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
-			}
-		}
-	}
-
-	void Image::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
-			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2;
-
-			memcpy(dest, source, width * 2);
-		}
-	}
-
-	void Image::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
-
-			for(int x = 0; x < width; x++)
-			{
-				dest[4 * x + 0] = source[2*x+0];
-				dest[4 * x + 1] = source[2*x+0];
-				dest[4 * x + 2] = source[2*x+0];
-				dest[4 * x + 3] = source[2*x+1];
-			}
-		}
-	}
-
-	void Image::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
-
-			for(int x = 0; x < width; x++)
-			{
-				dest[4 * x + 0] = source[2*x+0];
-				dest[4 * x + 1] = source[2*x+0];
-				dest[4 * x + 2] = source[2*x+0];
-				dest[4 * x + 3] = source[2*x+1];
-			}
-		}
-	}
-
-	void Image::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
-			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
-
-			for(int x = 0; x < width; x++)
-			{
-				dest[4 * x + 0] = source[x * 3 + 2];
-				dest[4 * x + 1] = source[x * 3 + 1];
-				dest[4 * x + 2] = source[x * 3 + 0];
-				dest[4 * x + 3] = 0xFF;
-			}
-		}
-	}
-
-	void Image::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 2;
-
-			memcpy(dest, source, width * 2);
-		}
-	}
-
-	void Image::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
-
-			for(int x = 0; x < width; x++)
-			{
-				dest[4 * x + 0] = source[x * 3 + 0];
-				dest[4 * x + 1] = source[x * 3 + 1];
-				dest[4 * x + 2] = source[x * 3 + 2];
-				dest[4 * x + 3] = 1.0f;
-			}
-		}
-	}
-
-	void Image::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			unsigned short *dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8);
-
-			for(int x = 0; x < width; x++)
-			{
-				dest[4 * x + 0] = source[x * 3 + 0];
-				dest[4 * x + 1] = source[x * 3 + 1];
-				dest[4 * x + 2] = source[x * 3 + 2];
-				dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
-			}
-		}
-	}
-
-	void Image::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
-
-			for(int x = 0; x < width; x++)
-			{
-				unsigned int rgba = source[x];
-				dest[x] = (rgba & 0xFF00FF00) | ((rgba << 16) & 0x00FF0000) | ((rgba >> 16) & 0x000000FF);
-			}
-		}
-	}
-
-	void Image::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
-
-			for(int x = 0; x < width; x++)
-			{
-				unsigned short rgba = source[x];
-				dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
-				dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
-				dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
-				dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
-			}
-		}
-	}
-
-	void Image::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
-
-			for(int x = 0; x < width; x++)
-			{
-				unsigned short rgba = source[x];
-				dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
-				dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
-				dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
-				dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
-			}
-		}
-	}
-
-	void Image::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const float *source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 16);
-
-			memcpy(dest, source, width * 16);
-		}
-	}
-
-	void Image::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
-			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 8;
-
-			memcpy(dest, source, width * 8);
-		}
-	}
-
-	void Image::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
-			unsigned char *dest = static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4;
-
-			memcpy(dest, source, width*4);
-		}
-	}
-
-	void Image::loadD16ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned short *source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
-
-			for(int x = 0; x < width; x++)
-			{
-				dest[x] = (float)source[x] / 0xFFFF;
-			}
-		}
-	}
-
-	void Image::loadD32ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
-
-			for(int x = 0; x < width; x++)
-			{
-				dest[x] = (float)source[x] / 0xFFFFFFFF;
-			}
-		}
-	}
-
-	void Image::loadD24S8ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer)
-	{
-		for(int y = 0; y < height; y++)
-		{
-			const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-			float *dest = reinterpret_cast<float*>(static_cast<unsigned char*>(buffer) + (y + yoffset) * getPitch() + xoffset * 4);
-
-			for(int x = 0; x < width; x++)
-			{
-				dest[x] = (float)(source[x] & 0xFFFFFF00) / 0xFFFFFF00;
-			}
-		}
-
-		unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, 0, 0, sw::PUBLIC));
-
-		if(stencil)
-		{
-			for(int y = 0; y < height; y++)
-			{
-				const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
-				unsigned char *dest = static_cast<unsigned char*>(stencil) + (y + yoffset) * getStencilPitchB() + xoffset;
-
-				for(int x = 0; x < width; x++)
-				{
-					dest[x] = static_cast<unsigned char>(source[x] & 0x000000FF);   // FIXME: Quad layout
-				}
-			}
-
-			unlockStencil();
-		}
-	}
-
-	void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
-	{
-		int inputPitch = ComputeCompressedPitch(width, format);
-		int rows = imageSize / inputPitch;
-		void *buffer = lock(xoffset, yoffset, sw::LOCK_WRITEONLY);
-
-		if(buffer)
-		{
-			for(int i = 0; i < rows; i++)
-			{
-				memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch);
-			}
-		}
-
-		unlock();
-	}
-}
\ No newline at end of file
diff --git a/src/OpenGL/libGL/Image.hpp b/src/OpenGL/libGL/Image.hpp
deleted file mode 100644
index 2b74cf3..0000000
--- a/src/OpenGL/libGL/Image.hpp
+++ /dev/null
@@ -1,97 +0,0 @@
-// 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.
-
-#ifndef gl_Image_hpp
-#define gl_Image_hpp
-
-#include "Renderer/Surface.hpp"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-namespace gl
-{
-	class Texture;
-
-	class Image : public sw::Surface
-	{
-	public:
-		Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type);
-		Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, int multiSampleDepth, bool lockable, bool renderTarget);
-
-		void loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input);
-		void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
-
-		void *lock(unsigned int left, unsigned int top, sw::Lock lock);
-		unsigned int getPitch() const;
-		void unlock();
-
-		void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client) override;
-		void unlockInternal() override;
-
-		int getWidth();
-		int getHeight();
-		GLenum getFormat();
-		GLenum getType();
-		virtual sw::Format getInternalFormat();
-		int getMultiSampleDepth();
-
-		virtual void addRef();
-		virtual void release();
-		void unbind();   // Break parent ownership and release
-
-		static sw::Format selectInternalFormat(GLenum format, GLenum type);
-
-	private:
-		~Image() override;
-
-		void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadD16ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadD32ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const;
-		void loadD24S8ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer);
-
-		Texture *parentTexture;
-
-		const GLsizei width;
-		const GLsizei height;
-		const GLenum format;
-		const GLenum type;
-		const sw::Format internalFormat;
-		const int multiSampleDepth;
-
-		volatile int referenceCount;
-	};
-}
-
-#endif   // gl_Image_hpp
diff --git a/src/OpenGL/libGL/IndexDataManager.cpp b/src/OpenGL/libGL/IndexDataManager.cpp
deleted file mode 100644
index 30d056e..0000000
--- a/src/OpenGL/libGL/IndexDataManager.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-// 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.
-
-// IndexDataManager.cpp: Defines the IndexDataManager, a class that
-// runs the Buffer translation process for index buffers.
-
-#include "IndexDataManager.h"
-
-#include "Buffer.h"
-#include "common/debug.h"
-
-#include <string.h>
-#include <algorithm>
-
-namespace
-{
-	enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
-}
-
-namespace gl
-{
-
-IndexDataManager::IndexDataManager()
-{
-	mStreamingBuffer = new StreamingIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);
-
-	if(!mStreamingBuffer)
-	{
-		ERR("Failed to allocate the streaming index buffer.");
-	}
-}
-
-IndexDataManager::~IndexDataManager()
-{
-	delete mStreamingBuffer;
-}
-
-void copyIndices(GLenum type, const void *input, GLsizei count, void *output)
-{
-	if(type == GL_UNSIGNED_BYTE)
-	{
-		memcpy(output, input, count * sizeof(GLubyte));
-	}
-	else if(type == GL_UNSIGNED_INT)
-	{
-		memcpy(output, input, count * sizeof(GLuint));
-	}
-	else if(type == GL_UNSIGNED_SHORT)
-	{
-		memcpy(output, input, count * sizeof(GLushort));
-	}
-	else UNREACHABLE(type);
-}
-
-template<class IndexType>
-void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
-{
-	*minIndex = indices[0];
-	*maxIndex = indices[0];
-
-	for(GLsizei i = 0; i < count; i++)
-	{
-		if(*minIndex > indices[i]) *minIndex = indices[i];
-		if(*maxIndex < indices[i]) *maxIndex = indices[i];
-	}
-}
-
-void computeRange(GLenum type, const void *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
-{
-	if(type == GL_UNSIGNED_BYTE)
-	{
-		computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
-	}
-	else if(type == GL_UNSIGNED_INT)
-	{
-		computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
-	}
-	else if(type == GL_UNSIGNED_SHORT)
-	{
-		computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
-	}
-	else UNREACHABLE(type);
-}
-
-GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
-{
-	if(!mStreamingBuffer)
-	{
-		return GL_OUT_OF_MEMORY;
-	}
-
-	intptr_t offset = reinterpret_cast<intptr_t>(indices);
-	bool alignedOffset = false;
-
-	if(buffer)
-	{
-		switch(type)
-		{
-		case GL_UNSIGNED_BYTE:  alignedOffset = (offset % sizeof(GLubyte) == 0);  break;
-		case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
-		case GL_UNSIGNED_INT:   alignedOffset = (offset % sizeof(GLuint) == 0);   break;
-		default: UNREACHABLE(type); alignedOffset = false;
-		}
-
-		if(typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
-		{
-			return GL_INVALID_OPERATION;
-		}
-
-		indices = static_cast<const GLubyte*>(buffer->data()) + offset;
-	}
-
-	StreamingIndexBuffer *streamingBuffer = mStreamingBuffer;
-
-	sw::Resource *staticBuffer = buffer ? buffer->getResource() : nullptr;
-
-	if(staticBuffer)
-	{
-		computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-
-		translated->indexBuffer = staticBuffer;
-		translated->indexOffset = offset;
-	}
-	else
-	{
-		unsigned int streamOffset = 0;
-		int convertCount = count;
-
-		streamingBuffer->reserveSpace(convertCount * typeSize(type), type);
-		void *output = streamingBuffer->map(typeSize(type) * convertCount, &streamOffset);
-
-		if(!output)
-		{
-			ERR("Failed to map index buffer.");
-			return GL_OUT_OF_MEMORY;
-		}
-
-		copyIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
-		streamingBuffer->unmap();
-
-		computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-
-		translated->indexBuffer = streamingBuffer->getResource();
-		translated->indexOffset = streamOffset;
-	}
-
-	return GL_NO_ERROR;
-}
-
-std::size_t IndexDataManager::typeSize(GLenum type)
-{
-	switch(type)
-	{
-	case GL_UNSIGNED_INT:   return sizeof(GLuint);
-	case GL_UNSIGNED_SHORT: return sizeof(GLushort);
-	case GL_UNSIGNED_BYTE:  return sizeof(GLubyte);
-	default: UNREACHABLE(type); return sizeof(GLushort);
-	}
-}
-
-StreamingIndexBuffer::StreamingIndexBuffer(unsigned int initialSize) : mIndexBuffer(nullptr), mBufferSize(initialSize)
-{
-	if(initialSize > 0)
-	{
-		mIndexBuffer = new sw::Resource(initialSize + 16);
-
-		if(!mIndexBuffer)
-		{
-			ERR("Out of memory allocating an index buffer of size %u.", initialSize);
-		}
-	}
-
-	mWritePosition = 0;
-}
-
-StreamingIndexBuffer::~StreamingIndexBuffer()
-{
-	if(mIndexBuffer)
-	{
-		mIndexBuffer->destruct();
-	}
-}
-
-void *StreamingIndexBuffer::map(unsigned int requiredSpace, unsigned int *offset)
-{
-	void *mapPtr = nullptr;
-
-	if(mIndexBuffer)
-	{
-		mapPtr = (char*)mIndexBuffer->lock(sw::PUBLIC) + mWritePosition;
-
-		if(!mapPtr)
-		{
-			ERR(" Lock failed");
-			return nullptr;
-		}
-
-		*offset = mWritePosition;
-		mWritePosition += requiredSpace;
-	}
-
-	return mapPtr;
-}
-
-void StreamingIndexBuffer::unmap()
-{
-	if(mIndexBuffer)
-	{
-		mIndexBuffer->unlock();
-	}
-}
-
-void StreamingIndexBuffer::reserveSpace(unsigned int requiredSpace, GLenum type)
-{
-	if(requiredSpace > mBufferSize)
-	{
-		if(mIndexBuffer)
-		{
-			mIndexBuffer->destruct();
-			mIndexBuffer = 0;
-		}
-
-		mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
-
-		mIndexBuffer = new sw::Resource(mBufferSize + 16);
-
-		if(!mIndexBuffer)
-		{
-			ERR("Out of memory allocating an index buffer of size %u.", mBufferSize);
-		}
-
-		mWritePosition = 0;
-	}
-	else if(mWritePosition + requiredSpace > mBufferSize)   // Recycle
-	{
-		if(mIndexBuffer)
-		{
-			mIndexBuffer->destruct();
-			mIndexBuffer = new sw::Resource(mBufferSize + 16);
-		}
-
-		mWritePosition = 0;
-	}
-}
-
-sw::Resource *StreamingIndexBuffer::getResource() const
-{
-	return mIndexBuffer;
-}
-
-}
diff --git a/src/OpenGL/libGL/IndexDataManager.h b/src/OpenGL/libGL/IndexDataManager.h
deleted file mode 100644
index d1d6e54..0000000
--- a/src/OpenGL/libGL/IndexDataManager.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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.
-
-// IndexDataManager.h: Defines the IndexDataManager, a class that
-// runs the Buffer translation process for index buffers.
-
-#ifndef LIBGL_INDEXDATAMANAGER_H_
-#define LIBGL_INDEXDATAMANAGER_H_
-
-#include "Context.h"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-namespace gl
-{
-
-struct TranslatedIndexData
-{
-	unsigned int minIndex;
-	unsigned int maxIndex;
-	unsigned int indexOffset;
-
-	sw::Resource *indexBuffer;
-};
-
-class StreamingIndexBuffer
-{
-public:
-	StreamingIndexBuffer(unsigned int initialSize);
-	virtual ~StreamingIndexBuffer();
-
-	void *map(unsigned int requiredSpace, unsigned int *offset);
-	void unmap();
-	void reserveSpace(unsigned int requiredSpace, GLenum type);
-
-	sw::Resource *getResource() const;
-
-private:
-	sw::Resource *mIndexBuffer;
-	unsigned int mBufferSize;
-	unsigned int mWritePosition;
-};
-
-class IndexDataManager
-{
-public:
-	IndexDataManager();
-	virtual ~IndexDataManager();
-
-	GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
-
-	static std::size_t typeSize(GLenum type);
-
-private:
-	StreamingIndexBuffer *mStreamingBuffer;
-};
-
-}
-
-#endif   // LIBGL_INDEXDATAMANAGER_H_
diff --git a/src/OpenGL/libGL/Program.cpp b/src/OpenGL/libGL/Program.cpp
deleted file mode 100644
index 1a55bce..0000000
--- a/src/OpenGL/libGL/Program.cpp
+++ /dev/null
@@ -1,2287 +0,0 @@
-// 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.
-
-// Program.cpp: Implements the Program class. Implements GL program objects
-// and related functionality.
-
-#include "Program.h"
-
-#include "main.h"
-#include "Shader.h"
-#include "utilities.h"
-#include "common/debug.h"
-#include "Shader/PixelShader.hpp"
-#include "Shader/VertexShader.hpp"
-
-#include <string>
-#include <stdlib.h>
-
-namespace gl
-{
-	unsigned int Program::currentSerial = 1;
-
-	std::string str(int i)
-	{
-		char buffer[20];
-		sprintf(buffer, "%d", i);
-		return buffer;
-	}
-
-	Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize) : type(type), precision(precision), name(name), arraySize(arraySize)
-	{
-		int bytes = UniformTypeSize(type) * size();
-		data = new unsigned char[bytes];
-		memset(data, 0, bytes);
-		dirty = true;
-
-		psRegisterIndex = -1;
-		vsRegisterIndex = -1;
-	}
-
-	Uniform::~Uniform()
-	{
-		delete[] data;
-	}
-
-	bool Uniform::isArray() const
-	{
-		return arraySize >= 1;
-	}
-
-	int Uniform::size() const
-	{
-		return arraySize > 0 ? arraySize : 1;
-	}
-
-	int Uniform::registerCount() const
-	{
-		return size() * VariableRowCount(type);
-	}
-
-	UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index)
-	{
-	}
-
-	Program::Program(ResourceManager *manager, GLuint handle) : serial(issueSerial()), resourceManager(manager), handle(handle)
-	{
-		device = getDevice();
-
-		fragmentShader = 0;
-		vertexShader = 0;
-		pixelBinary = 0;
-		vertexBinary = 0;
-
-		infoLog = 0;
-		validated = false;
-
-		unlink();
-
-		orphaned = false;
-		referenceCount = 0;
-	}
-
-	Program::~Program()
-	{
-		unlink();
-
-		if(vertexShader)
-		{
-			vertexShader->release();
-		}
-
-		if(fragmentShader)
-		{
-			fragmentShader->release();
-		}
-	}
-
-	bool Program::attachShader(Shader *shader)
-	{
-		if(shader->getType() == GL_VERTEX_SHADER)
-		{
-			if(vertexShader)
-			{
-				return false;
-			}
-
-			vertexShader = (VertexShader*)shader;
-			vertexShader->addRef();
-		}
-		else if(shader->getType() == GL_FRAGMENT_SHADER)
-		{
-			if(fragmentShader)
-			{
-				return false;
-			}
-
-			fragmentShader = (FragmentShader*)shader;
-			fragmentShader->addRef();
-		}
-		else UNREACHABLE(shader->getType());
-
-		return true;
-	}
-
-	bool Program::detachShader(Shader *shader)
-	{
-		if(shader->getType() == GL_VERTEX_SHADER)
-		{
-			if(vertexShader != shader)
-			{
-				return false;
-			}
-
-			vertexShader->release();
-			vertexShader = 0;
-		}
-		else if(shader->getType() == GL_FRAGMENT_SHADER)
-		{
-			if(fragmentShader != shader)
-			{
-				return false;
-			}
-
-			fragmentShader->release();
-			fragmentShader = 0;
-		}
-		else UNREACHABLE(shader->getType());
-
-		return true;
-	}
-
-	int Program::getAttachedShadersCount() const
-	{
-		return (vertexShader ? 1 : 0) + (fragmentShader ? 1 : 0);
-	}
-
-	sw::PixelShader *Program::getPixelShader()
-	{
-		return pixelBinary;
-	}
-
-	sw::VertexShader *Program::getVertexShader()
-	{
-		return vertexBinary;
-	}
-
-	void Program::bindAttributeLocation(GLuint index, const char *name)
-	{
-		if(index < MAX_VERTEX_ATTRIBS)
-		{
-			for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-			{
-				attributeBinding[i].erase(name);
-			}
-
-			attributeBinding[index].insert(name);
-		}
-	}
-
-	GLuint Program::getAttributeLocation(const char *name)
-	{
-		if(name)
-		{
-			for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
-			{
-				if(linkedAttribute[index].name == std::string(name))
-				{
-					return index;
-				}
-			}
-		}
-
-		return -1;
-	}
-
-	int Program::getAttributeStream(int attributeIndex)
-	{
-		ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
-
-		return attributeStream[attributeIndex];
-	}
-
-	// Returns the index of the texture image unit (0-19) corresponding to a sampler index (0-15 for the pixel shader and 0-3 for the vertex shader)
-	GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex)
-	{
-		GLuint logicalTextureUnit = -1;
-
-		switch(type)
-		{
-		case sw::SAMPLER_PIXEL:
-			ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0]));
-
-			if(samplersPS[samplerIndex].active)
-			{
-				logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit;
-			}
-			break;
-		case sw::SAMPLER_VERTEX:
-			ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0]));
-
-			if(samplersVS[samplerIndex].active)
-			{
-				logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit;
-			}
-			break;
-		default: UNREACHABLE(type);
-		}
-
-		if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS)
-		{
-			return logicalTextureUnit;
-		}
-
-		return -1;
-	}
-
-	// Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader)
-	TextureType Program::getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex)
-	{
-		switch(type)
-		{
-		case sw::SAMPLER_PIXEL:
-			ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0]));
-			ASSERT(samplersPS[samplerIndex].active);
-			return samplersPS[samplerIndex].textureType;
-		case sw::SAMPLER_VERTEX:
-			ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0]));
-			ASSERT(samplersVS[samplerIndex].active);
-			return samplersVS[samplerIndex].textureType;
-		default: UNREACHABLE(type);
-		}
-
-		return TEXTURE_2D;
-	}
-
-	GLint Program::getUniformLocation(std::string name)
-	{
-		int subscript = 0;
-
-		// Strip any trailing array operator and retrieve the subscript
-		size_t open = name.find_last_of('[');
-		size_t close = name.find_last_of(']');
-		if(open != std::string::npos && close == name.length() - 1)
-		{
-			subscript = atoi(name.substr(open + 1).c_str());
-			name.erase(open);
-		}
-
-		unsigned int numUniforms = uniformIndex.size();
-		for(unsigned int location = 0; location < numUniforms; location++)
-		{
-			if(uniformIndex[location].name == name &&
-			   uniformIndex[location].element == subscript)
-			{
-				return location;
-			}
-		}
-
-		return -1;
-	}
-
-	bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		targetUniform->dirty = true;
-
-		int size = targetUniform->size();
-
-		if(size == 1 && count > 1)
-		{
-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
-		}
-
-		count = std::min(size - (int)uniformIndex[location].element, count);
-
-		if(targetUniform->type == GL_FLOAT)
-		{
-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat),
-				   v, sizeof(GLfloat) * count);
-		}
-		else if(targetUniform->type == GL_BOOL)
-		{
-			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element;
-
-			for(int i = 0; i < count; i++)
-			{
-				if(v[i] == 0.0f)
-				{
-					boolParams[i] = GL_FALSE;
-				}
-				else
-				{
-					boolParams[i] = GL_TRUE;
-				}
-			}
-		}
-		else
-		{
-			return false;
-		}
-
-		return true;
-	}
-
-	bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		targetUniform->dirty = true;
-
-		int size = targetUniform->size();
-
-		if(size == 1 && count > 1)
-		{
-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
-		}
-
-		count = std::min(size - (int)uniformIndex[location].element, count);
-
-		if(targetUniform->type == GL_FLOAT_VEC2)
-		{
-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 2,
-				   v, 2 * sizeof(GLfloat) * count);
-		}
-		else if(targetUniform->type == GL_BOOL_VEC2)
-		{
-			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 2;
-
-			for(int i = 0; i < count * 2; i++)
-			{
-				if(v[i] == 0.0f)
-				{
-					boolParams[i] = GL_FALSE;
-				}
-				else
-				{
-					boolParams[i] = GL_TRUE;
-				}
-			}
-		}
-		else
-		{
-			return false;
-		}
-
-		return true;
-	}
-
-	bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		targetUniform->dirty = true;
-
-		int size = targetUniform->size();
-
-		if(size == 1 && count > 1)
-		{
-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
-		}
-
-		count = std::min(size - (int)uniformIndex[location].element, count);
-
-		if(targetUniform->type == GL_FLOAT_VEC3)
-		{
-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 3,
-				   v, 3 * sizeof(GLfloat) * count);
-		}
-		else if(targetUniform->type == GL_BOOL_VEC3)
-		{
-			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 3;
-
-			for(int i = 0; i < count * 3; i++)
-			{
-				if(v[i] == 0.0f)
-				{
-					boolParams[i] = GL_FALSE;
-				}
-				else
-				{
-					boolParams[i] = GL_TRUE;
-				}
-			}
-		}
-		else
-		{
-			return false;
-		}
-
-		return true;
-	}
-
-	bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		targetUniform->dirty = true;
-
-		int size = targetUniform->size();
-
-		if(size == 1 && count > 1)
-		{
-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
-		}
-
-		count = std::min(size - (int)uniformIndex[location].element, count);
-
-		if(targetUniform->type == GL_FLOAT_VEC4)
-		{
-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 4,
-				   v, 4 * sizeof(GLfloat) * count);
-		}
-		else if(targetUniform->type == GL_BOOL_VEC4)
-		{
-			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * 4;
-
-			for(int i = 0; i < count * 4; i++)
-			{
-				if(v[i] == 0.0f)
-				{
-					boolParams[i] = GL_FALSE;
-				}
-				else
-				{
-					boolParams[i] = GL_TRUE;
-				}
-			}
-		}
-		else
-		{
-			return false;
-		}
-
-		return true;
-	}
-
-	bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		targetUniform->dirty = true;
-
-		if(targetUniform->type != GL_FLOAT_MAT2)
-		{
-			return false;
-		}
-
-		int size = targetUniform->size();
-
-		if(size == 1 && count > 1)
-		{
-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
-		}
-
-		count = std::min(size - (int)uniformIndex[location].element, count);
-
-		memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 4,
-			   value, 4 * sizeof(GLfloat) * count);
-
-		return true;
-	}
-
-	bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		targetUniform->dirty = true;
-
-		if(targetUniform->type != GL_FLOAT_MAT3)
-		{
-			return false;
-		}
-
-		int size = targetUniform->size();
-
-		if(size == 1 && count > 1)
-		{
-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
-		}
-
-		count = std::min(size - (int)uniformIndex[location].element, count);
-
-		memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 9,
-			   value, 9 * sizeof(GLfloat) * count);
-
-		return true;
-	}
-
-	bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		targetUniform->dirty = true;
-
-		if(targetUniform->type != GL_FLOAT_MAT4)
-		{
-			return false;
-		}
-
-		int size = targetUniform->size();
-
-		if(size == 1 && count > 1)
-		{
-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
-		}
-
-		count = std::min(size - (int)uniformIndex[location].element, count);
-
-		memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * 16,
-			   value, 16 * sizeof(GLfloat) * count);
-
-		return true;
-	}
-
-	bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		targetUniform->dirty = true;
-
-		int size = targetUniform->size();
-
-		if(size == 1 && count > 1)
-		{
-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
-		}
-
-		count = std::min(size - (int)uniformIndex[location].element, count);
-
-		if(targetUniform->type == GL_INT ||
-		   targetUniform->type == GL_SAMPLER_2D ||
-		   targetUniform->type == GL_SAMPLER_CUBE)
-		{
-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),
-				   v, sizeof(GLint) * count);
-		}
-		else if(targetUniform->type == GL_BOOL)
-		{
-			GLboolean *boolParams = new GLboolean[count];
-
-			for(int i = 0; i < count; i++)
-			{
-				if(v[i] == 0)
-				{
-					boolParams[i] = GL_FALSE;
-				}
-				else
-				{
-					boolParams[i] = GL_TRUE;
-				}
-			}
-
-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
-				   boolParams, sizeof(GLboolean) * count);
-
-			delete[] boolParams;
-		}
-		else
-		{
-			return false;
-		}
-
-		return true;
-	}
-
-	bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		targetUniform->dirty = true;
-
-		int size = targetUniform->size();
-
-		if(size == 1 && count > 1)
-		{
-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
-		}
-
-		count = std::min(size - (int)uniformIndex[location].element, count);
-
-		if(targetUniform->type == GL_INT_VEC2)
-		{
-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 2,
-				   v, 2 * sizeof(GLint) * count);
-		}
-		else if(targetUniform->type == GL_BOOL_VEC2)
-		{
-			GLboolean *boolParams = new GLboolean[count * 2];
-
-			for(int i = 0; i < count * 2; i++)
-			{
-				if(v[i] == 0)
-				{
-					boolParams[i] = GL_FALSE;
-				}
-				else
-				{
-					boolParams[i] = GL_TRUE;
-				}
-			}
-
-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 2,
-				   boolParams, 2 * sizeof(GLboolean) * count);
-
-			delete[] boolParams;
-		}
-		else
-		{
-			return false;
-		}
-
-		return true;
-	}
-
-	bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		targetUniform->dirty = true;
-
-		int size = targetUniform->size();
-
-		if(size == 1 && count > 1)
-		{
-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
-		}
-
-		count = std::min(size - (int)uniformIndex[location].element, count);
-
-		if(targetUniform->type == GL_INT_VEC3)
-		{
-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 3,
-				   v, 3 * sizeof(GLint) * count);
-		}
-		else if(targetUniform->type == GL_BOOL_VEC3)
-		{
-			GLboolean *boolParams = new GLboolean[count * 3];
-
-			for(int i = 0; i < count * 3; i++)
-			{
-				if(v[i] == 0)
-				{
-					boolParams[i] = GL_FALSE;
-				}
-				else
-				{
-					boolParams[i] = GL_TRUE;
-				}
-			}
-
-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 3,
-				   boolParams, 3 * sizeof(GLboolean) * count);
-
-			delete[] boolParams;
-		}
-		else
-		{
-			return false;
-		}
-
-		return true;
-	}
-
-	bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		targetUniform->dirty = true;
-
-		int size = targetUniform->size();
-
-		if(size == 1 && count > 1)
-		{
-			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
-		}
-
-		count = std::min(size - (int)uniformIndex[location].element, count);
-
-		if(targetUniform->type == GL_INT_VEC4)
-		{
-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint) * 4,
-				   v, 4 * sizeof(GLint) * count);
-		}
-		else if(targetUniform->type == GL_BOOL_VEC4)
-		{
-			GLboolean *boolParams = new GLboolean[count * 4];
-
-			for(int i = 0; i < count * 4; i++)
-			{
-				if(v[i] == 0)
-				{
-					boolParams[i] = GL_FALSE;
-				}
-				else
-				{
-					boolParams[i] = GL_TRUE;
-				}
-			}
-
-			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean) * 4,
-				   boolParams, 4 * sizeof(GLboolean) * count);
-
-			delete[] boolParams;
-		}
-		else
-		{
-			return false;
-		}
-
-		return true;
-	}
-
-	bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		unsigned int count = UniformComponentCount(targetUniform->type);
-
-		// Sized query - ensure the provided buffer is large enough
-		if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLfloat))
-		{
-			return false;
-		}
-
-		switch(UniformComponentType(targetUniform->type))
-		{
-		case GL_BOOL:
-			{
-				GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * count;
-
-				for(unsigned int i = 0; i < count; i++)
-				{
-					params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;
-				}
-			}
-			break;
-		case GL_FLOAT:
-			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLfloat),
-				   count * sizeof(GLfloat));
-			break;
-		case GL_INT:
-			{
-				GLint *intParams = (GLint*)targetUniform->data + uniformIndex[location].element * count;
-
-				for(unsigned int i = 0; i < count; i++)
-				{
-					params[i] = (float)intParams[i];
-				}
-			}
-			break;
-		default: UNREACHABLE(targetUniform->type);
-		}
-
-		return true;
-	}
-
-	bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
-	{
-		if(location < 0 || location >= (int)uniformIndex.size())
-		{
-			return false;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-		unsigned int count = UniformComponentCount(targetUniform->type);
-
-		// Sized query - ensure the provided buffer is large enough
-		if(bufSize && static_cast<unsigned int>(*bufSize) < count *sizeof(GLint))
-		{
-			return false;
-		}
-
-		switch(UniformComponentType(targetUniform->type))
-		{
-		case GL_BOOL:
-			{
-				GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;
-
-				for(unsigned int i = 0; i < count; i++)
-				{
-					params[i] = (GLint)boolParams[i];
-				}
-			}
-			break;
-		case GL_FLOAT:
-			{
-				GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;
-
-				for(unsigned int i = 0; i < count; i++)
-				{
-					params[i] = (GLint)floatParams[i];
-				}
-			}
-			break;
-		case GL_INT:
-			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLint),
-				   count * sizeof(GLint));
-			break;
-		default: UNREACHABLE(targetUniform->type);
-		}
-
-		return true;
-	}
-
-	void Program::dirtyAllUniforms()
-	{
-		unsigned int numUniforms = uniforms.size();
-		for(unsigned int index = 0; index < numUniforms; index++)
-		{
-			uniforms[index]->dirty = true;
-		}
-	}
-
-	// Applies all the uniforms set for this program object to the device
-	void Program::applyUniforms()
-	{
-		unsigned int numUniforms = uniformIndex.size();
-		for(unsigned int location = 0; location < numUniforms; location++)
-		{
-			if(uniformIndex[location].element != 0)
-			{
-				continue;
-			}
-
-			Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-			if(targetUniform->dirty)
-			{
-				int size = targetUniform->size();
-				GLfloat *f = (GLfloat*)targetUniform->data;
-				GLint *i = (GLint*)targetUniform->data;
-				GLboolean *b = (GLboolean*)targetUniform->data;
-
-				switch(targetUniform->type)
-				{
-				case GL_BOOL:       applyUniform1bv(location, size, b);       break;
-				case GL_BOOL_VEC2:  applyUniform2bv(location, size, b);       break;
-				case GL_BOOL_VEC3:  applyUniform3bv(location, size, b);       break;
-				case GL_BOOL_VEC4:  applyUniform4bv(location, size, b);       break;
-				case GL_FLOAT:      applyUniform1fv(location, size, f);       break;
-				case GL_FLOAT_VEC2: applyUniform2fv(location, size, f);       break;
-				case GL_FLOAT_VEC3: applyUniform3fv(location, size, f);       break;
-				case GL_FLOAT_VEC4: applyUniform4fv(location, size, f);       break;
-				case GL_FLOAT_MAT2: applyUniformMatrix2fv(location, size, f); break;
-				case GL_FLOAT_MAT3: applyUniformMatrix3fv(location, size, f); break;
-				case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, size, f); break;
-				case GL_SAMPLER_2D:
-				case GL_SAMPLER_CUBE:
-				case GL_INT:        applyUniform1iv(location, size, i);       break;
-				case GL_INT_VEC2:   applyUniform2iv(location, size, i);       break;
-				case GL_INT_VEC3:   applyUniform3iv(location, size, i);       break;
-				case GL_INT_VEC4:   applyUniform4iv(location, size, i);       break;
-				default:
-					UNREACHABLE(targetUniform->type);
-				}
-
-				targetUniform->dirty = false;
-			}
-		}
-	}
-
-	// Packs varyings into generic varying registers.
-	// Returns the number of used varying registers, or -1 if unsuccesful
-	int Program::packVaryings(const glsl::Varying *packing[][4])
-	{
-		for(glsl::VaryingList::iterator varying = fragmentShader->varyings.begin(); varying != fragmentShader->varyings.end(); varying++)
-		{
-			int n = VariableRowCount(varying->type) * varying->size();
-			int m = VariableColumnCount(varying->type);
-			bool success = false;
-
-			if(m == 2 || m == 3 || m == 4)
-			{
-				for(int r = 0; r <= MAX_VARYING_VECTORS - n && !success; r++)
-				{
-					bool available = true;
-
-					for(int y = 0; y < n && available; y++)
-					{
-						for(int x = 0; x < m && available; x++)
-						{
-							if(packing[r + y][x])
-							{
-								available = false;
-							}
-						}
-					}
-
-					if(available)
-					{
-						varying->registerIndex = r;
-						varying->column = 0;
-
-						for(int y = 0; y < n; y++)
-						{
-							for(int x = 0; x < m; x++)
-							{
-								packing[r + y][x] = &*varying;
-							}
-						}
-
-						success = true;
-					}
-				}
-
-				if(!success && m == 2)
-				{
-					for(int r = MAX_VARYING_VECTORS - n; r >= 0 && !success; r--)
-					{
-						bool available = true;
-
-						for(int y = 0; y < n && available; y++)
-						{
-							for(int x = 2; x < 4 && available; x++)
-							{
-								if(packing[r + y][x])
-								{
-									available = false;
-								}
-							}
-						}
-
-						if(available)
-						{
-							varying->registerIndex = r;
-							varying->column = 2;
-
-							for(int y = 0; y < n; y++)
-							{
-								for(int x = 2; x < 4; x++)
-								{
-									packing[r + y][x] = &*varying;
-								}
-							}
-
-							success = true;
-						}
-					}
-				}
-			}
-			else if(m == 1)
-			{
-				int space[4] = {0};
-
-				for(int y = 0; y < MAX_VARYING_VECTORS; y++)
-				{
-					for(int x = 0; x < 4; x++)
-					{
-						space[x] += packing[y][x] ? 0 : 1;
-					}
-				}
-
-				int column = 0;
-
-				for(int x = 0; x < 4; x++)
-				{
-					if(space[x] >= n && space[x] < space[column])
-					{
-						column = x;
-					}
-				}
-
-				if(space[column] >= n)
-				{
-					for(int r = 0; r < MAX_VARYING_VECTORS; r++)
-					{
-						if(!packing[r][column])
-						{
-							varying->registerIndex = r;
-
-							for(int y = r; y < r + n; y++)
-							{
-								packing[y][column] = &*varying;
-							}
-
-							break;
-						}
-					}
-
-					varying->column = column;
-
-					success = true;
-				}
-			}
-			else UNREACHABLE(m);
-
-			if(!success)
-			{
-				appendToInfoLog("Could not pack varying %s", varying->name.c_str());
-
-				return -1;
-			}
-		}
-
-		// Return the number of used registers
-		int registers = 0;
-
-		for(int r = 0; r < MAX_VARYING_VECTORS; r++)
-		{
-			if(packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
-			{
-				registers++;
-			}
-		}
-
-		return registers;
-	}
-
-	bool Program::linkVaryings()
-	{
-		for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); input++)
-		{
-			bool matched = false;
-
-			for(glsl::VaryingList::iterator output = vertexShader->varyings.begin(); output != vertexShader->varyings.end(); output++)
-			{
-				if(output->name == input->name)
-				{
-					if(output->type != input->type || output->size() != input->size())
-					{
-						appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());
-
-						return false;
-					}
-
-					matched = true;
-					break;
-				}
-			}
-
-			if(!matched)
-			{
-				appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str());
-
-				return false;
-			}
-		}
-
-		glsl::VaryingList &psVaryings = fragmentShader->varyings;
-		glsl::VaryingList &vsVaryings = vertexShader->varyings;
-
-		for(glsl::VaryingList::iterator output = vsVaryings.begin(); output != vsVaryings.end(); output++)
-		{
-			for(glsl::VaryingList::iterator input = psVaryings.begin(); input != psVaryings.end(); input++)
-			{
-				if(output->name == input->name)
-				{
-					int in = input->registerIndex;
-					int out = output->registerIndex;
-					int components = VariableColumnCount(output->type);
-					int registers = VariableRowCount(output->type) * output->size();
-
-					ASSERT(in >= 0);
-
-					if(in + registers > MAX_VARYING_VECTORS)
-					{
-						appendToInfoLog("Too many varyings");
-						return false;
-					}
-
-					if(out >= 0)
-					{
-						if(out + registers > MAX_VARYING_VECTORS)
-						{
-							appendToInfoLog("Too many varyings");
-							return false;
-						}
-
-						for(int i = 0; i < registers; i++)
-						{
-							vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i));
-						}
-					}
-					else   // Vertex varying is declared but not written to
-					{
-						for(int i = 0; i < registers; i++)
-						{
-							pixelBinary->setInput(in + i, components, sw::Shader::Semantic());
-						}
-					}
-
-					break;
-				}
-			}
-		}
-
-		return true;
-	}
-
-	// Links the code of the vertex and pixel shader by matching up their varyings,
-	// compiling them into binaries, determining the attribute mappings, and collecting
-	// a list of uniforms
-	void Program::link()
-	{
-		unlink();
-
-		if(!fragmentShader || !fragmentShader->isCompiled())
-		{
-			return;
-		}
-
-		if(!vertexShader || !vertexShader->isCompiled())
-		{
-			return;
-		}
-
-		vertexBinary = new sw::VertexShader(vertexShader->getVertexShader());
-		pixelBinary = new sw::PixelShader(fragmentShader->getPixelShader());
-
-		if(!linkVaryings())
-		{
-			return;
-		}
-
-		if(!linkAttributes())
-		{
-			return;
-		}
-
-		if(!linkUniforms(fragmentShader))
-		{
-			return;
-		}
-
-		if(!linkUniforms(vertexShader))
-		{
-			return;
-		}
-
-		linked = true;   // Success
-	}
-
-	// Determines the mapping between GL attributes and vertex stream usage indices
-	bool Program::linkAttributes()
-	{
-		unsigned int usedLocations = 0;
-
-		// Link attributes that have a binding location
-		for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); attribute++)
-		{
-			int location = getAttributeBinding(attribute->name);
-
-			if(location != -1)   // Set by glBindAttribLocation
-			{
-				if(!linkedAttribute[location].name.empty())
-				{
-					// Multiple active attributes bound to the same location; not an error
-				}
-
-				linkedAttribute[location] = *attribute;
-
-				int rows = VariableRowCount(attribute->type);
-
-				if(rows + location > MAX_VERTEX_ATTRIBS)
-				{
-					appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
-					return false;
-				}
-
-				for(int i = 0; i < rows; i++)
-				{
-					usedLocations |= 1 << (location + i);
-				}
-			}
-		}
-
-		// Link attributes that don't have a binding location
-		for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); attribute++)
-		{
-			int location = getAttributeBinding(attribute->name);
-
-			if(location == -1)   // Not set by glBindAttribLocation
-			{
-				int rows = VariableRowCount(attribute->type);
-				int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
-
-				if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
-				{
-					appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str());
-					return false;   // Fail to link
-				}
-
-				linkedAttribute[availableIndex] = *attribute;
-			}
-		}
-
-		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
-		{
-			int index = vertexShader->getSemanticIndex(linkedAttribute[attributeIndex].name);
-			int rows = std::max(VariableRowCount(linkedAttribute[attributeIndex].type), 1);
-
-			for(int r = 0; r < rows; r++)
-			{
-				attributeStream[attributeIndex++] = index++;
-			}
-		}
-
-		return true;
-	}
-
-	int Program::getAttributeBinding(const std::string &name)
-	{
-		for(int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
-		{
-			if(attributeBinding[location].find(name) != attributeBinding[location].end())
-			{
-				return location;
-			}
-		}
-
-		return -1;
-	}
-
-	bool Program::linkUniforms(Shader *shader)
-	{
-		const glsl::ActiveUniforms &activeUniforms = shader->activeUniforms;
-
-		for(unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++)
-		{
-			const glsl::Uniform &uniform = activeUniforms[uniformIndex];
-
-			if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex))
-			{
-				return false;
-			}
-		}
-
-		return true;
-	}
-
-	bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex)
-	{
-		if(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE)
-		{
-			int index = registerIndex;
-
-			do
-			{
-				if(shader == GL_VERTEX_SHADER)
-				{
-					if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
-					{
-						samplersVS[index].active = true;
-						samplersVS[index].textureType = (type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
-						samplersVS[index].logicalTextureUnit = 0;
-					}
-					else
-					{
-					   appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", MAX_VERTEX_TEXTURE_IMAGE_UNITS);
-					   return false;
-					}
-				}
-				else if(shader == GL_FRAGMENT_SHADER)
-				{
-					if(index < MAX_TEXTURE_IMAGE_UNITS)
-					{
-						samplersPS[index].active = true;
-						samplersPS[index].textureType = (type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
-						samplersPS[index].logicalTextureUnit = 0;
-					}
-					else
-					{
-						appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
-						return false;
-					}
-				}
-				else UNREACHABLE(shader);
-
-				index++;
-			}
-			while(index < registerIndex + static_cast<int>(arraySize));
-		}
-
-		Uniform *uniform = 0;
-		GLint location = getUniformLocation(name);
-
-		if(location >= 0)   // Previously defined, types must match
-		{
-			uniform = uniforms[uniformIndex[location].index];
-
-			if(uniform->type != type)
-			{
-				appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
-				return false;
-			}
-
-			if(uniform->precision != precision)
-			{
-				appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
-				return false;
-			}
-		}
-		else
-		{
-			uniform = new Uniform(type, precision, name, arraySize);
-		}
-
-		if(!uniform)
-		{
-			return false;
-		}
-
-		if(shader == GL_VERTEX_SHADER)
-		{
-			uniform->vsRegisterIndex = registerIndex;
-		}
-		else if(shader == GL_FRAGMENT_SHADER)
-		{
-			uniform->psRegisterIndex = registerIndex;
-		}
-		else UNREACHABLE(shader);
-
-		if(location == -1)   // Not previously defined
-		{
-			uniforms.push_back(uniform);
-			unsigned int index = uniforms.size() - 1;
-
-			for(int i = 0; i < uniform->size(); i++)
-			{
-				uniformIndex.push_back(UniformLocation(name, i, index));
-			}
-		}
-
-		if(shader == GL_VERTEX_SHADER)
-		{
-			if(registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
-			{
-				appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);
-				return false;
-			}
-		}
-		else if(shader == GL_FRAGMENT_SHADER)
-		{
-			if(registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)
-			{
-				appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);
-				return false;
-			}
-		}
-		else UNREACHABLE(shader);
-
-		return true;
-	}
-
-	bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v)
-	{
-		int vector[MAX_UNIFORM_VECTORS][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
-			vector[i][1] = 0;
-			vector[i][2] = 0;
-			vector[i][3] = 0;
-
-			v += 1;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniform2bv(GLint location, GLsizei count, const GLboolean *v)
-	{
-		int vector[MAX_UNIFORM_VECTORS][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
-			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
-			vector[i][2] = 0;
-			vector[i][3] = 0;
-
-			v += 2;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniform3bv(GLint location, GLsizei count, const GLboolean *v)
-	{
-		int vector[MAX_UNIFORM_VECTORS][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
-			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
-			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
-			vector[i][3] = 0;
-
-			v += 3;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniform4bv(GLint location, GLsizei count, const GLboolean *v)
-	{
-		int vector[MAX_UNIFORM_VECTORS][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
-			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
-			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
-			vector[i][3] = (v[3] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
-
-			v += 4;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniform1fv(GLint location, GLsizei count, const GLfloat *v)
-	{
-		float vector[MAX_UNIFORM_VECTORS][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			vector[i][0] = v[0];
-			vector[i][1] = 0;
-			vector[i][2] = 0;
-			vector[i][3] = 0;
-
-			v += 1;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniform2fv(GLint location, GLsizei count, const GLfloat *v)
-	{
-		float vector[MAX_UNIFORM_VECTORS][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			vector[i][0] = v[0];
-			vector[i][1] = v[1];
-			vector[i][2] = 0;
-			vector[i][3] = 0;
-
-			v += 2;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniform3fv(GLint location, GLsizei count, const GLfloat *v)
-	{
-		float vector[MAX_UNIFORM_VECTORS][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			vector[i][0] = v[0];
-			vector[i][1] = v[1];
-			vector[i][2] = v[2];
-			vector[i][3] = 0;
-
-			v += 3;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniform4fv(GLint location, GLsizei count, const GLfloat *v)
-	{
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)v, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)v, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
-	{
-		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;
-			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;
-
-			value += 4;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)matrix, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)matrix, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
-	{
-		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2];	matrix[i][0][3] = 0;
-			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];	matrix[i][1][2] = value[5];	matrix[i][1][3] = 0;
-			matrix[i][2][0] = value[6];	matrix[i][2][1] = value[7];	matrix[i][2][2] = value[8];	matrix[i][2][3] = 0;
-
-			value += 9;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)matrix, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)matrix, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
-	{
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)value, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)value, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
-	{
-		float vector[MAX_UNIFORM_VECTORS][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			vector[i][0] = (float)v[i];
-			vector[i][1] = 0;
-			vector[i][2] = 0;
-			vector[i][3] = 0;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			if(targetUniform->type == GL_SAMPLER_2D ||
-			   targetUniform->type == GL_SAMPLER_CUBE)
-			{
-				for(int i = 0; i < count; i++)
-				{
-					unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
-
-					if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
-					{
-						ASSERT(samplersPS[samplerIndex].active);
-						samplersPS[samplerIndex].logicalTextureUnit = v[i];
-					}
-				}
-			}
-			else
-			{
-				device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
-			}
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			if(targetUniform->type == GL_SAMPLER_2D ||
-			   targetUniform->type == GL_SAMPLER_CUBE)
-			{
-				for(int i = 0; i < count; i++)
-				{
-					unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
-
-					if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
-					{
-						ASSERT(samplersVS[samplerIndex].active);
-						samplersVS[samplerIndex].logicalTextureUnit = v[i];
-					}
-				}
-			}
-			else
-			{
-				device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
-			}
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v)
-	{
-		float vector[MAX_UNIFORM_VECTORS][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			vector[i][0] = (float)v[0];
-			vector[i][1] = (float)v[1];
-			vector[i][2] = 0;
-			vector[i][3] = 0;
-
-			v += 2;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniform3iv(GLint location, GLsizei count, const GLint *v)
-	{
-		float vector[MAX_UNIFORM_VECTORS][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			vector[i][0] = (float)v[0];
-			vector[i][1] = (float)v[1];
-			vector[i][2] = (float)v[2];
-			vector[i][3] = 0;
-
-			v += 3;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)
-	{
-		float vector[MAX_UNIFORM_VECTORS][4];
-
-		for(int i = 0; i < count; i++)
-		{
-			vector[i][0] = (float)v[0];
-			vector[i][1] = (float)v[1];
-			vector[i][2] = (float)v[2];
-			vector[i][3] = (float)v[3];
-
-			v += 4;
-		}
-
-		Uniform *targetUniform = uniforms[uniformIndex[location].index];
-
-		if(targetUniform->psRegisterIndex != -1)
-		{
-			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		if(targetUniform->vsRegisterIndex != -1)
-		{
-			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, (float*)vector, targetUniform->registerCount());
-		}
-
-		return true;
-	}
-
-	void Program::appendToInfoLog(const char *format, ...)
-	{
-		if(!format)
-		{
-			return;
-		}
-
-		char info[1024];
-
-		va_list vararg;
-		va_start(vararg, format);
-		vsnprintf(info, sizeof(info), format, vararg);
-		va_end(vararg);
-
-		size_t infoLength = strlen(info);
-
-		if(!infoLog)
-		{
-			infoLog = new char[infoLength + 2];
-			strcpy(infoLog, info);
-			strcpy(infoLog + infoLength, "\n");
-		}
-		else
-		{
-			size_t logLength = strlen(infoLog);
-			char *newLog = new char[logLength + infoLength + 2];
-			strcpy(newLog, infoLog);
-			strcpy(newLog + logLength, info);
-			strcpy(newLog + logLength + infoLength, "\n");
-
-			delete[] infoLog;
-			infoLog = newLog;
-		}
-	}
-
-	void Program::resetInfoLog()
-	{
-		if(infoLog)
-		{
-			delete[] infoLog;
-			infoLog = 0;
-		}
-	}
-
-	// Returns the program object to an unlinked state, before re-linking, or at destruction
-	void Program::unlink()
-	{
-		delete vertexBinary;
-		vertexBinary = 0;
-		delete pixelBinary;
-		pixelBinary = 0;
-
-		for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
-		{
-			linkedAttribute[index].name.clear();
-			attributeStream[index] = -1;
-		}
-
-		for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
-		{
-			samplersPS[index].active = false;
-		}
-
-		for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
-		{
-			samplersVS[index].active = false;
-		}
-
-		while(!uniforms.empty())
-		{
-			delete uniforms.back();
-			uniforms.pop_back();
-		}
-
-		uniformIndex.clear();
-
-		delete[] infoLog;
-		infoLog = 0;
-
-		linked = false;
-	}
-
-	bool Program::isLinked()
-	{
-		return linked;
-	}
-
-	bool Program::isValidated() const
-	{
-		return validated;
-	}
-
-	void Program::release()
-	{
-		referenceCount--;
-
-		if(referenceCount == 0 && orphaned)
-		{
-			resourceManager->deleteProgram(handle);
-		}
-	}
-
-	void Program::addRef()
-	{
-		referenceCount++;
-	}
-
-	unsigned int Program::getRefCount() const
-	{
-		return referenceCount;
-	}
-
-	unsigned int Program::getSerial() const
-	{
-		return serial;
-	}
-
-	unsigned int Program::issueSerial()
-	{
-		return currentSerial++;
-	}
-
-	int Program::getInfoLogLength() const
-	{
-		if(!infoLog)
-		{
-			return 0;
-		}
-		else
-		{
-		   return strlen(infoLog) + 1;
-		}
-	}
-
-	void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *buffer)
-	{
-		int index = 0;
-
-		if(bufSize > 0)
-		{
-			if(infoLog)
-			{
-				index = std::min(bufSize - 1, (int)strlen(infoLog));
-				memcpy(buffer, infoLog, index);
-			}
-
-			buffer[index] = '\0';
-		}
-
-		if(length)
-		{
-			*length = index;
-		}
-	}
-
-	void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
-	{
-		int total = 0;
-
-		if(vertexShader)
-		{
-			if(total < maxCount)
-			{
-				shaders[total] = vertexShader->getName();
-			}
-
-			total++;
-		}
-
-		if(fragmentShader)
-		{
-			if(total < maxCount)
-			{
-				shaders[total] = fragmentShader->getName();
-			}
-
-			total++;
-		}
-
-		if(count)
-		{
-			*count = total;
-		}
-	}
-
-	void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
-	{
-		// Skip over inactive attributes
-		unsigned int activeAttribute = 0;
-		unsigned int attribute;
-		for(attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
-		{
-			if(linkedAttribute[attribute].name.empty())
-			{
-				continue;
-			}
-
-			if(activeAttribute == index)
-			{
-				break;
-			}
-
-			activeAttribute++;
-		}
-
-		if(bufsize > 0)
-		{
-			const char *string = linkedAttribute[attribute].name.c_str();
-
-			strncpy(name, string, bufsize);
-			name[bufsize - 1] = '\0';
-
-			if(length)
-			{
-				*length = strlen(name);
-			}
-		}
-
-		*size = 1;   // Always a single 'type' instance
-
-		*type = linkedAttribute[attribute].type;
-	}
-
-	size_t Program::getActiveAttributeCount() const
-	{
-		size_t count = 0;
-
-		for(size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; ++attributeIndex)
-		{
-			if(!linkedAttribute[attributeIndex].name.empty())
-			{
-				count++;
-			}
-		}
-
-		return count;
-	}
-
-	GLint Program::getActiveAttributeMaxLength() const
-	{
-		int maxLength = 0;
-
-		for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
-		{
-			if(!linkedAttribute[attributeIndex].name.empty())
-			{
-				maxLength = std::max((int)(linkedAttribute[attributeIndex].name.length() + 1), maxLength);
-			}
-		}
-
-		return maxLength;
-	}
-
-	void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
-	{
-		if(bufsize > 0)
-		{
-			std::string string = uniforms[index]->name;
-
-			if(uniforms[index]->isArray())
-			{
-				string += "[0]";
-			}
-
-			strncpy(name, string.c_str(), bufsize);
-			name[bufsize - 1] = '\0';
-
-			if(length)
-			{
-				*length = strlen(name);
-			}
-		}
-
-		*size = uniforms[index]->size();
-
-		*type = uniforms[index]->type;
-	}
-
-	size_t Program::getActiveUniformCount() const
-	{
-		return uniforms.size();
-	}
-
-	GLint Program::getActiveUniformMaxLength() const
-	{
-		int maxLength = 0;
-
-		unsigned int numUniforms = uniforms.size();
-		for(unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
-		{
-			if(!uniforms[uniformIndex]->name.empty())
-			{
-				int length = (int)(uniforms[uniformIndex]->name.length() + 1);
-				if(uniforms[uniformIndex]->isArray())
-				{
-					length += 3;  // Counting in "[0]".
-				}
-				maxLength = std::max(length, maxLength);
-			}
-		}
-
-		return maxLength;
-	}
-
-	void Program::flagForDeletion()
-	{
-		orphaned = true;
-	}
-
-	bool Program::isFlaggedForDeletion() const
-	{
-		return orphaned;
-	}
-
-	void Program::validate()
-	{
-		resetInfoLog();
-
-		if(!isLinked())
-		{
-			appendToInfoLog("Program has not been successfully linked.");
-			validated = false;
-		}
-		else
-		{
-			applyUniforms();
-			if(!validateSamplers(true))
-			{
-				validated = false;
-			}
-			else
-			{
-				validated = true;
-			}
-		}
-	}
-
-	bool Program::validateSamplers(bool logErrors)
-	{
-		// if any two active samplers in a program are of different types, but refer to the same
-		// texture image unit, and this is the current program, then ValidateProgram will fail, and
-		// DrawArrays and DrawElements will issue the INVALID_OPERATION error.
-
-		TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-
-		for(unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++)
-		{
-			textureUnitType[i] = TEXTURE_UNKNOWN;
-		}
-
-		for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
-		{
-			if(samplersPS[i].active)
-			{
-				unsigned int unit = samplersPS[i].logicalTextureUnit;
-
-				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
-				{
-					if(logErrors)
-					{
-						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
-					}
-
-					return false;
-				}
-
-				if(textureUnitType[unit] != TEXTURE_UNKNOWN)
-				{
-					if(samplersPS[i].textureType != textureUnitType[unit])
-					{
-						if(logErrors)
-						{
-							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
-						}
-
-						return false;
-					}
-				}
-				else
-				{
-					textureUnitType[unit] = samplersPS[i].textureType;
-				}
-			}
-		}
-
-		for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
-		{
-			if(samplersVS[i].active)
-			{
-				unsigned int unit = samplersVS[i].logicalTextureUnit;
-
-				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
-				{
-					if(logErrors)
-					{
-						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
-					}
-
-					return false;
-				}
-
-				if(textureUnitType[unit] != TEXTURE_UNKNOWN)
-				{
-					if(samplersVS[i].textureType != textureUnitType[unit])
-					{
-						if(logErrors)
-						{
-							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
-						}
-
-						return false;
-					}
-				}
-				else
-				{
-					textureUnitType[unit] = samplersVS[i].textureType;
-				}
-			}
-		}
-
-		return true;
-	}
-}
diff --git a/src/OpenGL/libGL/Program.h b/src/OpenGL/libGL/Program.h
deleted file mode 100644
index 0e7c0f6..0000000
--- a/src/OpenGL/libGL/Program.h
+++ /dev/null
@@ -1,210 +0,0 @@
-// 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.
-
-// Program.h: Defines the Program class. Implements GL program objects
-// and related functionality.
-
-#ifndef LIBGL_PROGRAM_H_
-#define LIBGL_PROGRAM_H_
-
-#include "Shader.h"
-#include "Context.h"
-#include "Shader/PixelShader.hpp"
-#include "Shader/VertexShader.hpp"
-
-#include <string>
-#include <vector>
-#include <set>
-
-namespace gl
-{
-	class Device;
-	class ResourceManager;
-	class FragmentShader;
-	class VertexShader;
-
-	// Helper struct representing a single shader uniform
-	struct Uniform
-	{
-		Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize);
-
-		~Uniform();
-
-		bool isArray() const;
-		int size() const;
-		int registerCount() const;
-
-		const GLenum type;
-		const GLenum precision;
-		const std::string name;
-		const unsigned int arraySize;
-
-		unsigned char *data;
-		bool dirty;
-
-		short psRegisterIndex;
-		short vsRegisterIndex;
-	};
-
-	// Struct used for correlating uniforms/elements of uniform arrays to handles
-	struct UniformLocation
-	{
-		UniformLocation(const std::string &name, unsigned int element, unsigned int index);
-
-		std::string name;
-		unsigned int element;
-		unsigned int index;
-	};
-
-	class Program
-	{
-	public:
-		Program(ResourceManager *manager, GLuint handle);
-
-		~Program();
-
-		bool attachShader(Shader *shader);
-		bool detachShader(Shader *shader);
-		int getAttachedShadersCount() const;
-
-		sw::PixelShader *getPixelShader();
-		sw::VertexShader *getVertexShader();
-
-		void bindAttributeLocation(GLuint index, const char *name);
-		GLuint getAttributeLocation(const char *name);
-		int getAttributeStream(int attributeIndex);
-
-		GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex);
-		TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex);
-
-		GLint getUniformLocation(std::string name);
-		bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
-		bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
-		bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
-		bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
-		bool setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value);
-		bool setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value);
-		bool setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value);
-		bool setUniform1iv(GLint location, GLsizei count, const GLint *v);
-		bool setUniform2iv(GLint location, GLsizei count, const GLint *v);
-		bool setUniform3iv(GLint location, GLsizei count, const GLint *v);
-		bool setUniform4iv(GLint location, GLsizei count, const GLint *v);
-
-		bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params);
-		bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params);
-
-		void dirtyAllUniforms();
-		void applyUniforms();
-
-		void link();
-		bool isLinked();
-		int getInfoLogLength() const;
-		void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
-		void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
-
-		void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
-		size_t getActiveAttributeCount() const;
-		GLint getActiveAttributeMaxLength() const;
-
-		void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
-		size_t getActiveUniformCount() const;
-		GLint getActiveUniformMaxLength() const;
-
-		void addRef();
-		void release();
-		unsigned int getRefCount() const;
-		void flagForDeletion();
-		bool isFlaggedForDeletion() const;
-
-		void validate();
-		bool validateSamplers(bool logErrors);
-		bool isValidated() const;
-
-		unsigned int getSerial() const;
-
-	private:
-		void unlink();
-
-		int packVaryings(const glsl::Varying *packing[][4]);
-		bool linkVaryings();
-
-		bool linkAttributes();
-		int getAttributeBinding(const std::string &name);
-
-		bool linkUniforms(Shader *shader);
-		bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex);
-		bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v);
-		bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v);
-		bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v);
-		bool applyUniform4bv(GLint location, GLsizei count, const GLboolean *v);
-		bool applyUniform1fv(GLint location, GLsizei count, const GLfloat *v);
-		bool applyUniform2fv(GLint location, GLsizei count, const GLfloat *v);
-		bool applyUniform3fv(GLint location, GLsizei count, const GLfloat *v);
-		bool applyUniform4fv(GLint location, GLsizei count, const GLfloat *v);
-		bool applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value);
-		bool applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value);
-		bool applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value);
-		bool applyUniform1iv(GLint location, GLsizei count, const GLint *v);
-		bool applyUniform2iv(GLint location, GLsizei count, const GLint *v);
-		bool applyUniform3iv(GLint location, GLsizei count, const GLint *v);
-		bool applyUniform4iv(GLint location, GLsizei count, const GLint *v);    
-
-		void appendToInfoLog(const char *info, ...);
-		void resetInfoLog();
-
-		static unsigned int issueSerial();
-
-	private:
-		gl::Device *device;
-		FragmentShader *fragmentShader;
-		VertexShader *vertexShader;
-
-		sw::PixelShader *pixelBinary;
-		sw::VertexShader *vertexBinary;
-
-		std::set<std::string> attributeBinding[MAX_VERTEX_ATTRIBS];
-		glsl::Attribute linkedAttribute[MAX_VERTEX_ATTRIBS];
-		int attributeStream[MAX_VERTEX_ATTRIBS];
-
-		struct Sampler
-		{
-			bool active;
-			GLint logicalTextureUnit;
-			TextureType textureType;
-		};
-
-		Sampler samplersPS[MAX_TEXTURE_IMAGE_UNITS];
-		Sampler samplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS];
-
-		typedef std::vector<Uniform*> UniformArray;
-		UniformArray uniforms;
-		typedef std::vector<UniformLocation> UniformIndex;
-		UniformIndex uniformIndex;
-
-		bool linked;
-		bool orphaned;   // Flag to indicate that the program can be deleted when no longer in use
-		char *infoLog;
-		bool validated;
-
-		unsigned int referenceCount;
-		const unsigned int serial;
-
-		static unsigned int currentSerial;
-
-		ResourceManager *resourceManager;
-		const GLuint handle;
-	};
-}
-
-#endif   // LIBGL_PROGRAM_H_
diff --git a/src/OpenGL/libGL/Query.cpp b/src/OpenGL/libGL/Query.cpp
deleted file mode 100644
index 92b9d61..0000000
--- a/src/OpenGL/libGL/Query.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-// 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.
-
-// Query.cpp: Implements the gl::Query class
-
-#include "Query.h"
-
-#include "main.h"
-#include "Common/Thread.hpp"
-
-namespace gl
-{
-
-Query::Query(GLuint name, GLenum type) : NamedObject(name)
-{
-	mQuery = nullptr;
-	mStatus = GL_FALSE;
-	mResult = GL_FALSE;
-	mType = type;
-}
-
-Query::~Query()
-{
-	delete mQuery;
-}
-
-void Query::begin()
-{
-	if(!mQuery)
-	{
-		sw::Query::Type type;
-		switch(mType)
-		{
-		case GL_ANY_SAMPLES_PASSED:
-		case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
-			type = sw::Query::FRAGMENTS_PASSED;
-			break;
-		default:
-			ASSERT(false);
-		}
-
-		mQuery = new sw::Query(type);
-
-		if(!mQuery)
-		{
-			return error(GL_OUT_OF_MEMORY);
-		}
-	}
-
-	Device *device = getDevice();
-
-	mQuery->begin();
-	device->addQuery(mQuery);
-	device->setOcclusionEnabled(true);
-}
-
-void Query::end()
-{
-	if(!mQuery)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	Device *device = getDevice();
-
-	mQuery->end();
-	device->removeQuery(mQuery);
-	device->setOcclusionEnabled(false);
-
-	mStatus = GL_FALSE;
-	mResult = GL_FALSE;
-}
-
-GLuint Query::getResult()
-{
-	if(mQuery)
-	{
-		while(!testQuery())
-		{
-			sw::Thread::yield();
-		}
-	}
-
-	return (GLuint)mResult;
-}
-
-GLboolean Query::isResultAvailable()
-{
-	if(mQuery)
-	{
-		testQuery();
-	}
-
-	return mStatus;
-}
-
-GLenum Query::getType() const
-{
-	return mType;
-}
-
-GLboolean Query::testQuery()
-{
-	if(mQuery && mStatus != GL_TRUE)
-	{
-		if(!mQuery->building && mQuery->reference == 0)
-		{
-			unsigned int numPixels = mQuery->data;
-			mStatus = GL_TRUE;
-
-			switch(mType)
-			{
-			case GL_ANY_SAMPLES_PASSED:
-			case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
-				mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
-				break;
-			default:
-				ASSERT(false);
-			}
-		}
-
-		return mStatus;
-	}
-
-	return GL_TRUE;   // Prevent blocking when query is null
-}
-}
diff --git a/src/OpenGL/libGL/Query.h b/src/OpenGL/libGL/Query.h
deleted file mode 100644
index e16da8e..0000000
--- a/src/OpenGL/libGL/Query.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.
-
-// Query.h: Defines the gl::Query class
-
-#ifndef LIBGL_QUERY_H_
-#define LIBGL_QUERY_H_
-
-#include "common/Object.hpp"
-#include "Renderer/Renderer.hpp"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-namespace gl
-{
-
-class Query : public NamedObject
-{
-public:
-	Query(GLuint name, GLenum type);
-	virtual ~Query();
-
-	void begin();
-	void end();
-	GLuint getResult();
-	GLboolean isResultAvailable();
-
-	GLenum getType() const;
-
-private:
-	GLboolean testQuery();
-
-	sw::Query* mQuery;
-	GLenum mType;
-	GLboolean mStatus;
-	GLint mResult;
-};
-
-}
-
-#endif   // LIBGL_QUERY_H_
diff --git a/src/OpenGL/libGL/Renderbuffer.cpp b/src/OpenGL/libGL/Renderbuffer.cpp
deleted file mode 100644
index a2b8e97..0000000
--- a/src/OpenGL/libGL/Renderbuffer.cpp
+++ /dev/null
@@ -1,493 +0,0 @@
-// 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.
-
-// Renderbuffer.cpp: the Renderbuffer class and its derived classes
-// Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
-// objects and related functionality.
-
-#include "Renderbuffer.h"
-
-#include "main.h"
-#include "Texture.h"
-#include "utilities.h"
-
-namespace gl
-{
-RenderbufferInterface::RenderbufferInterface()
-{
-}
-
-// The default case for classes inherited from RenderbufferInterface is not to
-// need to do anything upon the reference count to the parent Renderbuffer incrementing
-// or decrementing.
-void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy)
-{
-}
-
-void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy)
-{
-}
-
-GLuint RenderbufferInterface::getRedSize() const
-{
-	return sw2es::GetRedSize(getInternalFormat());
-}
-
-GLuint RenderbufferInterface::getGreenSize() const
-{
-	return sw2es::GetGreenSize(getInternalFormat());
-}
-
-GLuint RenderbufferInterface::getBlueSize() const
-{
-	return sw2es::GetBlueSize(getInternalFormat());
-}
-
-GLuint RenderbufferInterface::getAlphaSize() const
-{
-	return sw2es::GetAlphaSize(getInternalFormat());
-}
-
-GLuint RenderbufferInterface::getDepthSize() const
-{
-	return sw2es::GetDepthSize(getInternalFormat());
-}
-
-GLuint RenderbufferInterface::getStencilSize() const
-{
-	return sw2es::GetStencilSize(getInternalFormat());
-}
-
-///// RenderbufferTexture2D Implementation ////////
-
-RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture)
-{
-	mTexture2D = texture;
-}
-
-RenderbufferTexture2D::~RenderbufferTexture2D()
-{
-	mTexture2D = nullptr;
-}
-
-// Textures need to maintain their own reference count for references via
-// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
-void RenderbufferTexture2D::addProxyRef(const Renderbuffer *proxy)
-{
-	mTexture2D->addProxyRef(proxy);
-}
-
-void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
-{
-	mTexture2D->releaseProxy(proxy);
-}
-
-// Increments refcount on surface.
-// caller must release() the returned surface
-Image *RenderbufferTexture2D::getRenderTarget()
-{
-	return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0);
-}
-
-GLsizei RenderbufferTexture2D::getWidth() const
-{
-	return mTexture2D->getWidth(GL_TEXTURE_2D, 0);
-}
-
-GLsizei RenderbufferTexture2D::getHeight() const
-{
-	return mTexture2D->getHeight(GL_TEXTURE_2D, 0);
-}
-
-GLenum RenderbufferTexture2D::getFormat() const
-{
-	return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
-}
-
-sw::Format RenderbufferTexture2D::getInternalFormat() const
-{
-	return mTexture2D->getInternalFormat(GL_TEXTURE_2D, 0);
-}
-
-GLsizei RenderbufferTexture2D::getSamples() const
-{
-	return 0;
-}
-
-///// RenderbufferTextureCubeMap Implementation ////////
-
-RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target)
-{
-	mTextureCubeMap = texture;
-}
-
-RenderbufferTextureCubeMap::~RenderbufferTextureCubeMap()
-{
-	mTextureCubeMap = nullptr;
-}
-
-// Textures need to maintain their own reference count for references via
-// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
-void RenderbufferTextureCubeMap::addProxyRef(const Renderbuffer *proxy)
-{
-	mTextureCubeMap->addProxyRef(proxy);
-}
-
-void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
-{
-	mTextureCubeMap->releaseProxy(proxy);
-}
-
-// Increments refcount on surface.
-// caller must release() the returned surface
-Image *RenderbufferTextureCubeMap::getRenderTarget()
-{
-	return mTextureCubeMap->getRenderTarget(mTarget, 0);
-}
-
-GLsizei RenderbufferTextureCubeMap::getWidth() const
-{
-	return mTextureCubeMap->getWidth(mTarget, 0);
-}
-
-GLsizei RenderbufferTextureCubeMap::getHeight() const
-{
-	return mTextureCubeMap->getHeight(mTarget, 0);
-}
-
-GLenum RenderbufferTextureCubeMap::getFormat() const
-{
-	return mTextureCubeMap->getFormat(mTarget, 0);
-}
-
-sw::Format RenderbufferTextureCubeMap::getInternalFormat() const
-{
-	return mTextureCubeMap->getInternalFormat(mTarget, 0);
-}
-
-GLsizei RenderbufferTextureCubeMap::getSamples() const
-{
-	return 0;
-}
-
-////// Renderbuffer Implementation //////
-
-Renderbuffer::Renderbuffer(GLuint name, RenderbufferInterface *instance) : NamedObject(name)
-{
-	ASSERT(instance);
-	mInstance = instance;
-}
-
-Renderbuffer::~Renderbuffer()
-{
-	delete mInstance;
-}
-
-// The RenderbufferInterface contained in this Renderbuffer may need to maintain
-// its own reference count, so we pass it on here.
-void Renderbuffer::addRef()
-{
-	mInstance->addProxyRef(this);
-
-	Object::addRef();
-}
-
-void Renderbuffer::release()
-{
-	mInstance->releaseProxy(this);
-
-	Object::release();
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-Image *Renderbuffer::getRenderTarget()
-{
-	return mInstance->getRenderTarget();
-}
-
-GLsizei Renderbuffer::getWidth() const
-{
-	return mInstance->getWidth();
-}
-
-GLsizei Renderbuffer::getHeight() const
-{
-	return mInstance->getHeight();
-}
-
-GLenum Renderbuffer::getFormat() const
-{
-	return mInstance->getFormat();
-}
-
-sw::Format Renderbuffer::getInternalFormat() const
-{
-	return mInstance->getInternalFormat();
-}
-
-GLuint Renderbuffer::getRedSize() const
-{
-	return mInstance->getRedSize();
-}
-
-GLuint Renderbuffer::getGreenSize() const
-{
-	return mInstance->getGreenSize();
-}
-
-GLuint Renderbuffer::getBlueSize() const
-{
-	return mInstance->getBlueSize();
-}
-
-GLuint Renderbuffer::getAlphaSize() const
-{
-	return mInstance->getAlphaSize();
-}
-
-GLuint Renderbuffer::getDepthSize() const
-{
-	return mInstance->getDepthSize();
-}
-
-GLuint Renderbuffer::getStencilSize() const
-{
-	return mInstance->getStencilSize();
-}
-
-GLsizei Renderbuffer::getSamples() const
-{
-	return mInstance->getSamples();
-}
-
-void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
-{
-	ASSERT(newStorage);
-
-	delete mInstance;
-	mInstance = newStorage;
-}
-
-RenderbufferStorage::RenderbufferStorage()
-{
-	mWidth = 0;
-	mHeight = 0;
-	format = GL_RGBA4;
-	internalFormat = sw::FORMAT_A8R8G8B8;
-	mSamples = 0;
-}
-
-RenderbufferStorage::~RenderbufferStorage()
-{
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-Image *RenderbufferStorage::getRenderTarget()
-{
-	return nullptr;
-}
-
-GLsizei RenderbufferStorage::getWidth() const
-{
-	return mWidth;
-}
-
-GLsizei RenderbufferStorage::getHeight() const
-{
-	return mHeight;
-}
-
-GLenum RenderbufferStorage::getFormat() const
-{
-	return format;
-}
-
-sw::Format RenderbufferStorage::getInternalFormat() const
-{
-	return internalFormat;
-}
-
-GLsizei RenderbufferStorage::getSamples() const
-{
-	return mSamples;
-}
-
-Colorbuffer::Colorbuffer(Image *renderTarget) : mRenderTarget(renderTarget)
-{
-	if(renderTarget)
-	{
-		renderTarget->addRef();
-
-		mWidth = renderTarget->getWidth();
-		mHeight = renderTarget->getHeight();
-		internalFormat = renderTarget->getInternalFormat();
-		format = sw2es::ConvertBackBufferFormat(internalFormat);
-		mSamples = renderTarget->getMultiSampleDepth() & ~1;
-	}
-}
-
-Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(nullptr)
-{
-	Device *device = getDevice();
-
-	sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format);
-	int supportedSamples = Context::getSupportedMultisampleCount(samples);
-
-	if(width > 0 && height > 0)
-	{
-		mRenderTarget = device->createRenderTarget(width, height, requestedFormat, supportedSamples, false);
-
-		if(!mRenderTarget)
-		{
-			error(GL_OUT_OF_MEMORY);
-			return;
-		}
-	}
-
-	mWidth = width;
-	mHeight = height;
-	this->format = format;
-	internalFormat = requestedFormat;
-	mSamples = supportedSamples;
-}
-
-Colorbuffer::~Colorbuffer()
-{
-	if(mRenderTarget)
-	{
-		mRenderTarget->release();
-	}
-}
-
-// Increments refcount on surface.
-// caller must release() the returned surface
-Image *Colorbuffer::getRenderTarget()
-{
-	if(mRenderTarget)
-	{
-		mRenderTarget->addRef();
-	}
-
-	return mRenderTarget;
-}
-
-DepthStencilbuffer::DepthStencilbuffer(Image *depthStencil) : mDepthStencil(depthStencil)
-{
-	if(depthStencil)
-	{
-		depthStencil->addRef();
-
-		mWidth = depthStencil->getWidth();
-		mHeight = depthStencil->getHeight();
-		internalFormat = depthStencil->getInternalFormat();
-		format = sw2es::ConvertDepthStencilFormat(internalFormat);
-		mSamples = depthStencil->getMultiSampleDepth() & ~1;
-	}
-}
-
-DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) : mDepthStencil(nullptr)
-{
-	Device *device = getDevice();
-
-	int supportedSamples = Context::getSupportedMultisampleCount(samples);
-
-	if(width > 0 && height > 0)
-	{
-		mDepthStencil = device->createDepthStencilSurface(width, height, sw::FORMAT_D24S8, supportedSamples, false);
-
-		if(!mDepthStencil)
-		{
-			error(GL_OUT_OF_MEMORY);
-			return;
-		}
-	}
-
-	mWidth = width;
-	mHeight = height;
-	format = GL_DEPTH24_STENCIL8_EXT;
-	internalFormat = sw::FORMAT_D24S8;
-	mSamples = supportedSamples;
-}
-
-DepthStencilbuffer::~DepthStencilbuffer()
-{
-	if(mDepthStencil)
-	{
-		mDepthStencil->release();
-	}
-}
-
-// Increments refcount on surface.
-// caller must release() the returned surface
-Image *DepthStencilbuffer::getRenderTarget()
-{
-	if(mDepthStencil)
-	{
-		mDepthStencil->addRef();
-	}
-
-	return mDepthStencil;
-}
-
-Depthbuffer::Depthbuffer(Image *depthStencil) : DepthStencilbuffer(depthStencil)
-{
-	if(depthStencil)
-	{
-		format = GL_DEPTH_COMPONENT16;   // If the renderbuffer parameters are queried, the calling function
-		                                 // will expect one of the valid renderbuffer formats for use in
-		                                 // glRenderbufferStorage
-	}
-}
-
-Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
-{
-	if(mDepthStencil)
-	{
-		format = GL_DEPTH_COMPONENT16;   // If the renderbuffer parameters are queried, the calling function
-		                                 // will expect one of the valid renderbuffer formats for use in
-		                                 // glRenderbufferStorage
-	}
-}
-
-Depthbuffer::~Depthbuffer()
-{
-}
-
-Stencilbuffer::Stencilbuffer(Image *depthStencil) : DepthStencilbuffer(depthStencil)
-{
-	if(depthStencil)
-	{
-		format = GL_STENCIL_INDEX8;   // If the renderbuffer parameters are queried, the calling function
-		                              // will expect one of the valid renderbuffer formats for use in
-		                              // glRenderbufferStorage
-	}
-}
-
-Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
-{
-	if(mDepthStencil)
-	{
-		format = GL_STENCIL_INDEX8;   // If the renderbuffer parameters are queried, the calling function
-		                              // will expect one of the valid renderbuffer formats for use in
-		                              // glRenderbufferStorage
-	}
-}
-
-Stencilbuffer::~Stencilbuffer()
-{
-}
-
-}
diff --git a/src/OpenGL/libGL/Renderbuffer.h b/src/OpenGL/libGL/Renderbuffer.h
deleted file mode 100644
index 55c639a..0000000
--- a/src/OpenGL/libGL/Renderbuffer.h
+++ /dev/null
@@ -1,220 +0,0 @@
-// 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.
-
-// Renderbuffer.h: Defines the wrapper class Renderbuffer, as well as the
-// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
-// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
-// objects and related functionality.
-
-#ifndef LIBGL_RENDERBUFFER_H_
-#define LIBGL_RENDERBUFFER_H_
-
-#include "common/Object.hpp"
-#include "Image.hpp"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-namespace gl
-{
-class Texture2D;
-class TextureCubeMap;
-class Renderbuffer;
-class Colorbuffer;
-class DepthStencilbuffer;
-
-class RenderbufferInterface
-{
-public:
-	RenderbufferInterface();
-
-	virtual ~RenderbufferInterface() {};
-
-	virtual void addProxyRef(const Renderbuffer *proxy);
-	virtual void releaseProxy(const Renderbuffer *proxy);
-
-	virtual Image *getRenderTarget() = 0;
-
-	virtual GLsizei getWidth() const = 0;
-	virtual GLsizei getHeight() const = 0;
-	virtual GLenum getFormat() const = 0;
-	virtual sw::Format getInternalFormat() const = 0;
-	virtual GLsizei getSamples() const = 0;
-
-	GLuint getRedSize() const;
-	GLuint getGreenSize() const;
-	GLuint getBlueSize() const;
-	GLuint getAlphaSize() const;
-	GLuint getDepthSize() const;
-	GLuint getStencilSize() const;
-};
-
-class RenderbufferTexture2D : public RenderbufferInterface
-{
-public:
-	RenderbufferTexture2D(Texture2D *texture);
-
-	virtual ~RenderbufferTexture2D();
-
-	virtual void addProxyRef(const Renderbuffer *proxy);
-	virtual void releaseProxy(const Renderbuffer *proxy);
-
-	Image *getRenderTarget();
-
-	virtual GLsizei getWidth() const;
-	virtual GLsizei getHeight() const;
-	virtual GLenum getFormat() const;
-	virtual sw::Format getInternalFormat() const;
-	virtual GLsizei getSamples() const;
-
-private:
-	BindingPointer<Texture2D> mTexture2D;
-};
-
-class RenderbufferTextureCubeMap : public RenderbufferInterface
-{
-public:
-	RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target);
-
-	virtual ~RenderbufferTextureCubeMap();
-
-	virtual void addProxyRef(const Renderbuffer *proxy);
-	virtual void releaseProxy(const Renderbuffer *proxy);
-
-	Image *getRenderTarget();
-
-	virtual GLsizei getWidth() const;
-	virtual GLsizei getHeight() const;
-	virtual GLenum getFormat() const;
-	virtual sw::Format getInternalFormat() const;
-	virtual GLsizei getSamples() const;
-
-private:
-	BindingPointer<TextureCubeMap> mTextureCubeMap;
-	GLenum mTarget;
-};
-
-// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
-// is called. The specific concrete type depends on whether the internal format is
-// colour depth, stencil or packed depth/stencil.
-class RenderbufferStorage : public RenderbufferInterface
-{
-public:
-	RenderbufferStorage();
-
-	virtual ~RenderbufferStorage() = 0;
-
-	virtual Image *getRenderTarget();
-
-	virtual GLsizei getWidth() const;
-	virtual GLsizei getHeight() const;
-	virtual GLenum getFormat() const;
-	virtual sw::Format getInternalFormat() const;
-	virtual GLsizei getSamples() const;
-
-protected:
-	GLsizei mWidth;
-	GLsizei mHeight;
-	GLenum format;
-	sw::Format internalFormat;
-	GLsizei mSamples;
-};
-
-// Renderbuffer implements the GL renderbuffer object.
-// It's only a proxy for a RenderbufferInterface instance; the internal object
-// can change whenever glRenderbufferStorage is called.
-class Renderbuffer : public NamedObject
-{
-public:
-	Renderbuffer(GLuint name, RenderbufferInterface *storage);
-
-	virtual ~Renderbuffer();
-
-	// These functions from Object are overloaded here because
-	// Textures need to maintain their own count of references to them via
-	// Renderbuffers/RenderbufferTextures. These functions invoke those
-	// reference counting functions on the RenderbufferInterface.
-	virtual void addRef();
-	virtual void release();
-
-	Image *getRenderTarget();
-
-	GLsizei getWidth() const;
-	GLsizei getHeight() const;
-	GLenum getFormat() const;
-	sw::Format getInternalFormat() const;
-	GLuint getRedSize() const;
-	GLuint getGreenSize() const;
-	GLuint getBlueSize() const;
-	GLuint getAlphaSize() const;
-	GLuint getDepthSize() const;
-	GLuint getStencilSize() const;
-	GLsizei getSamples() const;
-
-	void setStorage(RenderbufferStorage *newStorage);
-
-private:
-	RenderbufferInterface *mInstance;
-};
-
-class Colorbuffer : public RenderbufferStorage
-{
-public:
-	explicit Colorbuffer(Image *renderTarget);
-	Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
-
-	virtual ~Colorbuffer();
-
-	virtual Image *getRenderTarget();
-
-private:
-	Image *mRenderTarget;
-};
-
-class DepthStencilbuffer : public RenderbufferStorage
-{
-public:
-	explicit DepthStencilbuffer(Image *depthStencil);
-	DepthStencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
-
-	~DepthStencilbuffer();
-
-	virtual Image *getRenderTarget();
-
-protected:
-	Image *mDepthStencil;
-};
-
-class Depthbuffer : public DepthStencilbuffer
-{
-public:
-	explicit Depthbuffer(Image *depthStencil);
-	Depthbuffer(GLsizei width, GLsizei height, GLsizei samples);
-
-	virtual ~Depthbuffer();
-};
-
-class Stencilbuffer : public DepthStencilbuffer
-{
-public:
-	explicit Stencilbuffer(Image *depthStencil);
-	Stencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
-
-	virtual ~Stencilbuffer();
-};
-}
-
-#endif   // LIBGL_RENDERBUFFER_H_
diff --git a/src/OpenGL/libGL/ResourceManager.cpp b/src/OpenGL/libGL/ResourceManager.cpp
deleted file mode 100644
index 48b912b..0000000
--- a/src/OpenGL/libGL/ResourceManager.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-// 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.
-
-// ResourceManager.cpp: Implements the ResourceManager class, which tracks and
-// retrieves objects which may be shared by multiple Contexts.
-
-#include "ResourceManager.h"
-
-#include "Buffer.h"
-#include "Program.h"
-#include "Renderbuffer.h"
-#include "Shader.h"
-#include "Texture.h"
-
-namespace gl
-{
-ResourceManager::ResourceManager()
-{
-	mRefCount = 1;
-}
-
-ResourceManager::~ResourceManager()
-{
-	while(!mBufferMap.empty())
-	{
-		deleteBuffer(mBufferMap.begin()->first);
-	}
-
-	while(!mProgramMap.empty())
-	{
-		deleteProgram(mProgramMap.begin()->first);
-	}
-
-	while(!mShaderMap.empty())
-	{
-		deleteShader(mShaderMap.begin()->first);
-	}
-
-	while(!mRenderbufferMap.empty())
-	{
-		deleteRenderbuffer(mRenderbufferMap.begin()->first);
-	}
-
-	while(!mTextureMap.empty())
-	{
-		deleteTexture(mTextureMap.begin()->first);
-	}
-}
-
-void ResourceManager::addRef()
-{
-	mRefCount++;
-}
-
-void ResourceManager::release()
-{
-	if(--mRefCount == 0)
-	{
-		delete this;
-	}
-}
-
-// Returns an unused buffer name
-GLuint ResourceManager::createBuffer()
-{
-	//GLuint handle = mBufferNameSpace.allocate();
-	unsigned int handle = 1;
-
-	while (mBufferMap.find(handle) != mBufferMap.end())
-	{
-		handle++;
-	}
-
-	mBufferMap[handle] = nullptr;
-
-	return handle;
-}
-
-// Returns an unused shader/program name
-GLuint ResourceManager::createShader(GLenum type)
-{
-	//GLuint handle = mProgramShaderNameSpace.allocate();
-	unsigned int handle = 1;
-
-	while (mShaderMap.find(handle) != mShaderMap.end())
-	{
-		handle++;
-	}
-
-	if(type == GL_VERTEX_SHADER)
-	{
-		mShaderMap[handle] = new VertexShader(this, handle);
-	}
-	else if(type == GL_FRAGMENT_SHADER)
-	{
-		mShaderMap[handle] = new FragmentShader(this, handle);
-	}
-	else UNREACHABLE(type);
-
-	return handle;
-}
-
-// Returns an unused program/shader name
-GLuint ResourceManager::createProgram()
-{
-	//GLuint handle = mProgramShaderNameSpace.allocate();
-	unsigned int handle = 1;
-
-	while (mProgramMap.find(handle) != mProgramMap.end())
-	{
-		handle++;
-	}
-
-	mProgramMap[handle] = new Program(this, handle);
-
-	return handle;
-}
-
-// Returns an unused texture name
-GLuint ResourceManager::createTexture()
-{
-	//GLuint handle = mTextureNameSpace.allocate();
-	unsigned int handle = 1;
-
-	while (mTextureMap.find(handle) != mTextureMap.end())
-	{
-		handle++;
-	}
-
-	mTextureMap[handle] = nullptr;
-
-	return handle;
-}
-
-// Returns an unused renderbuffer name
-GLuint ResourceManager::createRenderbuffer()
-{
-	//GLuint handle = mRenderbufferNameSpace.allocate();
-	unsigned int handle = 1;
-
-	while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
-	{
-		handle++;
-	}
-
-	mRenderbufferMap[handle] = nullptr;
-
-	return handle;
-}
-
-void ResourceManager::deleteBuffer(GLuint buffer)
-{
-	BufferMap::iterator bufferObject = mBufferMap.find(buffer);
-
-	if(bufferObject != mBufferMap.end())
-	{
-		//mBufferNameSpace.release(bufferObject->first);
-		if(bufferObject->second) bufferObject->second->release();
-		mBufferMap.erase(bufferObject);
-	}
-}
-
-void ResourceManager::deleteShader(GLuint shader)
-{
-	ShaderMap::iterator shaderObject = mShaderMap.find(shader);
-
-	if(shaderObject != mShaderMap.end())
-	{
-		if(shaderObject->second->getRefCount() == 0)
-		{
-			//mProgramShaderNameSpace.release(shaderObject->first);
-			delete shaderObject->second;
-			mShaderMap.erase(shaderObject);
-		}
-		else
-		{
-			shaderObject->second->flagForDeletion();
-		}
-	}
-}
-
-void ResourceManager::deleteProgram(GLuint program)
-{
-	ProgramMap::iterator programObject = mProgramMap.find(program);
-
-	if(programObject != mProgramMap.end())
-	{
-		if(programObject->second->getRefCount() == 0)
-		{
-			//mProgramShaderNameSpace.release(programObject->first);
-			delete programObject->second;
-			mProgramMap.erase(programObject);
-		}
-		else
-		{
-			programObject->second->flagForDeletion();
-		}
-	}
-}
-
-void ResourceManager::deleteTexture(GLuint texture)
-{
-	TextureMap::iterator textureObject = mTextureMap.find(texture);
-
-	if(textureObject != mTextureMap.end())
-	{
-		//mTextureNameSpace.release(textureObject->first);
-		if(textureObject->second) textureObject->second->release();
-		mTextureMap.erase(textureObject);
-	}
-}
-
-void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
-{
-	RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
-
-	if(renderbufferObject != mRenderbufferMap.end())
-	{
-		//mRenderbufferNameSpace.release(renderbufferObject->first);
-		if(renderbufferObject->second) renderbufferObject->second->release();
-		mRenderbufferMap.erase(renderbufferObject);
-	}
-}
-
-Buffer *ResourceManager::getBuffer(unsigned int handle)
-{
-	BufferMap::iterator buffer = mBufferMap.find(handle);
-
-	if(buffer == mBufferMap.end())
-	{
-		return nullptr;
-	}
-	else
-	{
-		return buffer->second;
-	}
-}
-
-Shader *ResourceManager::getShader(unsigned int handle)
-{
-	ShaderMap::iterator shader = mShaderMap.find(handle);
-
-	if(shader == mShaderMap.end())
-	{
-		return nullptr;
-	}
-	else
-	{
-		return shader->second;
-	}
-}
-
-Texture *ResourceManager::getTexture(unsigned int handle)
-{
-	if(handle == 0) return nullptr;
-
-	TextureMap::iterator texture = mTextureMap.find(handle);
-
-	if(texture == mTextureMap.end())
-	{
-		return nullptr;
-	}
-	else
-	{
-		return texture->second;
-	}
-}
-
-Program *ResourceManager::getProgram(unsigned int handle)
-{
-	ProgramMap::iterator program = mProgramMap.find(handle);
-
-	if(program == mProgramMap.end())
-	{
-		return nullptr;
-	}
-	else
-	{
-		return program->second;
-	}
-}
-
-Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
-{
-	RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
-
-	if(renderbuffer == mRenderbufferMap.end())
-	{
-		return nullptr;
-	}
-	else
-	{
-		return renderbuffer->second;
-	}
-}
-
-void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
-{
-	mRenderbufferMap[handle] = buffer;
-}
-
-void ResourceManager::checkBufferAllocation(unsigned int buffer)
-{
-	if(buffer != 0 && !getBuffer(buffer))
-	{
-		Buffer *bufferObject = new Buffer(buffer);
-		mBufferMap[buffer] = bufferObject;
-		bufferObject->addRef();
-	}
-}
-
-void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
-{
-	if(!getTexture(texture) && texture != 0)
-	{
-		Texture *textureObject;
-
-		if(type == TEXTURE_2D)
-		{
-			textureObject = new Texture2D(texture);
-		}
-		else if(type == TEXTURE_CUBE)
-		{
-			textureObject = new TextureCubeMap(texture);
-		}
-		else
-		{
-			UNREACHABLE(type);
-			return;
-		}
-
-		mTextureMap[texture] = textureObject;
-		textureObject->addRef();
-	}
-}
-
-void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
-{
-	if(renderbuffer != 0 && !getRenderbuffer(renderbuffer))
-	{
-		Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0));
-		mRenderbufferMap[renderbuffer] = renderbufferObject;
-		renderbufferObject->addRef();
-	}
-}
-
-}
diff --git a/src/OpenGL/libGL/ResourceManager.h b/src/OpenGL/libGL/ResourceManager.h
deleted file mode 100644
index e857b03..0000000
--- a/src/OpenGL/libGL/ResourceManager.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// 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.
-
-// ResourceManager.h : Defines the ResourceManager class, which tracks objects
-// shared by multiple GL contexts.
-
-#ifndef LIBGL_RESOURCEMANAGER_H_
-#define LIBGL_RESOURCEMANAGER_H_
-
-#include "common/NameSpace.hpp"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-#include <map>
-
-namespace gl
-{
-class Buffer;
-class Shader;
-class Program;
-class Texture;
-class Renderbuffer;
-
-enum TextureType
-{
-	TEXTURE_2D,
-	PROXY_TEXTURE_2D,
-	TEXTURE_CUBE,
-
-	TEXTURE_TYPE_COUNT,
-	TEXTURE_UNKNOWN
-};
-
-class ResourceManager
-{
-public:
-	ResourceManager();
-	~ResourceManager();
-
-	void addRef();
-	void release();
-
-	GLuint createBuffer();
-	GLuint createShader(GLenum type);
-	GLuint createProgram();
-	GLuint createTexture();
-	GLuint createRenderbuffer();
-
-	void deleteBuffer(GLuint buffer);
-	void deleteShader(GLuint shader);
-	void deleteProgram(GLuint program);
-	void deleteTexture(GLuint texture);
-	void deleteRenderbuffer(GLuint renderbuffer);
-
-	Buffer *getBuffer(GLuint handle);
-	Shader *getShader(GLuint handle);
-	Program *getProgram(GLuint handle);
-	Texture *getTexture(GLuint handle);
-	Renderbuffer *getRenderbuffer(GLuint handle);
-
-	void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
-
-	void checkBufferAllocation(unsigned int buffer);
-	void checkTextureAllocation(GLuint texture, TextureType type);
-	void checkRenderbufferAllocation(GLuint renderbuffer);
-
-private:
-	std::size_t mRefCount;
-
-	typedef std::map<GLint, Buffer*> BufferMap;
-	BufferMap mBufferMap;
-	//NameSpace mBufferNameSpace;
-
-	typedef std::map<GLint, Shader*> ShaderMap;
-	ShaderMap mShaderMap;
-
-	typedef std::map<GLint, Program*> ProgramMap;
-	ProgramMap mProgramMap;
-	//NameSpace mProgramShaderNameSpace;
-
-	typedef std::map<GLint, Texture*> TextureMap;
-	TextureMap mTextureMap;
-	//NameSpace mTextureNameSpace;
-
-	typedef std::map<GLint, Renderbuffer*> RenderbufferMap;
-	RenderbufferMap mRenderbufferMap;
-	//NameSpace mRenderbufferNameSpace;
-};
-
-}
-
-#endif // LIBGL_RESOURCEMANAGER_H_
diff --git a/src/OpenGL/libGL/Shader.cpp b/src/OpenGL/libGL/Shader.cpp
deleted file mode 100644
index 3a6b2cd..0000000
--- a/src/OpenGL/libGL/Shader.cpp
+++ /dev/null
@@ -1,445 +0,0 @@
-// 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.
-
-// Shader.cpp: Implements the Shader class and its  derived classes
-// VertexShader and FragmentShader. Implements GL shader objects and related
-// functionality.
-
-#include "Shader.h"
-
-#include "main.h"
-#include "utilities.h"
-
-#include <string>
-
-namespace gl
-{
-bool Shader::compilerInitialized = false;
-
-Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
-{
-	mSource = nullptr;
-
-	clear();
-
-	mRefCount = 0;
-	mDeleteStatus = false;
-}
-
-Shader::~Shader()
-{
-	delete[] mSource;
-}
-
-GLuint Shader::getName() const
-{
-	return mHandle;
-}
-
-void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
-{
-	delete[] mSource;
-	int totalLength = 0;
-
-	for(int i = 0; i < count; i++)
-	{
-		if(length && length[i] >= 0)
-		{
-			totalLength += length[i];
-		}
-		else
-		{
-			totalLength += (int)strlen(string[i]);
-		}
-	}
-
-	mSource = new char[totalLength + 1];
-	char *code = mSource;
-
-	for(int i = 0; i < count; i++)
-	{
-		int stringLength;
-
-		if(length && length[i] >= 0)
-		{
-			stringLength = length[i];
-		}
-		else
-		{
-			stringLength = (int)strlen(string[i]);
-		}
-
-		strncpy(code, string[i], stringLength);
-		code += stringLength;
-	}
-
-	mSource[totalLength] = '\0';
-}
-
-int Shader::getInfoLogLength() const
-{
-	if(infoLog.empty())
-	{
-		return 0;
-	}
-	else
-	{
-	   return infoLog.size() + 1;
-	}
-}
-
-void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLogOut)
-{
-	int index = 0;
-
-	if(bufSize > 0)
-	{
-		if(!infoLog.empty())
-		{
-			index = std::min(bufSize - 1, (GLsizei)infoLog.size());
-			memcpy(infoLogOut, infoLog.c_str(), index);
-		}
-
-		infoLogOut[index] = '\0';
-	}
-
-	if(length)
-	{
-		*length = index;
-	}
-}
-
-int Shader::getSourceLength() const
-{
-	if(!mSource)
-	{
-		return 0;
-	}
-	else
-	{
-	   return strlen(mSource) + 1;
-	}
-}
-
-void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source)
-{
-	int index = 0;
-
-	if(bufSize > 0)
-	{
-		if(mSource)
-		{
-			index = std::min(bufSize - 1, (int)strlen(mSource));
-			memcpy(source, mSource, index);
-		}
-
-		source[index] = '\0';
-	}
-
-	if(length)
-	{
-		*length = index;
-	}
-}
-
-TranslatorASM *Shader::createCompiler(GLenum shaderType)
-{
-	if(!compilerInitialized)
-	{
-		InitCompilerGlobals();
-		compilerInitialized = true;
-	}
-
-	TranslatorASM *assembler = new TranslatorASM(this, shaderType);
-
-	ShBuiltInResources resources;
-	resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
-	resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
-	resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
-	resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
-	resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
-	resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
-	resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
-	resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
-	resources.OES_standard_derivatives = 1;
-	resources.OES_fragment_precision_high = 1;
-	resources.MaxCallStackDepth = 16;
-	assembler->Init(resources);
-
-	return assembler;
-}
-
-void Shader::clear()
-{
-	infoLog.clear();
-
-	varyings.clear();
-	activeUniforms.clear();
-	activeAttributes.clear();
-}
-
-void Shader::compile()
-{
-	clear();
-
-	createShader();
-	TranslatorASM *compiler = createCompiler(getType());
-
-	// Ensure we don't pass a nullptr source to the compiler
-	const char *source = "\0";
-	if(mSource)
-	{
-		source = mSource;
-	}
-
-	bool success = compiler->compile(&source, 1, SH_OBJECT_CODE);
-
-	if(false)
-	{
-		static int serial = 1;
-		char buffer[256];
-		sprintf(buffer, "shader-input-%d-%d.txt", getName(), serial);
-		FILE *file = fopen(buffer, "wt");
-		fprintf(file, "%s", mSource);
-		fclose(file);
-		getShader()->print("shader-output-%d-%d.txt", getName(), serial);
-		serial++;
-	}
-
-	if(!success)
-	{
-		deleteShader();
-
-		infoLog = compiler->getInfoSink().info.c_str();
-		TRACE("\n%s", infoLog.c_str());
-	}
-
-	delete compiler;
-}
-
-bool Shader::isCompiled()
-{
-	return getShader() != 0;
-}
-
-void Shader::addRef()
-{
-	mRefCount++;
-}
-
-void Shader::release()
-{
-	mRefCount--;
-
-	if(mRefCount == 0 && mDeleteStatus)
-	{
-		mResourceManager->deleteShader(mHandle);
-	}
-}
-
-unsigned int Shader::getRefCount() const
-{
-	return mRefCount;
-}
-
-bool Shader::isFlaggedForDeletion() const
-{
-	return mDeleteStatus;
-}
-
-void Shader::flagForDeletion()
-{
-	mDeleteStatus = true;
-}
-
-void Shader::releaseCompiler()
-{
-	FreeCompilerGlobals();
-	compilerInitialized = false;
-}
-
-// true if varying x has a higher priority in packing than y
-bool Shader::compareVarying(const glsl::Varying &x, const glsl::Varying &y)
-{
-	if(x.type == y.type)
-	{
-		return x.size() > y.size();
-	}
-
-	switch(x.type)
-	{
-	case GL_FLOAT_MAT4: return true;
-	case GL_FLOAT_MAT2:
-		switch(y.type)
-		{
-		case GL_FLOAT_MAT4: return false;
-		case GL_FLOAT_MAT2: return true;
-		case GL_FLOAT_VEC4: return true;
-		case GL_FLOAT_MAT3: return true;
-		case GL_FLOAT_VEC3: return true;
-		case GL_FLOAT_VEC2: return true;
-		case GL_FLOAT:      return true;
-		default: UNREACHABLE(y.type);
-		}
-		break;
-	case GL_FLOAT_VEC4:
-		switch(y.type)
-		{
-		case GL_FLOAT_MAT4: return false;
-		case GL_FLOAT_MAT2: return false;
-		case GL_FLOAT_VEC4: return true;
-		case GL_FLOAT_MAT3: return true;
-		case GL_FLOAT_VEC3: return true;
-		case GL_FLOAT_VEC2: return true;
-		case GL_FLOAT:      return true;
-		default: UNREACHABLE(y.type);
-		}
-		break;
-	case GL_FLOAT_MAT3:
-		switch(y.type)
-		{
-		case GL_FLOAT_MAT4: return false;
-		case GL_FLOAT_MAT2: return false;
-		case GL_FLOAT_VEC4: return false;
-		case GL_FLOAT_MAT3: return true;
-		case GL_FLOAT_VEC3: return true;
-		case GL_FLOAT_VEC2: return true;
-		case GL_FLOAT:      return true;
-		default: UNREACHABLE(y.type);
-		}
-		break;
-	case GL_FLOAT_VEC3:
-		switch(y.type)
-		{
-		case GL_FLOAT_MAT4: return false;
-		case GL_FLOAT_MAT2: return false;
-		case GL_FLOAT_VEC4: return false;
-		case GL_FLOAT_MAT3: return false;
-		case GL_FLOAT_VEC3: return true;
-		case GL_FLOAT_VEC2: return true;
-		case GL_FLOAT:      return true;
-		default: UNREACHABLE(y.type);
-		}
-		break;
-	case GL_FLOAT_VEC2:
-		switch(y.type)
-		{
-		case GL_FLOAT_MAT4: return false;
-		case GL_FLOAT_MAT2: return false;
-		case GL_FLOAT_VEC4: return false;
-		case GL_FLOAT_MAT3: return false;
-		case GL_FLOAT_VEC3: return false;
-		case GL_FLOAT_VEC2: return true;
-		case GL_FLOAT:      return true;
-		default: UNREACHABLE(y.type);
-		}
-		break;
-	case GL_FLOAT: return false;
-	default: UNREACHABLE(x.type);
-	}
-
-	return false;
-}
-
-VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
-{
-	vertexShader = 0;
-}
-
-VertexShader::~VertexShader()
-{
-	delete vertexShader;
-}
-
-GLenum VertexShader::getType()
-{
-	return GL_VERTEX_SHADER;
-}
-
-int VertexShader::getSemanticIndex(const std::string &attributeName)
-{
-	if(!attributeName.empty())
-	{
-		for(glsl::ActiveAttributes::iterator attribute = activeAttributes.begin(); attribute != activeAttributes.end(); attribute++)
-		{
-			if(attribute->name == attributeName)
-			{
-				return attribute->registerIndex;
-			}
-		}
-	}
-
-	return -1;
-}
-
-sw::Shader *VertexShader::getShader() const
-{
-	return vertexShader;
-}
-
-sw::VertexShader *VertexShader::getVertexShader() const
-{
-	return vertexShader;
-}
-
-void VertexShader::createShader()
-{
-	delete vertexShader;
-	vertexShader = new sw::VertexShader();
-}
-
-void VertexShader::deleteShader()
-{
-	delete vertexShader;
-	vertexShader = nullptr;
-}
-
-FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
-{
-	pixelShader = 0;
-}
-
-FragmentShader::~FragmentShader()
-{
-	delete pixelShader;
-}
-
-GLenum FragmentShader::getType()
-{
-	return GL_FRAGMENT_SHADER;
-}
-
-sw::Shader *FragmentShader::getShader() const
-{
-	return pixelShader;
-}
-
-sw::PixelShader *FragmentShader::getPixelShader() const
-{
-	return pixelShader;
-}
-
-void FragmentShader::createShader()
-{
-	delete pixelShader;
-	pixelShader = new sw::PixelShader();
-}
-
-void FragmentShader::deleteShader()
-{
-	delete pixelShader;
-	pixelShader = nullptr;
-}
-
-}
diff --git a/src/OpenGL/libGL/Shader.h b/src/OpenGL/libGL/Shader.h
deleted file mode 100644
index 2267ac6..0000000
--- a/src/OpenGL/libGL/Shader.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// 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.
-
-// Shader.h: Defines the abstract Shader class and its concrete derived
-// classes VertexShader and FragmentShader. Implements GL shader objects and
-// related functionality.
-
-
-#ifndef LIBGL_SHADER_H_
-#define LIBGL_SHADER_H_
-
-#include "ResourceManager.h"
-
-#include "compiler/TranslatorASM.h"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-#include <string>
-#include <list>
-#include <vector>
-
-namespace glsl
-{
-	class OutputASM;
-}
-
-namespace gl
-{
-
-class Shader : public glsl::Shader
-{
-	friend class Program;
-
-public:
-	Shader(ResourceManager *manager, GLuint handle);
-
-	virtual ~Shader();
-
-	virtual GLenum getType() = 0;
-	GLuint getName() const;
-
-	void deleteSource();
-	void setSource(GLsizei count, const char *const *string, const GLint *length);
-	int getInfoLogLength() const;
-	void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
-	int getSourceLength() const;
-	void getSource(GLsizei bufSize, GLsizei *length, char *source);
-
-	void compile();
-	bool isCompiled();
-
-	void addRef();
-	void release();
-	unsigned int getRefCount() const;
-	bool isFlaggedForDeletion() const;
-	void flagForDeletion();
-
-	static void releaseCompiler();
-
-protected:
-	static bool compilerInitialized;
-	TranslatorASM *createCompiler(GLenum shaderType);
-	void clear();
-
-	static bool compareVarying(const glsl::Varying &x, const glsl::Varying &y);
-
-	char *mSource;
-	std::string infoLog;
-
-private:
-	virtual void createShader() = 0;
-	virtual void deleteShader() = 0;
-
-	const GLuint mHandle;
-	unsigned int mRefCount;     // Number of program objects this shader is attached to
-	bool mDeleteStatus;         // Flag to indicate that the shader can be deleted when no longer in use
-
-	ResourceManager *mResourceManager;
-};
-
-class VertexShader : public Shader
-{
-	friend class Program;
-
-public:
-	VertexShader(ResourceManager *manager, GLuint handle);
-
-	~VertexShader();
-
-	virtual GLenum getType();
-	int getSemanticIndex(const std::string &attributeName);
-
-	virtual sw::Shader *getShader() const;
-	virtual sw::VertexShader *getVertexShader() const;
-
-private:
-	virtual void createShader();
-	virtual void deleteShader();
-
-	sw::VertexShader *vertexShader;
-};
-
-class FragmentShader : public Shader
-{
-public:
-	FragmentShader(ResourceManager *manager, GLuint handle);
-
-	~FragmentShader();
-
-	virtual GLenum getType();
-
-	virtual sw::Shader *getShader() const;
-	virtual sw::PixelShader *getPixelShader() const;
-
-private:
-	virtual void createShader();
-	virtual void deleteShader();
-
-	sw::PixelShader *pixelShader;
-};
-}
-
-#endif   // LIBGL_SHADER_H_
diff --git a/src/OpenGL/libGL/Surface.cpp b/src/OpenGL/libGL/Surface.cpp
deleted file mode 100644
index f5bfa0e..0000000
--- a/src/OpenGL/libGL/Surface.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-// 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.
-
-// Surface.cpp: Implements the Surface class, representing a drawing surface
-// such as the client area of a window, including any back buffers.
-
-#include "Surface.h"
-
-#include "main.h"
-#include "Display.h"
-#include "Image.hpp"
-#include "Context.h"
-#include "common/debug.h"
-#include "Main/FrameBuffer.hpp"
-
-#if defined(_WIN32)
-#include <tchar.h>
-#endif
-
-#include <algorithm>
-
-namespace gl
-{
-
-Surface::Surface(Display *display, NativeWindowType window)
-	: mDisplay(display), mWindow(window)
-{
-	frameBuffer = 0;
-	backBuffer = 0;
-
-	mDepthStencil = nullptr;
-	mTextureFormat = GL_NONE;
-	mTextureTarget = GL_NONE;
-
-	mSwapInterval = -1;
-	setSwapInterval(1);
-}
-
-Surface::Surface(Display *display, GLint width, GLint height, GLenum textureFormat, GLenum textureType)
-	: mDisplay(display), mWindow(nullptr), mWidth(width), mHeight(height)
-{
-	frameBuffer = 0;
-	backBuffer = 0;
-
-	mDepthStencil = nullptr;
-	mWindowSubclassed = false;
-	mTextureFormat = textureFormat;
-	mTextureTarget = textureType;
-
-	mSwapInterval = -1;
-	setSwapInterval(1);
-}
-
-Surface::~Surface()
-{
-	release();
-}
-
-bool Surface::initialize()
-{
-	ASSERT(!frameBuffer && !backBuffer && !mDepthStencil);
-
-	return reset();
-}
-
-void Surface::release()
-{
-	if(mDepthStencil)
-	{
-		mDepthStencil->release();
-		mDepthStencil = nullptr;
-	}
-
-	if(backBuffer)
-	{
-		backBuffer->release();
-		backBuffer = 0;
-	}
-
-	delete frameBuffer;
-	frameBuffer = 0;
-}
-
-bool Surface::reset()
-{
-	if(!mWindow)
-	{
-		return reset(mWidth, mHeight);
-	}
-
-	// FIXME: Wrap into an abstract Window class
-	#if defined(_WIN32)
-		RECT windowRect;
-		GetClientRect(mWindow, &windowRect);
-
-		return reset(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
-	#else
-		XWindowAttributes windowAttributes;
-		XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);
-
-		return reset(windowAttributes.width, windowAttributes.height);
-	#endif
-}
-
-bool Surface::reset(int backBufferWidth, int backBufferHeight)
-{
-	release();
-
-	if(mWindow)
-	{
-		frameBuffer = ::createFrameBuffer(mDisplay->getNativeDisplay(), mWindow, backBufferWidth, backBufferHeight);
-
-		if(!frameBuffer)
-		{
-			ERR("Could not create frame buffer");
-			release();
-			return error(GL_OUT_OF_MEMORY, false);
-		}
-	}
-
-	backBuffer = new Image(0, backBufferWidth, backBufferHeight, GL_RGB, GL_UNSIGNED_BYTE);
-
-	if(!backBuffer)
-	{
-		ERR("Could not create back buffer");
-		release();
-		return error(GL_OUT_OF_MEMORY, false);
-	}
-
-	if(true)   // Always provide a depth/stencil buffer
-	{
-		mDepthStencil = new Image(0, backBufferWidth, backBufferHeight, sw::FORMAT_D24S8, 1, false, true);
-
-		if(!mDepthStencil)
-		{
-			ERR("Could not create depth/stencil buffer for surface");
-			release();
-			return error(GL_OUT_OF_MEMORY, false);
-		}
-	}
-
-	mWidth = backBufferWidth;
-	mHeight = backBufferHeight;
-
-	return true;
-}
-
-void Surface::swap()
-{
-	if(backBuffer)
-	{
-		frameBuffer->flip(backBuffer);
-
-		checkForResize();
-	}
-}
-
-Image *Surface::getRenderTarget()
-{
-	if(backBuffer)
-	{
-		backBuffer->addRef();
-	}
-
-	return backBuffer;
-}
-
-Image *Surface::getDepthStencil()
-{
-	if(mDepthStencil)
-	{
-		mDepthStencil->addRef();
-	}
-
-	return mDepthStencil;
-}
-
-void Surface::setSwapInterval(GLint interval)
-{
-	if(mSwapInterval == interval)
-	{
-		return;
-	}
-
-	mSwapInterval = interval;
-	mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());
-	mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());
-}
-
-GLint Surface::getWidth() const
-{
-	return mWidth;
-}
-
-GLint Surface::getHeight() const
-{
-	return mHeight;
-}
-
-GLenum Surface::getTextureFormat() const
-{
-	return mTextureFormat;
-}
-
-GLenum Surface::getTextureTarget() const
-{
-	return mTextureTarget;
-}
-
-bool Surface::checkForResize()
-{
-	#if defined(_WIN32)
-		RECT client;
-		if(!GetClientRect(mWindow, &client))
-		{
-			ASSERT(false);
-			return false;
-		}
-
-		int clientWidth = client.right - client.left;
-		int clientHeight = client.bottom - client.top;
-	#else
-		XWindowAttributes windowAttributes;
-		XGetWindowAttributes(mDisplay->getNativeDisplay(), mWindow, &windowAttributes);
-
-		int clientWidth = windowAttributes.width;
-		int clientHeight = windowAttributes.height;
-	#endif
-
-	bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
-
-	if(sizeDirty)
-	{
-		reset(clientWidth, clientHeight);
-
-		if(getCurrentDrawSurface() == this)
-		{
-			getContext()->makeCurrent(this);
-		}
-
-		return true;
-	}
-
-	return false;
-}
-}
diff --git a/src/OpenGL/libGL/Surface.h b/src/OpenGL/libGL/Surface.h
deleted file mode 100644
index 70f910f..0000000
--- a/src/OpenGL/libGL/Surface.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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.
-
-// Surface.h: Defines the Surface class, representing a drawing surface
-// such as the client area of a window, including any back buffers.
-
-#ifndef INCLUDE_SURFACE_H_
-#define INCLUDE_SURFACE_H_
-
-#include "Main/FrameBuffer.hpp"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-#if defined(_WIN32)
-typedef HDC     NativeDisplayType;
-typedef HBITMAP NativePixmapType;
-typedef HWND    NativeWindowType;
-#else
-#error
-#endif
-
-namespace gl
-{
-class Image;
-class Display;
-
-class Surface
-{
-public:
-	Surface(Display *display, NativeWindowType window);
-	Surface(Display *display, GLint width, GLint height, GLenum textureFormat, GLenum textureTarget);
-
-	virtual ~Surface();
-
-	bool initialize();
-	void swap();
-
-	virtual Image *getRenderTarget();
-	virtual Image *getDepthStencil();
-
-	void setSwapInterval(GLint interval);
-
-	virtual GLint getWidth() const;
-	virtual GLint getHeight() const;
-	virtual GLenum getTextureFormat() const;
-	virtual GLenum getTextureTarget() const;
-
-	bool checkForResize();   // Returns true if surface changed due to resize
-
-private:
-	void release();
-	bool reset();
-
-	Display *const mDisplay;
-	Image *mDepthStencil;
-	sw::FrameBuffer *frameBuffer;
-	Image *backBuffer;
-
-	bool reset(int backbufferWidth, int backbufferHeight);
-
-	const NativeWindowType mWindow;   // Window that the surface is created for.
-	bool mWindowSubclassed;           // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
-	GLint mWidth;                     // Width of surface
-	GLint mHeight;                    // Height of surface
-	GLenum mTextureFormat;            // Format of texture: RGB, RGBA, or no texture
-	GLenum mTextureTarget;            // Type of texture: 2D or no texture
-	GLint mSwapInterval;
-};
-}
-
-#endif   // INCLUDE_SURFACE_H_
diff --git a/src/OpenGL/libGL/Texture.cpp b/src/OpenGL/libGL/Texture.cpp
deleted file mode 100644
index 3ff0cb3..0000000
--- a/src/OpenGL/libGL/Texture.cpp
+++ /dev/null
@@ -1,1036 +0,0 @@
-// 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.
-
-// Texture.cpp: Implements the Texture class and its derived classes
-// Texture2D and TextureCubeMap. Implements GL texture objects and related
-// functionality.
-
-#include "Texture.h"
-
-#include "main.h"
-#include "mathutil.h"
-#include "Framebuffer.h"
-#include "Device.hpp"
-#include "Display.h"
-#include "common/debug.h"
-
-#include <algorithm>
-
-namespace gl
-{
-
-Texture::Texture(GLuint name) : NamedObject(name)
-{
-	mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
-	mMagFilter = GL_LINEAR;
-	mWrapS = GL_REPEAT;
-	mWrapT = GL_REPEAT;
-	mMaxAnisotropy = 1.0f;
-	mMaxLevel = 1000;
-
-	resource = new sw::Resource(0);
-}
-
-Texture::~Texture()
-{
-	resource->destruct();
-}
-
-sw::Resource *Texture::getResource() const
-{
-	return resource;
-}
-
-// Returns true on successful filter state update (valid enum parameter)
-bool Texture::setMinFilter(GLenum filter)
-{
-	switch(filter)
-	{
-	case GL_NEAREST:
-	case GL_LINEAR:
-	case GL_NEAREST_MIPMAP_NEAREST:
-	case GL_LINEAR_MIPMAP_NEAREST:
-	case GL_NEAREST_MIPMAP_LINEAR:
-	case GL_LINEAR_MIPMAP_LINEAR:
-		mMinFilter = filter;
-		return true;
-	default:
-		return false;
-	}
-}
-
-// Returns true on successful filter state update (valid enum parameter)
-bool Texture::setMagFilter(GLenum filter)
-{
-	switch(filter)
-	{
-	case GL_NEAREST:
-	case GL_LINEAR:
-		mMagFilter = filter;
-		return true;
-	default:
-		return false;
-	}
-}
-
-// Returns true on successful wrap state update (valid enum parameter)
-bool Texture::setWrapS(GLenum wrap)
-{
-	switch(wrap)
-	{
-	case GL_CLAMP:
-	case GL_REPEAT:
-	case GL_CLAMP_TO_EDGE:
-	case GL_MIRRORED_REPEAT:
-		mWrapS = wrap;
-		return true;
-	default:
-		return false;
-	}
-}
-
-// Returns true on successful wrap state update (valid enum parameter)
-bool Texture::setWrapT(GLenum wrap)
-{
-	switch(wrap)
-	{
-	case GL_CLAMP:
-	case GL_REPEAT:
-	case GL_CLAMP_TO_EDGE:
-	case GL_MIRRORED_REPEAT:
-		 mWrapT = wrap;
-		 return true;
-	default:
-		return false;
-	}
-}
-
-// Returns true on successful max anisotropy update (valid anisotropy value)
-bool Texture::setMaxAnisotropy(float textureMaxAnisotropy)
-{
-	textureMaxAnisotropy = std::min(textureMaxAnisotropy, MAX_TEXTURE_MAX_ANISOTROPY);
-
-	if(textureMaxAnisotropy < 1.0f)
-	{
-		return false;
-	}
-
-	if(mMaxAnisotropy != textureMaxAnisotropy)
-	{
-		mMaxAnisotropy = textureMaxAnisotropy;
-	}
-
-	return true;
-}
-
-bool Texture::setMaxLevel(int level)
-{
-	if(level < 0)
-	{
-		return false;
-	}
-
-	mMaxLevel = level;
-
-	return true;
-}
-
-GLenum Texture::getMinFilter() const
-{
-	return mMinFilter;
-}
-
-GLenum Texture::getMagFilter() const
-{
-	return mMagFilter;
-}
-
-GLenum Texture::getWrapS() const
-{
-	return mWrapS;
-}
-
-GLenum Texture::getWrapT() const
-{
-	return mWrapT;
-}
-
-GLfloat Texture::getMaxAnisotropy() const
-{
-	return mMaxAnisotropy;
-}
-
-void Texture::setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image)
-{
-	if(pixels && image)
-	{
-		image->loadImageData(0, 0, 0, image->getWidth(), image->getHeight(), 1, format, type, unpackAlignment, pixels);
-	}
-}
-
-void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, Image *image)
-{
-	if(pixels && image && (imageSize > 0)) // imageSize's correlation to width and height is already validated with gl::ComputeCompressedSize() at the API level
-	{
-		image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), 1, imageSize, pixels);
-	}
-}
-
-void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image)
-{
-	if(!image)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(IsCompressed(image->getFormat()))
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	if(format != image->getFormat())
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	if(pixels)
-	{
-		image->loadImageData(xoffset, yoffset, 0, width, height, 1, format, type, unpackAlignment, pixels);
-	}
-}
-
-void Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image)
-{
-	if(!image)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	if(width + xoffset > image->getWidth() || height + yoffset > image->getHeight())
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(format != image->getFormat())
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	if(pixels && (imageSize > 0)) // imageSize's correlation to width and height is already validated with gl::ComputeCompressedSize() at the API level
-	{
-		image->loadCompressedData(xoffset, yoffset, 0, width, height, 1, imageSize, pixels);
-	}
-}
-
-bool Texture::copy(Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, Image *dest)
-{
-	Device *device = getDevice();
-
-	sw::SliceRect destRect(xoffset, yoffset, xoffset + (sourceRect.x1 - sourceRect.x0), yoffset + (sourceRect.y1 - sourceRect.y0), 0);
-	sw::SliceRect sourceSliceRect(sourceRect);
-	bool success = device->stretchRect(source, &sourceSliceRect, dest, &destRect, false);
-
-	if(!success)
-	{
-		return error(GL_OUT_OF_MEMORY, false);
-	}
-
-	return true;
-}
-
-bool Texture::isMipmapFiltered() const
-{
-	switch(mMinFilter)
-	{
-	case GL_NEAREST:
-	case GL_LINEAR:
-		return false;
-	case GL_NEAREST_MIPMAP_NEAREST:
-	case GL_LINEAR_MIPMAP_NEAREST:
-	case GL_NEAREST_MIPMAP_LINEAR:
-	case GL_LINEAR_MIPMAP_LINEAR:
-		return true;
-	default: UNREACHABLE(mMinFilter);
-	}
-
-	return false;
-}
-
-Texture2D::Texture2D(GLuint name) : Texture(name)
-{
-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
-	{
-		image[i] = 0;
-	}
-
-	mColorbufferProxy = nullptr;
-	mProxyRefs = 0;
-}
-
-Texture2D::~Texture2D()
-{
-	for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
-	{
-		if(image[i])
-		{
-			image[i]->unbind();
-			image[i] = 0;
-		}
-	}
-
-	mColorbufferProxy = nullptr;
-}
-
-// We need to maintain a count of references to renderbuffers acting as
-// proxies for this texture, so that we do not attempt to use a pointer
-// to a renderbuffer proxy which has been deleted.
-void Texture2D::addProxyRef(const Renderbuffer *proxy)
-{
-	mProxyRefs++;
-}
-
-void Texture2D::releaseProxy(const Renderbuffer *proxy)
-{
-	if(mProxyRefs > 0)
-	{
-		mProxyRefs--;
-	}
-
-	if(mProxyRefs == 0)
-	{
-		mColorbufferProxy = nullptr;
-	}
-}
-
-GLenum Texture2D::getTarget() const
-{
-	return GL_TEXTURE_2D;
-}
-
-GLsizei Texture2D::getWidth(GLenum target, GLint level) const
-{
-	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);
-	return image[level] ? image[level]->getWidth() : 0;
-}
-
-GLsizei Texture2D::getHeight(GLenum target, GLint level) const
-{
-	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);
-	return image[level] ? image[level]->getHeight() : 0;
-}
-
-GLenum Texture2D::getFormat(GLenum target, GLint level) const
-{
-	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);
-	return image[level] ? image[level]->getFormat() : GL_NONE;
-}
-
-GLenum Texture2D::getType(GLenum target, GLint level) const
-{
-	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);
-	return image[level] ? image[level]->getType() : GL_NONE;
-}
-
-sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const
-{
-	ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);
-	return image[level] ? image[level]->getInternalFormat() : sw::FORMAT_NULL;
-}
-
-int Texture2D::getTopLevel() const
-{
-	ASSERT(isSamplerComplete());
-	int levels = 0;
-
-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[levels])
-	{
-		levels++;
-	}
-
-	return levels;
-}
-
-void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
-{
-	if(image[level])
-	{
-		image[level]->unbind();
-	}
-
-	image[level] = new Image(this, width, height, format, type);
-
-	if(!image[level])
-	{
-		return error(GL_OUT_OF_MEMORY);
-	}
-
-	Texture::setImage(format, type, unpackAlignment, pixels, image[level]);
-}
-
-void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
-{
-	if(image[level])
-	{
-		image[level]->unbind();
-	}
-
-	image[level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);
-
-	if(!image[level])
-	{
-		return error(GL_OUT_OF_MEMORY);
-	}
-
-	Texture::setCompressedImage(imageSize, pixels, image[level]);
-}
-
-void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
-{
-	Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[level]);
-}
-
-void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
-{
-	Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[level]);
-}
-
-void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
-	if(image[level])
-	{
-		image[level]->unbind();
-	}
-
-	image[level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);
-
-	if(!image[level])
-	{
-		return error(GL_OUT_OF_MEMORY);
-	}
-
-	if(width != 0 && height != 0)
-	{
-		Image *renderTarget = source->getRenderTarget();
-
-		if(!renderTarget)
-		{
-			ERR("Failed to retrieve the render target.");
-			return error(GL_OUT_OF_MEMORY);
-		}
-
-		sw::Rect sourceRect = {x, y, x + width, y + height};
-		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
-
-		copy(renderTarget, sourceRect, format, 0, 0, image[level]);
-
-		renderTarget->release();
-	}
-}
-
-void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
-	if(!image[level])
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight())
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	Image *renderTarget = source->getRenderTarget();
-
-	if(!renderTarget)
-	{
-		ERR("Failed to retrieve the render target.");
-		return error(GL_OUT_OF_MEMORY);
-	}
-
-	sw::Rect sourceRect = {x, y, x + width, y + height};
-	sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
-
-	copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, image[level]);
-
-	renderTarget->release();
-}
-
-void Texture2D::setImage(Image *sharedImage)
-{
-	sharedImage->addRef();
-
-	if(image[0])
-	{
-		image[0]->unbind();
-	}
-
-	image[0] = sharedImage;
-}
-
-// Tests for 2D texture sampling completeness.
-bool Texture2D::isSamplerComplete() const
-{
-	if(!image[0])
-	{
-		return false;
-	}
-
-	GLsizei width = image[0]->getWidth();
-	GLsizei height = image[0]->getHeight();
-
-	if(width <= 0 || height <= 0)
-	{
-		return false;
-	}
-
-	if(isMipmapFiltered())
-	{
-		if(!isMipmapComplete())
-		{
-			return false;
-		}
-	}
-
-	return true;
-}
-
-// Tests for 2D texture (mipmap) completeness.
-bool Texture2D::isMipmapComplete() const
-{
-	GLsizei width = image[0]->getWidth();
-	GLsizei height = image[0]->getHeight();
-
-	int q = log2(std::max(width, height));
-
-	for(int level = 1; level <= q && level <= mMaxLevel; level++)
-	{
-		if(!image[level])
-		{
-			return false;
-		}
-
-		if(image[level]->getFormat() != image[0]->getFormat())
-		{
-			return false;
-		}
-
-		if(image[level]->getType() != image[0]->getType())
-		{
-			return false;
-		}
-
-		if(image[level]->getWidth() != std::max(1, width >> level))
-		{
-			return false;
-		}
-
-		if(image[level]->getHeight() != std::max(1, height >> level))
-		{
-			return false;
-		}
-	}
-
-	return true;
-}
-
-bool Texture2D::isCompressed(GLenum target, GLint level) const
-{
-	return IsCompressed(getFormat(target, level));
-}
-
-bool Texture2D::isDepth(GLenum target, GLint level) const
-{
-	return IsDepthTexture(getFormat(target, level));
-}
-
-void Texture2D::generateMipmaps()
-{
-	if(!image[0])
-	{
-		return;   // FIXME: error?
-	}
-
-	unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));
-
-	for(unsigned int i = 1; i <= q; i++)
-	{
-		if(image[i])
-		{
-			image[i]->unbind();
-		}
-
-		image[i] = new Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());
-
-		if(!image[i])
-		{
-			return error(GL_OUT_OF_MEMORY);
-		}
-
-		getDevice()->stretchRect(image[i - 1], 0, image[i], 0, true);
-	}
-}
-
-Image *Texture2D::getImage(unsigned int level)
-{
-	return image[level];
-}
-
-Renderbuffer *Texture2D::getRenderbuffer(GLenum target)
-{
-	if(target != GL_TEXTURE_2D)
-	{
-		return error(GL_INVALID_OPERATION, (Renderbuffer*)nullptr);
-	}
-
-	if(!mColorbufferProxy)
-	{
-		mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this));
-	}
-
-	return mColorbufferProxy;
-}
-
-Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)
-{
-	ASSERT(target == GL_TEXTURE_2D);
-	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
-
-	if(image[level])
-	{
-		image[level]->addRef();
-	}
-
-	return image[level];
-}
-
-TextureCubeMap::TextureCubeMap(GLuint name) : Texture(name)
-{
-	for(int f = 0; f < 6; f++)
-	{
-		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
-		{
-			image[f][i] = 0;
-		}
-	}
-
-	for(int f = 0; f < 6; f++)
-	{
-		mFaceProxies[f] = nullptr;
-		mFaceProxyRefs[f] = 0;
-	}
-}
-
-TextureCubeMap::~TextureCubeMap()
-{
-	for(int f = 0; f < 6; f++)
-	{
-		for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
-		{
-			if(image[f][i])
-			{
-				image[f][i]->unbind();
-				image[f][i] = 0;
-			}
-		}
-	}
-
-	for(int i = 0; i < 6; i++)
-	{
-		mFaceProxies[i] = nullptr;
-	}
-}
-
-// We need to maintain a count of references to renderbuffers acting as
-// proxies for this texture, so that the texture is not deleted while
-// proxy references still exist. If the reference count drops to zero,
-// we set our proxy pointer null, so that a new attempt at referencing
-// will cause recreation.
-void TextureCubeMap::addProxyRef(const Renderbuffer *proxy)
-{
-	for(int f = 0; f < 6; f++)
-	{
-		if(mFaceProxies[f] == proxy)
-		{
-			mFaceProxyRefs[f]++;
-		}
-	}
-}
-
-void TextureCubeMap::releaseProxy(const Renderbuffer *proxy)
-{
-	for(int f = 0; f < 6; f++)
-	{
-		if(mFaceProxies[f] == proxy)
-		{
-			if(mFaceProxyRefs[f] > 0)
-			{
-				mFaceProxyRefs[f]--;
-			}
-
-			if(mFaceProxyRefs[f] == 0)
-			{
-				mFaceProxies[f] = nullptr;
-			}
-		}
-	}
-}
-
-GLenum TextureCubeMap::getTarget() const
-{
-	return GL_TEXTURE_CUBE_MAP;
-}
-
-GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
-{
-	int face = CubeFaceIndex(target);
-	return image[face][level] ? image[face][level]->getWidth() : 0;
-}
-
-GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
-{
-	int face = CubeFaceIndex(target);
-	return image[face][level] ? image[face][level]->getHeight() : 0;
-}
-
-GLenum TextureCubeMap::getFormat(GLenum target, GLint level) const
-{
-	int face = CubeFaceIndex(target);
-	return image[face][level] ? image[face][level]->getFormat() : GL_NONE;
-}
-
-GLenum TextureCubeMap::getType(GLenum target, GLint level) const
-{
-	int face = CubeFaceIndex(target);
-	return image[face][level] ? image[face][level]->getType() : GL_NONE;
-}
-
-sw::Format TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
-{
-	int face = CubeFaceIndex(target);
-	return image[face][level] ? image[face][level]->getInternalFormat() : sw::FORMAT_NULL;
-}
-
-int TextureCubeMap::getTopLevel() const
-{
-	ASSERT(isSamplerComplete());
-	int levels = 0;
-
-	while(levels < IMPLEMENTATION_MAX_TEXTURE_LEVELS && image[0][levels])
-	{
-		levels++;
-	}
-
-	return levels;
-}
-
-void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
-{
-	int face = CubeFaceIndex(target);
-
-	if(image[face][level])
-	{
-		image[face][level]->unbind();
-	}
-
-	image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);
-
-	if(!image[face][level])
-	{
-		return error(GL_OUT_OF_MEMORY);
-	}
-
-	Texture::setCompressedImage(imageSize, pixels, image[face][level]);
-}
-
-void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
-{
-	Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, image[CubeFaceIndex(target)][level]);
-}
-
-void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
-{
-	Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[CubeFaceIndex(target)][level]);
-}
-
-// Tests for cube map sampling completeness.
-bool TextureCubeMap::isSamplerComplete() const
-{
-	for(int face = 0; face < 6; face++)
-	{
-		if(!image[face][0])
-		{
-			return false;
-		}
-	}
-
-	int size = image[0][0]->getWidth();
-
-	if(size <= 0)
-	{
-		return false;
-	}
-
-	if(!isMipmapFiltered())
-	{
-		if(!isCubeComplete())
-		{
-			return false;
-		}
-	}
-	else
-	{
-		if(!isMipmapCubeComplete())   // Also tests for isCubeComplete()
-		{
-			return false;
-		}
-	}
-
-	return true;
-}
-
-// Tests for cube texture completeness.
-bool TextureCubeMap::isCubeComplete() const
-{
-	if(image[0][0]->getWidth() <= 0 || image[0][0]->getHeight() != image[0][0]->getWidth())
-	{
-		return false;
-	}
-
-	for(unsigned int face = 1; face < 6; face++)
-	{
-		if(image[face][0]->getWidth()  != image[0][0]->getWidth() ||
-		   image[face][0]->getWidth()  != image[0][0]->getHeight() ||
-		   image[face][0]->getFormat() != image[0][0]->getFormat() ||
-		   image[face][0]->getType()   != image[0][0]->getType())
-		{
-			return false;
-		}
-	}
-
-	return true;
-}
-
-bool TextureCubeMap::isMipmapCubeComplete() const
-{
-	if(!isCubeComplete())
-	{
-		return false;
-	}
-
-	GLsizei size = image[0][0]->getWidth();
-	int q = log2(size);
-
-	for(int face = 0; face < 6; face++)
-	{
-		for(int level = 1; level <= q; level++)
-		{
-			if(!image[face][level])
-			{
-				return false;
-			}
-
-			if(image[face][level]->getFormat() != image[0][0]->getFormat())
-			{
-				return false;
-			}
-
-			if(image[face][level]->getType() != image[0][0]->getType())
-			{
-				return false;
-			}
-
-			if(image[face][level]->getWidth() != std::max(1, size >> level))
-			{
-				return false;
-			}
-		}
-	}
-
-	return true;
-}
-
-bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
-{
-	return IsCompressed(getFormat(target, level));
-}
-
-bool TextureCubeMap::isDepth(GLenum target, GLint level) const
-{
-	return IsDepthTexture(getFormat(target, level));
-}
-
-void TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
-{
-	int face = CubeFaceIndex(target);
-
-	if(image[face][level])
-	{
-		image[face][level]->unbind();
-	}
-
-	image[face][level] = new Image(this, width, height, format, type);
-
-	if(!image[face][level])
-	{
-		return error(GL_OUT_OF_MEMORY);
-	}
-
-	Texture::setImage(format, type, unpackAlignment, pixels, image[face][level]);
-}
-
-void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
-	int face = CubeFaceIndex(target);
-
-	if(image[face][level])
-	{
-		image[face][level]->unbind();
-	}
-
-	image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);
-
-	if(!image[face][level])
-	{
-		return error(GL_OUT_OF_MEMORY);
-	}
-
-	if(width != 0 && height != 0)
-	{
-		Image *renderTarget = source->getRenderTarget();
-
-		if(!renderTarget)
-		{
-			ERR("Failed to retrieve the render target.");
-			return error(GL_OUT_OF_MEMORY);
-		}
-
-		sw::Rect sourceRect = {x, y, x + width, y + height};
-		sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
-
-		copy(renderTarget, sourceRect, format, 0, 0, image[face][level]);
-
-		renderTarget->release();
-	}
-}
-
-Image *TextureCubeMap::getImage(int face, unsigned int level)
-{
-	return image[face][level];
-}
-
-Image *TextureCubeMap::getImage(GLenum face, unsigned int level)
-{
-	return image[CubeFaceIndex(face)][level];
-}
-
-void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
-	int face = CubeFaceIndex(target);
-
-	if(!image[face][level])
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	GLsizei size = image[face][level]->getWidth();
-
-	if(xoffset + width > size || yoffset + height > size)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	Image *renderTarget = source->getRenderTarget();
-
-	if(!renderTarget)
-	{
-		ERR("Failed to retrieve the render target.");
-		return error(GL_OUT_OF_MEMORY);
-	}
-
-	sw::Rect sourceRect = {x, y, x + width, y + height};
-	sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
-
-	copy(renderTarget, sourceRect, image[face][level]->getFormat(), xoffset, yoffset, image[face][level]);
-
-	renderTarget->release();
-}
-
-void TextureCubeMap::generateMipmaps()
-{
-	if(!isCubeComplete())
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	unsigned int q = log2(image[0][0]->getWidth());
-
-	for(unsigned int f = 0; f < 6; f++)
-	{
-		for(unsigned int i = 1; i <= q; i++)
-		{
-			if(image[f][i])
-			{
-				image[f][i]->unbind();
-			}
-
-			image[f][i] = new Image(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType());
-
-			if(!image[f][i])
-			{
-				return error(GL_OUT_OF_MEMORY);
-			}
-
-			getDevice()->stretchRect(image[f][i - 1], 0, image[f][i], 0, true);
-		}
-	}
-}
-
-Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target)
-{
-	if(!IsCubemapTextureTarget(target))
-	{
-		return error(GL_INVALID_OPERATION, (Renderbuffer *)nullptr);
-	}
-
-	int face = CubeFaceIndex(target);
-
-	if(!mFaceProxies[face])
-	{
-		mFaceProxies[face] = new Renderbuffer(name, new RenderbufferTextureCubeMap(this, target));
-	}
-
-	return mFaceProxies[face];
-}
-
-Image *TextureCubeMap::getRenderTarget(GLenum target, unsigned int level)
-{
-	ASSERT(IsCubemapTextureTarget(target));
-	ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
-
-	int face = CubeFaceIndex(target);
-
-	if(image[face][level])
-	{
-		image[face][level]->addRef();
-	}
-
-	return image[face][level];
-}
-
-}
diff --git a/src/OpenGL/libGL/Texture.h b/src/OpenGL/libGL/Texture.h
deleted file mode 100644
index 483dc77..0000000
--- a/src/OpenGL/libGL/Texture.h
+++ /dev/null
@@ -1,223 +0,0 @@
-// 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.
-
-// Texture.h: Defines the abstract Texture class and its concrete derived
-// classes Texture2D and TextureCubeMap. Implements GL texture objects and
-// related functionality.
-
-#ifndef LIBGL_TEXTURE_H_
-#define LIBGL_TEXTURE_H_
-
-#include "Renderbuffer.h"
-#include "common/Object.hpp"
-#include "utilities.h"
-#include "common/debug.h"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-#include <vector>
-
-namespace gl
-{
-class Surface;
-class Config;
-class Framebuffer;
-
-enum
-{
-	IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS,
-	IMPLEMENTATION_MAX_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),
-	IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1),
-	IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION,
-};
-
-class Texture : public NamedObject
-{
-public:
-	explicit Texture(GLuint name);
-
-	virtual ~Texture();
-
-	sw::Resource *getResource() const;
-
-	virtual void addProxyRef(const Renderbuffer *proxy) = 0;
-	virtual void releaseProxy(const Renderbuffer *proxy) = 0;
-
-	virtual GLenum getTarget() const = 0;
-
-	bool setMinFilter(GLenum filter);
-	bool setMagFilter(GLenum filter);
-	bool setWrapS(GLenum wrap);
-	bool setWrapT(GLenum wrap);
-	bool setMaxAnisotropy(GLfloat textureMaxAnisotropy);
-	bool setMaxLevel(int level);
-
-	GLenum getMinFilter() const;
-	GLenum getMagFilter() const;
-	GLenum getWrapS() const;
-	GLenum getWrapT() const;
-	GLfloat getMaxAnisotropy() const;
-
-	virtual GLsizei getWidth(GLenum target, GLint level) const = 0;
-	virtual GLsizei getHeight(GLenum target, GLint level) const = 0;
-	virtual GLenum getFormat(GLenum target, GLint level) const = 0;
-	virtual GLenum getType(GLenum target, GLint level) const = 0;
-	virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0;
-	virtual int getTopLevel() const = 0;
-
-	virtual bool isSamplerComplete() const = 0;
-	virtual bool isCompressed(GLenum target, GLint level) const = 0;
-	virtual bool isDepth(GLenum target, GLint level) const = 0;
-
-	virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;
-	virtual Image *getRenderTarget(GLenum target, unsigned int level) = 0;
-
-	virtual void generateMipmaps() = 0;
-	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
-
-protected:
-	void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);
-	void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);
-	void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
-	void subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);
-
-	bool copy(Image *source, const sw::Rect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, Image *dest);
-
-	bool isMipmapFiltered() const;
-
-	GLenum mMinFilter;
-	GLenum mMagFilter;
-	GLenum mWrapS;
-	GLenum mWrapT;
-	GLfloat mMaxAnisotropy;
-	GLint mMaxLevel;
-
-	sw::Resource *resource;
-};
-
-class Texture2D : public Texture
-{
-public:
-	explicit Texture2D(GLuint name);
-
-	virtual ~Texture2D();
-
-	void addProxyRef(const Renderbuffer *proxy);
-	void releaseProxy(const Renderbuffer *proxy);
-
-	virtual GLenum getTarget() const;
-
-	virtual GLsizei getWidth(GLenum target, GLint level) const;
-	virtual GLsizei getHeight(GLenum target, GLint level) const;
-	virtual GLenum getFormat(GLenum target, GLint level) const;
-	virtual GLenum getType(GLenum target, GLint level) const;
-	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
-	virtual int getTopLevel() const;
-
-	void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
-	void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
-	void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
-	void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
-	void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
-	void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
-
-	void setImage(Image *image);
-
-	virtual bool isSamplerComplete() const;
-	virtual bool isCompressed(GLenum target, GLint level) const;
-	virtual bool isDepth(GLenum target, GLint level) const;
-
-	virtual void generateMipmaps();
-
-	virtual Renderbuffer *getRenderbuffer(GLenum target);
-	virtual Image *getRenderTarget(GLenum target, unsigned int level);
-
-	Image *getImage(unsigned int level);
-
-protected:
-	bool isMipmapComplete() const;
-
-	Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
-	// A specific internal reference count is kept for colorbuffer proxy references,
-	// because, as the renderbuffer acting as proxy will maintain a binding pointer
-	// back to this texture, there would be a circular reference if we used a binding
-	// pointer here. This reference count will cause the pointer to be set to null if
-	// the count drops to zero, but will not cause deletion of the Renderbuffer.
-	Renderbuffer *mColorbufferProxy;
-	unsigned int mProxyRefs;
-};
-
-class TextureCubeMap : public Texture
-{
-public:
-	explicit TextureCubeMap(GLuint name);
-
-	virtual ~TextureCubeMap();
-
-	void addProxyRef(const Renderbuffer *proxy);
-	void releaseProxy(const Renderbuffer *proxy);
-
-	virtual GLenum getTarget() const;
-
-	virtual GLsizei getWidth(GLenum target, GLint level) const;
-	virtual GLsizei getHeight(GLenum target, GLint level) const;
-	virtual GLenum getFormat(GLenum target, GLint level) const;
-	virtual GLenum getType(GLenum target, GLint level) const;
-	virtual sw::Format getInternalFormat(GLenum target, GLint level) const;
-	virtual int getTopLevel() const;
-
-	void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
-	void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
-
-	void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
-	void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
-	void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
-	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
-
-	virtual bool isSamplerComplete() const;
-	virtual bool isCompressed(GLenum target, GLint level) const;
-	virtual bool isDepth(GLenum target, GLint level) const;
-
-	virtual void generateMipmaps();
-
-	virtual Renderbuffer *getRenderbuffer(GLenum target);
-	virtual Image *getRenderTarget(GLenum target, unsigned int level);
-
-	Image *getImage(int face, unsigned int level);
-
-private:
-	bool isCubeComplete() const;
-	bool isMipmapCubeComplete() const;
-
-	// face is one of the GL_TEXTURE_CUBE_MAP_* enumerants. Returns nullptr on failure.
-	Image *getImage(GLenum face, unsigned int level);
-
-	Image *image[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
-	// A specific internal reference count is kept for colorbuffer proxy references,
-	// because, as the renderbuffer acting as proxy will maintain a binding pointer
-	// back to this texture, there would be a circular reference if we used a binding
-	// pointer here. This reference count will cause the pointer to be set to null if
-	// the count drops to zero, but will not cause deletion of the Renderbuffer.
-	Renderbuffer *mFaceProxies[6];
-	unsigned int mFaceProxyRefs[6];
-};
-
-}
-
-#endif   // LIBGL_TEXTURE_H_
diff --git a/src/OpenGL/libGL/VertexDataManager.cpp b/src/OpenGL/libGL/VertexDataManager.cpp
deleted file mode 100644
index 1520ed0..0000000
--- a/src/OpenGL/libGL/VertexDataManager.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-// 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.
-
-// VertexDataManager.h: Defines the VertexDataManager, a class that
-// runs the Buffer translation process.
-
-#include "VertexDataManager.h"
-
-#include "Buffer.h"
-#include "Program.h"
-#include "IndexDataManager.h"
-#include "common/debug.h"
-
-namespace
-{
-	enum {INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024};
-}
-
-namespace gl
-{
-
-VertexDataManager::VertexDataManager(Context *context) : mContext(context)
-{
-	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-	{
-		mDirtyCurrentValue[i] = true;
-		mCurrentValueBuffer[i] = nullptr;
-	}
-
-	mStreamingBuffer = new StreamingVertexBuffer(INITIAL_STREAM_BUFFER_SIZE);
-
-	if(!mStreamingBuffer)
-	{
-		ERR("Failed to allocate the streaming vertex buffer.");
-	}
-}
-
-VertexDataManager::~VertexDataManager()
-{
-	delete mStreamingBuffer;
-
-	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-	{
-		delete mCurrentValueBuffer[i];
-	}
-}
-
-unsigned int VertexDataManager::writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
-{
-	Buffer *buffer = attribute.mBoundBuffer;
-
-	int inputStride = attribute.stride();
-	int elementSize = attribute.typeSize();
-	unsigned int streamOffset = 0;
-
-	char *output = nullptr;
-
-	if(vertexBuffer)
-	{
-		output = (char*)vertexBuffer->map(attribute, attribute.typeSize() * count, &streamOffset);
-	}
-
-	if(!output)
-	{
-		ERR("Failed to map vertex buffer.");
-		return ~0u;
-	}
-
-	const char *input = nullptr;
-
-	if(buffer)
-	{
-		int offset = attribute.mOffset;
-
-		input = static_cast<const char*>(buffer->data()) + offset;
-	}
-	else
-	{
-		input = static_cast<const char*>(attribute.mPointer);
-	}
-
-	input += inputStride * start;
-
-	if(inputStride == elementSize)
-	{
-		memcpy(output, input, count * inputStride);
-	}
-	else
-	{
-		for(int i = 0; i < count; i++)
-		{
-			memcpy(output, input, elementSize);
-			output += elementSize;
-			input += inputStride;
-		}
-	}
-
-	vertexBuffer->unmap();
-
-	return streamOffset;
-}
-
-GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)
-{
-	if(!mStreamingBuffer)
-	{
-		return GL_OUT_OF_MEMORY;
-	}
-
-	const VertexAttributeArray &attribs = mContext->getVertexAttributes();
-	Program *program = mContext->getCurrentProgram();
-
-	// Determine the required storage size per used buffer
-	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-	{
-		if(!program || program->getAttributeStream(i) != -1)
-		{
-			if(attribs[i].mArrayEnabled)
-			{
-				if(!attribs[i].mBoundBuffer)
-				{
-					mStreamingBuffer->addRequiredSpace(attribs[i].typeSize() * count);
-				}
-			}
-		}
-	}
-
-	mStreamingBuffer->reserveRequiredSpace();
-
-	// Perform the vertex data translations
-	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
-	{
-		if(!program || program->getAttributeStream(i) != -1)
-		{
-			if(attribs[i].mArrayEnabled)
-			{
-				Buffer *buffer = attribs[i].mBoundBuffer;
-
-				if(!buffer && attribs[i].mPointer == nullptr)
-				{
-					// This is an application error that would normally result in a crash, but we catch it and return an error
-					ERR("An enabled vertex array has no buffer and no pointer.");
-					return GL_INVALID_OPERATION;
-				}
-
-				sw::Resource *staticBuffer = buffer ? buffer->getResource() : nullptr;
-
-				if(staticBuffer)
-				{
-					translated[i].vertexBuffer = staticBuffer;
-					translated[i].offset = start * attribs[i].stride() + attribs[i].mOffset;
-					translated[i].stride = attribs[i].stride();
-				}
-				else
-				{
-					unsigned int streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i]);
-
-					if(streamOffset == ~0u)
-					{
-						return GL_OUT_OF_MEMORY;
-					}
-
-					translated[i].vertexBuffer = mStreamingBuffer->getResource();
-					translated[i].offset = streamOffset;
-					translated[i].stride = attribs[i].typeSize();
-				}
-
-				switch(attribs[i].mType)
-				{
-				case GL_BYTE:           translated[i].type = sw::STREAMTYPE_SBYTE;  break;
-				case GL_UNSIGNED_BYTE:  translated[i].type = sw::STREAMTYPE_BYTE;   break;
-				case GL_SHORT:          translated[i].type = sw::STREAMTYPE_SHORT;  break;
-				case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break;
-				case GL_INT:            translated[i].type = sw::STREAMTYPE_INT;    break;
-				case GL_UNSIGNED_INT:   translated[i].type = sw::STREAMTYPE_UINT;   break;
-				case GL_FIXED:          translated[i].type = sw::STREAMTYPE_FIXED;  break;
-				case GL_FLOAT:          translated[i].type = sw::STREAMTYPE_FLOAT;  break;
-				default: UNREACHABLE(attribs[i].mType); translated[i].type = sw::STREAMTYPE_FLOAT;  break;
-				}
-
-				translated[i].count = attribs[i].mSize;
-				translated[i].normalized = attribs[i].mNormalized;
-			}
-			else
-			{
-				if(mDirtyCurrentValue[i])
-				{
-					delete mCurrentValueBuffer[i];
-					mCurrentValueBuffer[i] = new ConstantVertexBuffer(attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);
-					mDirtyCurrentValue[i] = false;
-				}
-
-				translated[i].vertexBuffer = mCurrentValueBuffer[i]->getResource();
-
-				translated[i].type = sw::STREAMTYPE_FLOAT;
-				translated[i].count = 4;
-				translated[i].stride = 0;
-				translated[i].offset = 0;
-			}
-		}
-	}
-
-	return GL_NO_ERROR;
-}
-
-VertexBuffer::VertexBuffer(unsigned int size) : mVertexBuffer(nullptr)
-{
-	if(size > 0)
-	{
-		mVertexBuffer = new sw::Resource(size + 1024);
-
-		if(!mVertexBuffer)
-		{
-			ERR("Out of memory allocating a vertex buffer of size %u.", size);
-		}
-	}
-}
-
-VertexBuffer::~VertexBuffer()
-{
-	if(mVertexBuffer)
-	{
-		mVertexBuffer->destruct();
-	}
-}
-
-void VertexBuffer::unmap()
-{
-	if(mVertexBuffer)
-	{
-		mVertexBuffer->unlock();
-	}
-}
-
-sw::Resource *VertexBuffer::getResource() const
-{
-	return mVertexBuffer;
-}
-
-ConstantVertexBuffer::ConstantVertexBuffer(float x, float y, float z, float w) : VertexBuffer(4 * sizeof(float))
-{
-	if(mVertexBuffer)
-	{
-		float *vector = (float*)mVertexBuffer->lock(sw::PUBLIC);
-
-		vector[0] = x;
-		vector[1] = y;
-		vector[2] = z;
-		vector[3] = w;
-
-		mVertexBuffer->unlock();
-	}
-}
-
-ConstantVertexBuffer::~ConstantVertexBuffer()
-{
-}
-
-StreamingVertexBuffer::StreamingVertexBuffer(unsigned int size) : VertexBuffer(size)
-{
-	mBufferSize = size;
-	mWritePosition = 0;
-	mRequiredSpace = 0;
-}
-
-StreamingVertexBuffer::~StreamingVertexBuffer()
-{
-}
-
-void StreamingVertexBuffer::addRequiredSpace(unsigned int requiredSpace)
-{
-	mRequiredSpace += requiredSpace;
-}
-
-void *StreamingVertexBuffer::map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *offset)
-{
-	void *mapPtr = nullptr;
-
-	if(mVertexBuffer)
-	{
-		// We can use a private lock because we never overwrite the content
-		mapPtr = (char*)mVertexBuffer->lock(sw::PRIVATE) + mWritePosition;
-
-		*offset = mWritePosition;
-		mWritePosition += requiredSpace;
-	}
-
-	return mapPtr;
-}
-
-void StreamingVertexBuffer::reserveRequiredSpace()
-{
-	if(mRequiredSpace > mBufferSize)
-	{
-		if(mVertexBuffer)
-		{
-			mVertexBuffer->destruct();
-			mVertexBuffer = 0;
-		}
-
-		mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2);   // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.
-
-		mVertexBuffer = new sw::Resource(mBufferSize);
-
-		if(!mVertexBuffer)
-		{
-			ERR("Out of memory allocating a vertex buffer of size %u.", mBufferSize);
-		}
-
-		mWritePosition = 0;
-	}
-	else if(mWritePosition + mRequiredSpace > mBufferSize)   // Recycle
-	{
-		if(mVertexBuffer)
-		{
-			mVertexBuffer->destruct();
-			mVertexBuffer = new sw::Resource(mBufferSize);
-		}
-
-		mWritePosition = 0;
-	}
-
-	mRequiredSpace = 0;
-}
-
-}
diff --git a/src/OpenGL/libGL/VertexDataManager.h b/src/OpenGL/libGL/VertexDataManager.h
deleted file mode 100644
index 7f0a432..0000000
--- a/src/OpenGL/libGL/VertexDataManager.h
+++ /dev/null
@@ -1,104 +0,0 @@
-// 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.
-
-// VertexDataManager.h: Defines the VertexDataManager, a class that
-// runs the Buffer translation process.
-
-#ifndef LIBGL_VERTEXDATAMANAGER_H_
-#define LIBGL_VERTEXDATAMANAGER_H_
-
-#include "Context.h"
-#include "Device.hpp"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-namespace gl
-{
-
-struct TranslatedAttribute
-{
-	sw::StreamType type;
-	int count;
-	bool normalized;
-
-	unsigned int offset;
-	unsigned int stride;   // 0 means not to advance the read pointer at all
-
-	sw::Resource *vertexBuffer;
-};
-
-class VertexBuffer
-{
-public:
-	VertexBuffer(unsigned int size);
-	virtual ~VertexBuffer();
-
-	void unmap();
-
-	sw::Resource *getResource() const;
-
-protected:
-	sw::Resource *mVertexBuffer;
-};
-
-class ConstantVertexBuffer : public VertexBuffer
-{
-public:
-	ConstantVertexBuffer(float x, float y, float z, float w);
-	~ConstantVertexBuffer();
-};
-
-class StreamingVertexBuffer : public VertexBuffer
-{
-public:
-	StreamingVertexBuffer(unsigned int size);
-	~StreamingVertexBuffer();
-
-	void *map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *streamOffset);
-	void reserveRequiredSpace();
-	void addRequiredSpace(unsigned int requiredSpace);
-
-protected:
-	unsigned int mBufferSize;
-	unsigned int mWritePosition;
-	unsigned int mRequiredSpace;
-};
-
-class VertexDataManager
-{
-public:
-	VertexDataManager(Context *context);
-	virtual ~VertexDataManager();
-
-	void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
-
-	GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
-
-private:
-	unsigned int writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
-
-	Context *const mContext;
-
-	StreamingVertexBuffer *mStreamingBuffer;
-
-	bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
-	ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
-};
-
-}
-
-#endif   // LIBGL_VERTEXDATAMANAGER_H_
diff --git a/src/OpenGL/libGL/libGL.cpp b/src/OpenGL/libGL/libGL.cpp
deleted file mode 100644
index 87829be..0000000
--- a/src/OpenGL/libGL/libGL.cpp
+++ /dev/null
@@ -1,8263 +0,0 @@
-// 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.
-// libGL.cpp: Implements the exported OpenGL functions.
-
-#include "main.h"
-#include "mathutil.h"
-#include "utilities.h"
-#include "Buffer.h"
-#include "Context.h"
-#include "Fence.h"
-#include "Framebuffer.h"
-#include "Program.h"
-#include "Renderbuffer.h"
-#include "Shader.h"
-#include "Texture.h"
-#include "Query.h"
-#include "common/debug.h"
-#include "Common/Version.h"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-#include <limits>
-
-using std::abs;
-
-static bool validImageSize(GLint level, GLsizei width, GLsizei height)
-{
-	if(level < 0 || level >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
-	{
-		return false;
-	}
-
-	return true;
-}
-
-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, gl::Texture *texture)
-{
-	if(!texture)
-	{
-		return error(GL_INVALID_OPERATION, false);
-	}
-
-	if(compressed != texture->isCompressed(target, level))
-	{
-		return error(GL_INVALID_OPERATION, false);
-	}
-
-	if(format != GL_NONE && format != texture->getFormat(target, level))
-	{
-		return error(GL_INVALID_OPERATION, false);
-	}
-
-	if(compressed)
-	{
-		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
-		   (height % 4 != 0 && height != texture->getHeight(target, 0)))
-		{
-			return error(GL_INVALID_OPERATION, false);
-		}
-	}
-
-	if(xoffset + width > texture->getWidth(target, level) ||
-	   yoffset + height > texture->getHeight(target, level))
-	{
-		return error(GL_INVALID_VALUE, false);
-	}
-
-	return true;
-}
-
-// Check for combinations of format and type that are valid for ReadPixels
-static bool validReadFormatType(GLenum format, GLenum type)
-{
-	switch(format)
-	{
-	case GL_RGBA:
-		switch(type)
-		{
-		case GL_UNSIGNED_BYTE:
-			break;
-		default:
-			return false;
-		}
-		break;
-	case GL_BGRA_EXT:
-		switch(type)
-		{
-		case GL_UNSIGNED_BYTE:
-		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
-		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
-			break;
-		default:
-			return false;
-		}
-		break;
-	case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
-		switch(type)
-		{
-		case gl::IMPLEMENTATION_COLOR_READ_TYPE:
-			break;
-		default:
-			return false;
-		}
-		break;
-	default:
-		return false;
-	}
-
-	return true;
-}
-
-extern "C"
-{
-
-void APIENTRY glActiveTexture(GLenum texture)
-{
-	TRACE("(GLenum texture = 0x%X)", texture);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
-		{
-			return error(GL_INVALID_ENUM);
-		}
-
-		context->setActiveSampler(texture - GL_TEXTURE0);
-	}
-}
-
-void APIENTRY glAttachShader(GLuint program, GLuint shader)
-{
-	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Program *programObject = context->getProgram(program);
-		gl::Shader *shaderObject = context->getShader(shader);
-
-		if(!programObject)
-		{
-			if(context->getShader(program))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		if(!shaderObject)
-		{
-			if(context->getProgram(shader))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		if(!programObject->attachShader(shaderObject))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glBeginQueryEXT(GLenum target, GLuint name)
-{
-	TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);
-
-	switch(target)
-	{
-	case GL_ANY_SAMPLES_PASSED:
-	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	if(name == 0)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->beginQuery(target, name);
-	}
-}
-
-void APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
-{
-	TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);
-
-	if(index >= gl::MAX_VERTEX_ATTRIBS)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject)
-		{
-			if(context->getShader(program))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		if(strncmp(name, "gl_", 3) == 0)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		programObject->bindAttributeLocation(index, name);
-	}
-}
-
-void APIENTRY glBindBuffer(GLenum target, GLuint buffer)
-{
-	TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
-
-	gl::Context *context = gl::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 APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
-{
-	TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
-
-	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
-	{
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(target == GL_READ_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
-		{
-			context->bindReadFramebuffer(framebuffer);
-		}
-
-		if(target == GL_DRAW_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
-		{
-			context->bindDrawFramebuffer(framebuffer);
-		}
-	}
-}
-
-void APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
-{
-	TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
-
-	if(target != GL_RENDERBUFFER)
-	{
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->bindRenderbuffer(renderbuffer);
-	}
-}
-
-void APIENTRY glBindTexture(GLenum target, GLuint texture)
-{
-	TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Texture *textureObject = context->getTexture(texture);
-
-		if(textureObject && textureObject->getTarget() != target && texture != 0)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		switch(target)
-		{
-		case GL_TEXTURE_2D:
-			context->bindTexture2D(texture);
-			return;
-		case GL_TEXTURE_CUBE_MAP:
-			context->bindTextureCubeMap(texture);
-			return;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glBlendColor(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);
-
-	gl::Context* context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
-	}
-}
-
-void APIENTRY glBlendEquation(GLenum mode)
-{
-	glBlendEquationSeparate(mode, mode);
-}
-
-void APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
-{
-	TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
-
-	switch(modeRGB)
-	{
-	case GL_FUNC_ADD:
-	case GL_FUNC_SUBTRACT:
-	case GL_FUNC_REVERSE_SUBTRACT:
-	case GL_MIN_EXT:
-	case GL_MAX_EXT:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	switch(modeAlpha)
-	{
-	case GL_FUNC_ADD:
-	case GL_FUNC_SUBTRACT:
-	case GL_FUNC_REVERSE_SUBTRACT:
-	case GL_MIN_EXT:
-	case GL_MAX_EXT:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setBlendEquation(modeRGB, modeAlpha);
-	}
-}
-
-void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
-{
-	glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
-}
-
-void APIENTRY glBlendFuncSeparate(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_CONSTANT_COLOR:
-	case GL_ONE_MINUS_CONSTANT_COLOR:
-	case GL_CONSTANT_ALPHA:
-	case GL_ONE_MINUS_CONSTANT_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:
-	case GL_CONSTANT_COLOR:
-	case GL_ONE_MINUS_CONSTANT_COLOR:
-	case GL_CONSTANT_ALPHA:
-	case GL_ONE_MINUS_CONSTANT_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_CONSTANT_COLOR:
-	case GL_ONE_MINUS_CONSTANT_COLOR:
-	case GL_CONSTANT_ALPHA:
-	case GL_ONE_MINUS_CONSTANT_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:
-	case GL_CONSTANT_COLOR:
-	case GL_ONE_MINUS_CONSTANT_COLOR:
-	case GL_CONSTANT_ALPHA:
-	case GL_ONE_MINUS_CONSTANT_ALPHA:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
-	}
-}
-
-void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
-{
-	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_STREAM_DRAW:
-	case GL_STATIC_DRAW:
-	case GL_DYNAMIC_DRAW:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::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 APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
-{
-	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;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::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 APIENTRY glCheckFramebufferStatus(GLenum target)
-{
-	TRACE("(GLenum target = 0x%X)", target);
-
-	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
-	{
-		return error(GL_INVALID_ENUM, 0);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Framebuffer *framebuffer = nullptr;
-		if(target == GL_READ_FRAMEBUFFER_EXT)
-		{
-			framebuffer = context->getReadFramebuffer();
-		}
-		else
-		{
-			framebuffer = context->getDrawFramebuffer();
-		}
-
-		return framebuffer->completeness();
-	}
-
-	return 0;
-}
-
-void APIENTRY glClear(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);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			return context->listCommand(gl::newCommand(glClear, mask));
-		}
-
-		context->clear(mask);
-	}
-}
-
-void APIENTRY glClearColor(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);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setClearColor(red, green, blue, alpha);
-	}
-}
-
-void APIENTRY glClearDepthf(GLclampf depth)
-{
-	TRACE("(GLclampf depth = %f)", depth);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setClearDepth(depth);
-	}
-}
-
-void APIENTRY glClearStencil(GLint s)
-{
-	TRACE("(GLint s = %d)", s);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setClearStencil(s);
-	}
-}
-
-void APIENTRY glColorMask(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);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
-	}
-}
-
-void APIENTRY glCompileShader(GLuint shader)
-{
-	TRACE("(GLuint shader = %d)", shader);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Shader *shaderObject = context->getShader(shader);
-
-		if(!shaderObject)
-		{
-			if(context->getProgram(shader))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		shaderObject->compile();
-	}
-}
-
-void APIENTRY glCompressedTexImage2D(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(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	switch(internalformat)
-	{
-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-		break;
-	case GL_DEPTH_COMPONENT:
-	case GL_DEPTH_COMPONENT16:
-	case GL_DEPTH_COMPONENT32:
-	case GL_DEPTH_STENCIL_EXT:
-	case GL_DEPTH24_STENCIL8_EXT:
-		return error(GL_INVALID_OPERATION);
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	if(border != 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		switch(target)
-		{
-		case GL_TEXTURE_2D:
-			if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
-			   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
-			{
-				return error(GL_INVALID_VALUE);
-			}
-			break;
-		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-			if(width != height)
-			{
-				return error(GL_INVALID_VALUE);
-			}
-
-			if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
-			   height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_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)
-		{
-			gl::Texture2D *texture = context->getTexture2D(target);
-
-			if(!texture)
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-
-			texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
-		}
-		else
-		{
-			gl::TextureCubeMap *texture = context->getTextureCubeMap();
-
-			if(!texture)
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-
-			switch(target)
-			{
-			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-				texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
-				break;
-			default: UNREACHABLE(target);
-			}
-		}
-	}
-}
-
-void APIENTRY glCompressedTexSubImage2D(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(!gl::IsTextureTarget(target))
-	{
-		return error(GL_INVALID_ENUM);
-	}
-
-	if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	switch(format)
-	{
-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	if(width == 0 || height == 0 || !data)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		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)
-		{
-			gl::Texture2D *texture = context->getTexture2D(target);
-
-			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
-			{
-				texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
-			}
-		}
-		else if(gl::IsCubemapTextureTarget(target))
-		{
-			gl::TextureCubeMap *texture = context->getTextureCubeMap();
-
-			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
-			{
-				texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
-			}
-		}
-		else UNREACHABLE(target);
-	}
-}
-
-void APIENTRY glCopyTexImage2D(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);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		switch(target)
-		{
-		case GL_TEXTURE_2D:
-			if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
-			   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
-			{
-				return error(GL_INVALID_VALUE);
-			}
-			break;
-		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-			if(width != height)
-			{
-				return error(GL_INVALID_VALUE);
-			}
-
-			if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
-			   height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
-			{
-				return error(GL_INVALID_VALUE);
-			}
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-
-		gl::Framebuffer *framebuffer = context->getReadFramebuffer();
-
-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
-		{
-			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
-		}
-
-		if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		gl::Renderbuffer *source = framebuffer->getColorbuffer();
-		GLenum colorbufferFormat = source->getFormat();
-
-		switch(internalformat)
-		{
-		case GL_ALPHA:
-			if(colorbufferFormat != GL_ALPHA &&
-			   colorbufferFormat != GL_RGBA &&
-			   colorbufferFormat != GL_RGBA4 &&
-			   colorbufferFormat != GL_RGB5_A1 &&
-			   colorbufferFormat != GL_RGBA8_EXT)
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			break;
-		case GL_LUMINANCE:
-		case GL_RGB:
-			if(colorbufferFormat != GL_RGB &&
-			   colorbufferFormat != GL_RGB565 &&
-			   colorbufferFormat != GL_RGB8_EXT &&
-			   colorbufferFormat != GL_RGBA &&
-			   colorbufferFormat != GL_RGBA4 &&
-			   colorbufferFormat != GL_RGB5_A1 &&
-			   colorbufferFormat != GL_RGBA8_EXT)
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			break;
-		case GL_LUMINANCE_ALPHA:
-		case GL_RGBA:
-			if(colorbufferFormat != GL_RGBA &&
-			   colorbufferFormat != GL_RGBA4 &&
-			   colorbufferFormat != GL_RGB5_A1 &&
-			   colorbufferFormat != GL_RGBA8_EXT)
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			break;
-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-			return error(GL_INVALID_OPERATION);
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-
-		if(target == GL_TEXTURE_2D)
-		{
-			gl::Texture2D *texture = context->getTexture2D(target);
-
-			if(!texture)
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-
-			texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
-		}
-		else if(gl::IsCubemapTextureTarget(target))
-		{
-			gl::TextureCubeMap *texture = context->getTextureCubeMap();
-
-			if(!texture)
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-
-			texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
-		}
-		else UNREACHABLE(target);
-	}
-}
-
-void APIENTRY glCopyTexSubImage2D(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(!gl::IsTextureTarget(target))
-	{
-		return error(GL_INVALID_ENUM);
-	}
-
-	if(level < 0 || 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;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		gl::Framebuffer *framebuffer = context->getReadFramebuffer();
-
-		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
-		{
-			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
-		}
-
-		if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		gl::Texture *texture = nullptr;
-
-		if(target == GL_TEXTURE_2D)
-		{
-			texture = context->getTexture2D(target);
-		}
-		else if(gl::IsCubemapTextureTarget(target))
-		{
-			texture = context->getTextureCubeMap();
-		}
-		else UNREACHABLE(target);
-
-		if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))
-		{
-			return;
-		}
-
-		texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
-	}
-}
-
-GLuint APIENTRY glCreateProgram(void)
-{
-	TRACE("()");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		return context->createProgram();
-	}
-
-	return 0;
-}
-
-GLuint APIENTRY glCreateShader(GLenum type)
-{
-	TRACE("(GLenum type = 0x%X)", type);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		switch(type)
-		{
-		case GL_FRAGMENT_SHADER:
-		case GL_VERTEX_SHADER:
-			return context->createShader(type);
-		default:
-			return error(GL_INVALID_ENUM, 0);
-		}
-	}
-
-	return 0;
-}
-
-void APIENTRY glCullFace(GLenum mode)
-{
-	TRACE("(GLenum mode = 0x%X)", mode);
-
-	switch(mode)
-	{
-	case GL_FRONT:
-	case GL_BACK:
-	case GL_FRONT_AND_BACK:
-		{
-			gl::Context *context = gl::getContext();
-
-			if(context)
-			{
-				context->setCullMode(mode);
-			}
-		}
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-}
-
-void APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
-{
-	TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
-
-	if(n < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		for(int i = 0; i < n; i++)
-		{
-			context->deleteBuffer(buffers[i]);
-		}
-	}
-}
-
-void APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
-{
-	TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);
-
-	if(n < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		for(int i = 0; i < n; i++)
-		{
-			context->deleteFence(fences[i]);
-		}
-	}
-}
-
-void APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
-{
-	TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
-
-	if(n < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		for(int i = 0; i < n; i++)
-		{
-			if(framebuffers[i] != 0)
-			{
-				context->deleteFramebuffer(framebuffers[i]);
-			}
-		}
-	}
-}
-
-void APIENTRY glDeleteProgram(GLuint program)
-{
-	TRACE("(GLuint program = %d)", program);
-
-	if(program == 0)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(!context->getProgram(program))
-		{
-			if(context->getShader(program))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		context->deleteProgram(program);
-	}
-}
-
-void APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
-{
-	TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);
-
-	if(n < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		for(int i = 0; i < n; i++)
-		{
-			context->deleteQuery(ids[i]);
-		}
-	}
-}
-
-void APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
-{
-	TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
-
-	if(n < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		for(int i = 0; i < n; i++)
-		{
-			context->deleteRenderbuffer(renderbuffers[i]);
-		}
-	}
-}
-
-void APIENTRY glDeleteShader(GLuint shader)
-{
-	TRACE("(GLuint shader = %d)", shader);
-
-	if(shader == 0)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(!context->getShader(shader))
-		{
-			if(context->getProgram(shader))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		context->deleteShader(shader);
-	}
-}
-
-void APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
-{
-	TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
-
-	if(n < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		for(int i = 0; i < n; i++)
-		{
-			if(textures[i] != 0)
-			{
-				context->deleteTexture(textures[i]);
-			}
-		}
-	}
-}
-
-void APIENTRY glDepthFunc(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);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setDepthFunc(func);
-	}
-}
-
-void APIENTRY glDepthMask(GLboolean flag)
-{
-	TRACE("(GLboolean flag = %d)", flag);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setDepthMask(flag != GL_FALSE);
-	}
-}
-
-void APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
-{
-	TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setDepthRange(zNear, zFar);
-	}
-}
-
-void APIENTRY glDetachShader(GLuint program, GLuint shader)
-{
-	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Program *programObject = context->getProgram(program);
-		gl::Shader *shaderObject = context->getShader(shader);
-
-		if(!programObject)
-		{
-			gl::Shader *shaderByProgramHandle;
-			shaderByProgramHandle = context->getShader(program);
-			if(!shaderByProgramHandle)
-			{
-				return error(GL_INVALID_VALUE);
-			}
-			else
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-		}
-
-		if(!shaderObject)
-		{
-			gl::Program *programByShaderHandle = context->getProgram(shader);
-			if(!programByShaderHandle)
-			{
-				return error(GL_INVALID_VALUE);
-			}
-			else
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-		}
-
-		if(!programObject->detachShader(shaderObject))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glDisable(GLenum cap)
-{
-	TRACE("(GLenum cap = 0x%X)", cap);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		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_FOG:                      context->setFogEnabled(false);                   break;
-		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(false);             break;
-		case GL_TEXTURE_2D:               context->setTexture2DEnabled(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_COLOR_MATERIAL:           context->setColorMaterialEnabled(false);         break;
-		case GL_RESCALE_NORMAL:           context->setNormalizeNormalsEnabled(false);      break;
-		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(false);          break;
-		case GL_INDEX_LOGIC_OP:           UNIMPLEMENTED();
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glDisableVertexAttribArray(GLuint index)
-{
-	TRACE("(GLuint index = %d)", index);
-
-	if(index >= gl::MAX_VERTEX_ATTRIBS)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		context->setVertexAttribArrayEnabled(index, false);
-	}
-}
-
-void APIENTRY glCaptureAttribs()
-{
-	TRACE("()");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		context->captureAttribs();
-	}
-}
-
-void APIENTRY glRestoreAttribs()
-{
-	TRACE("()");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		context->restoreAttribs();
-	}
-}
-
-void APIENTRY glDrawArrays(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);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			ASSERT(context->getListMode() != GL_COMPILE_AND_EXECUTE);   // UNIMPLEMENTED!
-
-			context->listCommand(gl::newCommand(glCaptureAttribs));
-			context->captureDrawArrays(mode, first, count);
-			context->listCommand(gl::newCommand(glDrawArrays, mode, first, count));
-			context->listCommand(gl::newCommand(glRestoreAttribs));
-
-			return;
-		}
-
-		context->drawArrays(mode, first, count);
-	}
-}
-
-void APIENTRY glDrawElements(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);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		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 APIENTRY glEnable(GLenum cap)
-{
-	TRACE("(GLenum cap = 0x%X)", cap);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		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_TEXTURE_2D:               context->setTexture2DEnabled(true);             break;
-		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(true);             break;
-		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(true);         break;
-		case GL_FOG:                      context->setFogEnabled(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_RESCALE_NORMAL:           context->setNormalizeNormalsEnabled(true);      break;
-		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(true);          break;
-		case GL_INDEX_LOGIC_OP:           UNIMPLEMENTED();
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glEnableVertexAttribArray(GLuint index)
-{
-	TRACE("(GLuint index = %d)", index);
-
-	if(index >= gl::MAX_VERTEX_ATTRIBS)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		context->setVertexAttribArrayEnabled(index, true);
-	}
-}
-
-void APIENTRY glEndQueryEXT(GLenum target)
-{
-	TRACE("GLenum target = 0x%X)", target);
-
-	switch(target)
-	{
-	case GL_ANY_SAMPLES_PASSED:
-	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->endQuery(target);
-	}
-}
-
-void APIENTRY glFinishFenceNV(GLuint fence)
-{
-	TRACE("(GLuint fence = %d)", fence);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Fence* fenceObject = context->getFence(fence);
-
-		if(!fenceObject)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		fenceObject->finishFence();
-	}
-}
-
-void APIENTRY glFinish(void)
-{
-	TRACE("()");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		context->finish();
-	}
-}
-
-void APIENTRY glFlush(void)
-{
-	TRACE("()");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		context->flush();
-	}
-}
-
-void APIENTRY glFramebufferRenderbuffer(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 && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT) ||
-	   (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
-	{
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Framebuffer *framebuffer = nullptr;
-		GLuint framebufferName = 0;
-		if(target == GL_READ_FRAMEBUFFER_EXT)
-		{
-			framebuffer = context->getReadFramebuffer();
-			framebufferName = context->getReadFramebufferName();
-		}
-		else
-		{
-			framebuffer = context->getDrawFramebuffer();
-			framebufferName = context->getDrawFramebufferName();
-		}
-
-		if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		switch(attachment)
-		{
-		case GL_COLOR_ATTACHMENT0:
-			framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
-			break;
-		case GL_DEPTH_ATTACHMENT:
-			framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
-			break;
-		case GL_STENCIL_ATTACHMENT:
-			framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glFramebufferTexture2D(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 && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
-	{
-		return error(GL_INVALID_ENUM);
-	}
-
-	switch(attachment)
-	{
-	case GL_COLOR_ATTACHMENT0:
-	case GL_DEPTH_ATTACHMENT:
-	case GL_STENCIL_ATTACHMENT:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(texture == 0)
-		{
-			textarget = GL_NONE;
-		}
-		else
-		{
-			gl::Texture *tex = context->getTexture(texture);
-
-			if(!tex)
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-
-			if(tex->isCompressed(textarget, level))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-
-			switch(textarget)
-			{
-			case GL_TEXTURE_2D:
-				if(tex->getTarget() != GL_TEXTURE_2D)
-				{
-					return error(GL_INVALID_OPERATION);
-				}
-				break;
-			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-				if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
-				{
-					return error(GL_INVALID_OPERATION);
-				}
-				break;
-			default:
-				return error(GL_INVALID_ENUM);
-			}
-
-			if(level != 0)
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		gl::Framebuffer *framebuffer = nullptr;
-		GLuint framebufferName = 0;
-		if(target == GL_READ_FRAMEBUFFER_EXT)
-		{
-			framebuffer = context->getReadFramebuffer();
-			framebufferName = context->getReadFramebufferName();
-		}
-		else
-		{
-			framebuffer = context->getDrawFramebuffer();
-			framebufferName = context->getDrawFramebufferName();
-		}
-
-		if(framebufferName == 0 || !framebuffer)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		switch(attachment)
-		{
-		case GL_COLOR_ATTACHMENT0:  framebuffer->setColorbuffer(textarget, texture);   break;
-		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;
-		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
-		}
-	}
-}
-
-void APIENTRY glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glFrontFace(GLenum mode)
-{
-	TRACE("(GLenum mode = 0x%X)", mode);
-
-	switch(mode)
-	{
-	case GL_CW:
-	case GL_CCW:
-		{
-			gl::Context *context = gl::getContext();
-
-			if(context)
-			{
-				context->setFrontFace(mode);
-			}
-		}
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-}
-
-void APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
-{
-	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
-
-	if(n < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		for(int i = 0; i < n; i++)
-		{
-			buffers[i] = context->createBuffer();
-		}
-	}
-}
-
-void APIENTRY glGenerateMipmap(GLenum target)
-{
-	TRACE("(GLenum target = 0x%X)", target);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Texture *texture;
-
-		switch(target)
-		{
-		case GL_TEXTURE_2D:
-			texture = context->getTexture2D(target);
-			break;
-		case GL_TEXTURE_CUBE_MAP:
-			texture = context->getTextureCubeMap();
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-
-		if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		texture->generateMipmaps();
-	}
-}
-
-void APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
-{
-	TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);
-
-	if(n < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		for(int i = 0; i < n; i++)
-		{
-			fences[i] = context->createFence();
-		}
-	}
-}
-
-void APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
-{
-	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
-
-	if(n < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		for(int i = 0; i < n; i++)
-		{
-			framebuffers[i] = context->createFramebuffer();
-		}
-	}
-}
-
-void APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
-{
-	TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
-
-	if(n < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		for(int i = 0; i < n; i++)
-		{
-			ids[i] = context->createQuery();
-		}
-	}
-}
-
-void APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
-{
-	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
-
-	if(n < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		for(int i = 0; i < n; i++)
-		{
-			renderbuffers[i] = context->createRenderbuffer();
-		}
-	}
-}
-
-void APIENTRY glGenTextures(GLsizei n, GLuint* textures)
-{
-	TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
-
-	if(n < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		for(int i = 0; i < n; i++)
-		{
-			textures[i] = context->createTexture();
-		}
-	}
-}
-
-void APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
-{
-	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
-	      "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
-	      program, index, bufsize, length, size, type, name);
-
-	if(bufsize < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject)
-		{
-			if(context->getShader(program))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		if(index >= programObject->getActiveAttributeCount())
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		programObject->getActiveAttribute(index, bufsize, length, size, type, name);
-	}
-}
-
-void APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
-{
-	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
-	      "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
-	      program, index, bufsize, length, size, type, name);
-
-	if(bufsize < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject)
-		{
-			if(context->getShader(program))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		if(index >= programObject->getActiveUniformCount())
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		programObject->getActiveUniform(index, bufsize, length, size, type, name);
-	}
-}
-
-void APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
-{
-	TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
-	      program, maxcount, count, shaders);
-
-	if(maxcount < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject)
-		{
-			if(context->getShader(program))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		return programObject->getAttachedShaders(maxcount, count, shaders);
-	}
-}
-
-int APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
-{
-	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject)
-		{
-			if(context->getShader(program))
-			{
-				return error(GL_INVALID_OPERATION, -1);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE, -1);
-			}
-		}
-
-		if(!programObject->isLinked())
-		{
-			return error(GL_INVALID_OPERATION, -1);
-		}
-
-		return programObject->getAttributeLocation(name);
-	}
-
-	return -1;
-}
-
-void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
-{
-	TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)",  pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(!(context->getBooleanv(pname, params)))
-		{
-			GLenum nativeType;
-			unsigned int numParams = 0;
-			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
-				return error(GL_INVALID_ENUM);
-
-			if(numParams == 0)
-				return; // it is known that the pname is valid, but there are no parameters to return
-
-			if(nativeType == GL_FLOAT)
-			{
-				GLfloat *floatParams = nullptr;
-				floatParams = new GLfloat[numParams];
-
-				context->getFloatv(pname, floatParams);
-
-				for(unsigned int i = 0; i < numParams; ++i)
-				{
-					if(floatParams[i] == 0.0f)
-						params[i] = GL_FALSE;
-					else
-						params[i] = GL_TRUE;
-				}
-
-				delete [] floatParams;
-			}
-			else if(nativeType == GL_INT)
-			{
-				GLint *intParams = nullptr;
-				intParams = new GLint[numParams];
-
-				context->getIntegerv(pname, intParams);
-
-				for(unsigned int i = 0; i < numParams; ++i)
-				{
-					if(intParams[i] == 0)
-						params[i] = GL_FALSE;
-					else
-						params[i] = GL_TRUE;
-				}
-
-				delete [] intParams;
-			}
-		}
-	}
-}
-
-void APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
-{
-	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::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 = buffer->size();
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-GLenum APIENTRY glGetError(void)
-{
-	TRACE("()");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		return context->getError();
-	}
-
-	return GL_NO_ERROR;
-}
-
-void APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
-{
-	TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Fence *fenceObject = context->getFence(fence);
-
-		if(!fenceObject)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		fenceObject->getFenceiv(pname, params);
-	}
-}
-
-void APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
-{
-	TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(!(context->getFloatv(pname, params)))
-		{
-			GLenum nativeType;
-			unsigned int numParams = 0;
-			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
-				return error(GL_INVALID_ENUM);
-
-			if(numParams == 0)
-				return; // it is known that the pname is valid, but that there are no parameters to return.
-
-			if(nativeType == GL_BOOL)
-			{
-				GLboolean *boolParams = nullptr;
-				boolParams = new GLboolean[numParams];
-
-				context->getBooleanv(pname, boolParams);
-
-				for(unsigned int i = 0; i < numParams; ++i)
-				{
-					if(boolParams[i] == GL_FALSE)
-						params[i] = 0.0f;
-					else
-						params[i] = 1.0f;
-				}
-
-				delete [] boolParams;
-			}
-			else if(nativeType == GL_INT)
-			{
-				GLint *intParams = nullptr;
-				intParams = new GLint[numParams];
-
-				context->getIntegerv(pname, intParams);
-
-				for(unsigned int i = 0; i < numParams; ++i)
-				{
-					params[i] = (GLfloat)intParams[i];
-				}
-
-				delete [] intParams;
-			}
-		}
-	}
-}
-
-void APIENTRY glGetFramebufferAttachmentParameteriv(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);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
-		{
-			return error(GL_INVALID_ENUM);
-		}
-
-		gl::Framebuffer *framebuffer = nullptr;
-		if(target == GL_READ_FRAMEBUFFER_EXT)
-		{
-			if(context->getReadFramebufferName() == 0)
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-
-			framebuffer = context->getReadFramebuffer();
-		}
-		else
-		{
-			if(context->getDrawFramebufferName() == 0)
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-
-			framebuffer = context->getDrawFramebuffer();
-		}
-
-		GLenum attachmentType;
-		GLuint attachmentHandle;
-		switch(attachment)
-		{
-		case GL_COLOR_ATTACHMENT0:
-			attachmentType = framebuffer->getColorbufferType();
-			attachmentHandle = framebuffer->getColorbufferName();
-			break;
-		case GL_DEPTH_ATTACHMENT:
-			attachmentType = framebuffer->getDepthbufferType();
-			attachmentHandle = framebuffer->getDepthbufferName();
-			break;
-		case GL_STENCIL_ATTACHMENT:
-			attachmentType = framebuffer->getStencilbufferType();
-			attachmentHandle = framebuffer->getStencilbufferName();
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-
-		GLenum attachmentObjectType;   // Type category
-		if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
-		{
-			attachmentObjectType = attachmentType;
-		}
-		else if(gl::IsTextureTarget(attachmentType))
-		{
-			attachmentObjectType = GL_TEXTURE;
-		}
-		else UNREACHABLE(attachmentType);
-
-		switch(pname)
-		{
-		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
-			*params = attachmentObjectType;
-			break;
-		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-			if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
-			{
-				*params = attachmentHandle;
-			}
-			else
-			{
-				return error(GL_INVALID_ENUM);
-			}
-			break;
-		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
-			if(attachmentObjectType == GL_TEXTURE)
-			{
-				*params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
-			}
-			else
-			{
-				return error(GL_INVALID_ENUM);
-			}
-			break;
-		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
-			if(attachmentObjectType == GL_TEXTURE)
-			{
-				if(gl::IsCubemapTextureTarget(attachmentType))
-				{
-					*params = attachmentType;
-				}
-				else
-				{
-					*params = 0;
-				}
-			}
-			else
-			{
-				return error(GL_INVALID_ENUM);
-			}
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-GLenum APIENTRY glGetGraphicsResetStatusEXT(void)
-{
-	TRACE("()");
-
-	return GL_NO_ERROR;
-}
-
-void APIENTRY glGetIntegerv(GLenum pname, GLint* params)
-{
-	TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(!(context->getIntegerv(pname, params)))
-		{
-			GLenum nativeType;
-			unsigned int numParams = 0;
-			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
-				return error(GL_INVALID_ENUM);
-
-			if(numParams == 0)
-				return; // it is known that pname is valid, but there are no parameters to return
-
-			if(nativeType == GL_BOOL)
-			{
-				GLboolean *boolParams = nullptr;
-				boolParams = new GLboolean[numParams];
-
-				context->getBooleanv(pname, boolParams);
-
-				for(unsigned int i = 0; i < numParams; ++i)
-				{
-					if(boolParams[i] == GL_FALSE)
-						params[i] = 0;
-					else
-						params[i] = 1;
-				}
-
-				delete [] boolParams;
-			}
-			else if(nativeType == GL_FLOAT)
-			{
-				GLfloat *floatParams = nullptr;
-				floatParams = new GLfloat[numParams];
-
-				context->getFloatv(pname, floatParams);
-
-				for(unsigned int i = 0; i < numParams; ++i)
-				{
-					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
-					{
-						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;
-			}
-		}
-	}
-}
-
-void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
-{
-	TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		switch(pname)
-		{
-		case GL_DELETE_STATUS:
-			*params = programObject->isFlaggedForDeletion();
-			return;
-		case GL_LINK_STATUS:
-			*params = programObject->isLinked();
-			return;
-		case GL_VALIDATE_STATUS:
-			*params = programObject->isValidated();
-			return;
-		case GL_INFO_LOG_LENGTH:
-			*params = programObject->getInfoLogLength();
-			return;
-		case GL_ATTACHED_SHADERS:
-			*params = programObject->getAttachedShadersCount();
-			return;
-		case GL_ACTIVE_ATTRIBUTES:
-			*params = programObject->getActiveAttributeCount();
-			return;
-		case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
-			*params = programObject->getActiveAttributeMaxLength();
-			return;
-		case GL_ACTIVE_UNIFORMS:
-			*params = programObject->getActiveUniformCount();
-			return;
-		case GL_ACTIVE_UNIFORM_MAX_LENGTH:
-			*params = programObject->getActiveUniformMaxLength();
-			return;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
-{
-	TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
-	      program, bufsize, length, infolog);
-
-	if(bufsize < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		programObject->getInfoLog(bufsize, length, infolog);
-	}
-}
-
-void APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
-{
-	TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
-
-	switch(pname)
-	{
-	case GL_CURRENT_QUERY:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		params[0] = context->getActiveQuery(target);
-	}
-}
-
-void APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
-{
-	TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
-
-	switch(pname)
-	{
-	case GL_QUERY_RESULT:
-	case GL_QUERY_RESULT_AVAILABLE:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
-
-		if(!queryObject)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(context->getActiveQuery(queryObject->getType()) == name)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		switch(pname)
-		{
-		case GL_QUERY_RESULT:
-			params[0] = queryObject->getResult();
-			break;
-		case GL_QUERY_RESULT_AVAILABLE:
-			params[0] = queryObject->isResultAvailable();
-			break;
-		default:
-			ASSERT(false);
-		}
-	}
-}
-
-void APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
-{
-	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(target != GL_RENDERBUFFER)
-		{
-			return error(GL_INVALID_ENUM);
-		}
-
-		if(context->getRenderbufferName() == 0)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
-
-		switch(pname)
-		{
-		case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;
-		case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;
-		case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat();      break;
-		case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;
-		case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;
-		case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;
-		case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;
-		case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;
-		case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;
-		case GL_RENDERBUFFER_SAMPLES_EXT:     *params = renderbuffer->getSamples();     break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
-{
-	TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Shader *shaderObject = context->getShader(shader);
-
-		if(!shaderObject)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		switch(pname)
-		{
-		case GL_SHADER_TYPE:
-			*params = shaderObject->getType();
-			return;
-		case GL_DELETE_STATUS:
-			*params = shaderObject->isFlaggedForDeletion();
-			return;
-		case GL_COMPILE_STATUS:
-			*params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
-			return;
-		case GL_INFO_LOG_LENGTH:
-			*params = shaderObject->getInfoLogLength();
-			return;
-		case GL_SHADER_SOURCE_LENGTH:
-			*params = shaderObject->getSourceLength();
-			return;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
-{
-	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
-	      shader, bufsize, length, infolog);
-
-	if(bufsize < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Shader *shaderObject = context->getShader(shader);
-
-		if(!shaderObject)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		shaderObject->getInfoLog(bufsize, length, infolog);
-	}
-}
-
-void APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
-{
-	TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
-	      shadertype, precisiontype, range, precision);
-
-	switch(shadertype)
-	{
-	case GL_VERTEX_SHADER:
-	case GL_FRAGMENT_SHADER:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	switch(precisiontype)
-	{
-	case GL_LOW_FLOAT:
-	case GL_MEDIUM_FLOAT:
-	case GL_HIGH_FLOAT:
-		// IEEE 754 single-precision
-		range[0] = 127;
-		range[1] = 127;
-		*precision = 23;
-		break;
-	case GL_LOW_INT:
-	case GL_MEDIUM_INT:
-	case GL_HIGH_INT:
-		// Full integer precision is supported
-		range[0] = 31;
-		range[1] = 30;
-		*precision = 0;
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-}
-
-void APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
-{
-	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
-	      shader, bufsize, length, source);
-
-	if(bufsize < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Shader *shaderObject = context->getShader(shader);
-
-		if(!shaderObject)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		shaderObject->getSource(bufsize, length, source);
-	}
-}
-
-const GLubyte* APIENTRY glGetString(GLenum name)
-{
-	TRACE("(GLenum name = 0x%X)", name);
-
-	switch(name)
-	{
-	case GL_VENDOR:
-		return (GLubyte*)"Google Inc.";
-	case GL_RENDERER:
-		return (GLubyte*)"SwiftShader";
-	case GL_VERSION:
-		return (GLubyte*)"2.1 SwiftShader " VERSION_STRING;
-	case GL_SHADING_LANGUAGE_VERSION:
-		return (GLubyte*)"3.30 SwiftShader " VERSION_STRING;
-	case GL_EXTENSIONS:
-		// Keep list sorted in following order:
-		// OES extensions
-		// EXT extensions
-		// Vendor extensions
-		return (GLubyte*)
-			"GL_ARB_framebuffer_object "
-			"GL_EXT_blend_minmax "
-			"GL_EXT_depth_texture "
-			"GL_EXT_depth_texture_cube_map "
-			"GL_EXT_element_index_uint "
-			"GL_EXT_packed_depth_stencil "
-			"GL_EXT_rgb8_rgba8 "
-			"GL_EXT_standard_derivatives "
-			"GL_EXT_texture_float "
-			"GL_EXT_texture_float_linear "
-			"GL_EXT_texture_half_float "
-			"GL_EXT_texture_half_float_linear "
-			"GL_EXT_texture_npot "
-			"GL_EXT_occlusion_query_boolean "
-			"GL_EXT_read_format_bgra "
-			"GL_EXT_texture_compression_dxt1 "
-			"GL_EXT_blend_func_separate "
-			"GL_EXT_secondary_color "
-			"GL_EXT_texture_filter_anisotropic "
-			"GL_EXT_texture_format_BGRA8888 "
-			"GL_EXT_framebuffer_blit "
-			"GL_EXT_framebuffer_multisample "
-			"GL_EXT_texture_compression_dxt3 "
-			"GL_EXT_texture_compression_dxt5 "
-			"GL_NV_fence";
-	default:
-		return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
-	}
-
-	return nullptr;
-}
-
-void APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
-{
-	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Texture *texture;
-
-		switch(target)
-		{
-		case GL_TEXTURE_2D:
-			texture = context->getTexture2D(target);
-			break;
-		case GL_TEXTURE_CUBE_MAP:
-			texture = context->getTextureCubeMap();
-			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;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
-{
-	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Texture *texture;
-
-		switch(target)
-		{
-		case GL_TEXTURE_2D:
-			texture = context->getTexture2D(target);
-			break;
-		case GL_TEXTURE_CUBE_MAP:
-			texture = context->getTextureCubeMap();
-			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;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
-{
-	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
-	      program, location, bufSize, params);
-
-	if(bufSize < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(program == 0)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject || !programObject->isLinked())
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!programObject->getUniformfv(location, &bufSize, params))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
-{
-	TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(program == 0)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject || !programObject->isLinked())
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!programObject->getUniformfv(location, nullptr, params))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
-{
-	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
-	      program, location, bufSize, params);
-
-	if(bufSize < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(program == 0)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject || !programObject->isLinked())
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!programObject)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!programObject->getUniformiv(location, &bufSize, params))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
-{
-	TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(program == 0)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject || !programObject->isLinked())
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!programObject)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!programObject->getUniformiv(location, nullptr, params))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-int APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
-{
-	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
-
-	gl::Context *context = gl::getContext();
-
-	if(strstr(name, "gl_") == name)
-	{
-		return -1;
-	}
-
-	if(context)
-	{
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject)
-		{
-			if(context->getShader(program))
-			{
-				return error(GL_INVALID_OPERATION, -1);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE, -1);
-			}
-		}
-
-		if(!programObject->isLinked())
-		{
-			return error(GL_INVALID_OPERATION, -1);
-		}
-
-		return programObject->getUniformLocation(name);
-	}
-
-	return -1;
-}
-
-void APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
-{
-	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(index >= gl::MAX_VERTEX_ATTRIBS)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
-
-		switch(pname)
-		{
-		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
-			*params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
-			break;
-		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
-			*params = (GLfloat)attribState.mSize;
-			break;
-		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
-			*params = (GLfloat)attribState.mStride;
-			break;
-		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
-			*params = (GLfloat)attribState.mType;
-			break;
-		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
-			*params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
-			break;
-		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
-			*params = (GLfloat)attribState.mBoundBuffer.name();
-			break;
-		case GL_CURRENT_VERTEX_ATTRIB:
-			for(int i = 0; i < 4; ++i)
-			{
-				params[i] = attribState.mCurrentValue[i];
-			}
-			break;
-		default: return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
-{
-	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(index >= gl::MAX_VERTEX_ATTRIBS)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
-
-		switch(pname)
-		{
-		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
-			*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
-			break;
-		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
-			*params = attribState.mSize;
-			break;
-		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
-			*params = attribState.mStride;
-			break;
-		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
-			*params = attribState.mType;
-			break;
-		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
-			*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
-			break;
-		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
-			*params = attribState.mBoundBuffer.name();
-			break;
-		case GL_CURRENT_VERTEX_ATTRIB:
-			for(int i = 0; i < 4; ++i)
-			{
-				float currentValue = attribState.mCurrentValue[i];
-				params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
-			}
-			break;
-		default: return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
-{
-	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(index >= gl::MAX_VERTEX_ATTRIBS)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
-		{
-			return error(GL_INVALID_ENUM);
-		}
-
-		*pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
-	}
-}
-
-void APIENTRY glHint(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);
-	}
-
-	gl::Context *context = gl::getContext();
-	switch(target)
-	{
-	case GL_GENERATE_MIPMAP_HINT:
-		if(context) context->setGenerateMipmapHint(mode);
-		break;
-	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
-		if(context) context->setFragmentShaderDerivativeHint(mode);
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-}
-
-GLboolean APIENTRY glIsBuffer(GLuint buffer)
-{
-	TRACE("(GLuint buffer = %d)", buffer);
-
-	gl::Context *context = gl::getContext();
-
-	if(context && buffer)
-	{
-		gl::Buffer *bufferObject = context->getBuffer(buffer);
-
-		if(bufferObject)
-		{
-			return GL_TRUE;
-		}
-	}
-
-	return GL_FALSE;
-}
-
-GLboolean APIENTRY glIsEnabled(GLenum cap)
-{
-	TRACE("(GLenum cap = 0x%X)", cap);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		switch(cap)
-		{
-		case GL_CULL_FACE:                return context->isCullFaceEnabled();
-		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();
-		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
-		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();
-		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();
-		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();
-		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();
-		case GL_BLEND:                    return context->isBlendEnabled();
-		case GL_DITHER:                   return context->isDitherEnabled();
-		case GL_COLOR_LOGIC_OP:           return context->isColorLogicOpEnabled();
-		case GL_INDEX_LOGIC_OP:           UNIMPLEMENTED();
-		default:
-			return error(GL_INVALID_ENUM, false);
-		}
-	}
-
-	return false;
-}
-
-GLboolean APIENTRY glIsFenceNV(GLuint fence)
-{
-	TRACE("(GLuint fence = %d)", fence);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Fence *fenceObject = context->getFence(fence);
-
-		if(!fenceObject)
-		{
-			return GL_FALSE;
-		}
-
-		return fenceObject->isFence();
-	}
-
-	return GL_FALSE;
-}
-
-GLboolean APIENTRY glIsFramebuffer(GLuint framebuffer)
-{
-	TRACE("(GLuint framebuffer = %d)", framebuffer);
-
-	gl::Context *context = gl::getContext();
-
-	if(context && framebuffer)
-	{
-		gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
-
-		if(framebufferObject)
-		{
-			return GL_TRUE;
-		}
-	}
-
-	return GL_FALSE;
-}
-
-GLboolean APIENTRY glIsProgram(GLuint program)
-{
-	TRACE("(GLuint program = %d)", program);
-
-	gl::Context *context = gl::getContext();
-
-	if(context && program)
-	{
-		gl::Program *programObject = context->getProgram(program);
-
-		if(programObject)
-		{
-			return GL_TRUE;
-		}
-	}
-
-	return GL_FALSE;
-}
-
-GLboolean APIENTRY glIsQueryEXT(GLuint name)
-{
-	TRACE("(GLuint name = %d)", name);
-
-	if(name == 0)
-	{
-		return GL_FALSE;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Query *queryObject = context->getQuery(name, false, GL_NONE);
-
-		if(queryObject)
-		{
-			return GL_TRUE;
-		}
-	}
-
-	return GL_FALSE;
-}
-
-GLboolean APIENTRY glIsRenderbuffer(GLuint renderbuffer)
-{
-	TRACE("(GLuint renderbuffer = %d)", renderbuffer);
-
-	gl::Context *context = gl::getContext();
-
-	if(context && renderbuffer)
-	{
-		gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
-
-		if(renderbufferObject)
-		{
-			return GL_TRUE;
-		}
-	}
-
-	return GL_FALSE;
-}
-
-GLboolean APIENTRY glIsShader(GLuint shader)
-{
-	TRACE("(GLuint shader = %d)", shader);
-
-	gl::Context *context = gl::getContext();
-
-	if(context && shader)
-	{
-		gl::Shader *shaderObject = context->getShader(shader);
-
-		if(shaderObject)
-		{
-			return GL_TRUE;
-		}
-	}
-
-	return GL_FALSE;
-}
-
-GLboolean APIENTRY glIsTexture(GLuint texture)
-{
-	TRACE("(GLuint texture = %d)", texture);
-
-	gl::Context *context = gl::getContext();
-
-	if(context && texture)
-	{
-		gl::Texture *textureObject = context->getTexture(texture);
-
-		if(textureObject)
-		{
-			return GL_TRUE;
-		}
-	}
-
-	return GL_FALSE;
-}
-
-void APIENTRY glLineWidth(GLfloat width)
-{
-	TRACE("(GLfloat width = %f)", width);
-
-	if(width <= 0.0f)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setLineWidth(width);
-	}
-}
-
-void APIENTRY glLinkProgram(GLuint program)
-{
-	TRACE("(GLuint program = %d)", program);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject)
-		{
-			if(context->getShader(program))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		programObject->link();
-	}
-}
-
-void APIENTRY glPixelStorei(GLenum pname, GLint param)
-{
-	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
-
-	gl::Context *context = gl::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 APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
-{
-	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setPolygonOffsetParams(factor, units);
-	}
-}
-
-void APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
-							   GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
-{
-	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
-		  "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
-		  x, y, width, height, format, type, bufSize, data);
-
-	if(width < 0 || height < 0 || bufSize < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(!validReadFormatType(format, type))
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->readPixels(x, y, width, height, format, type, &bufSize, data);
-	}
-}
-
-void APIENTRY glReadPixels(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);
-	}
-
-	if(!validReadFormatType(format, type))
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		context->readPixels(x, y, width, height, format, type, nullptr, pixels);
-	}
-}
-
-void APIENTRY glReleaseShaderCompiler(void)
-{
-	TRACE("()");
-
-	gl::Shader::releaseCompiler();
-}
-
-void APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
-{
-	TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
-	      target, samples, internalformat, width, height);
-
-	switch(target)
-	{
-	case GL_RENDERBUFFER:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	if(!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
-	{
-		return error(GL_INVALID_ENUM);
-	}
-
-	if(width < 0 || height < 0 || samples < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(width > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
-		   height > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
-		   samples > gl::IMPLEMENTATION_MAX_SAMPLES)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		GLuint handle = context->getRenderbufferName();
-		if(handle == 0)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		switch(internalformat)
-		{
-		case GL_DEPTH_COMPONENT16:
-		case GL_DEPTH_COMPONENT24:
-			context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
-			break;
-		case GL_RGBA4:
-		case GL_RGB5_A1:
-		case GL_RGB565:
-		case GL_RGB8_EXT:
-		case GL_RGBA8_EXT:
-			context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
-			break;
-		case GL_STENCIL_INDEX8:
-			context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
-			break;
-		case GL_DEPTH24_STENCIL8_EXT:
-			context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
-{
-	glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
-}
-
-void APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
-{
-	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
-
-	gl::Context* context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
-	}
-}
-
-void APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
-{
-	TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
-
-	if(condition != GL_ALL_COMPLETED_NV)
-	{
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Fence *fenceObject = context->getFence(fence);
-
-		if(!fenceObject)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		fenceObject->setFence(condition);
-	}
-}
-
-void APIENTRY glScissor(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);
-	}
-
-	gl::Context* context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setScissorParams(x, y, width, height);
-	}
-}
-
-void APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
-{
-	TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
-	      "const GLvoid* binary = %p, GLsizei length = %d)",
-	      n, shaders, binaryformat, binary, length);
-
-	// No binary shader formats are supported.
-	return error(GL_INVALID_ENUM);
-}
-
-void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
-{
-	TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
-	      shader, count, string, length);
-
-	if(count < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Shader *shaderObject = context->getShader(shader);
-
-		if(!shaderObject)
-		{
-			if(context->getProgram(shader))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		shaderObject->setSource(count, string, length);
-	}
-}
-
-void APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
-{
-	glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
-}
-
-void APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
-{
-	TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
-
-	switch(face)
-	{
-	case GL_FRONT:
-	case GL_BACK:
-	case GL_FRONT_AND_BACK:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	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);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
-		{
-			context->setStencilParams(func, ref, mask);
-		}
-
-		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
-		{
-			context->setStencilBackParams(func, ref, mask);
-		}
-	}
-}
-
-void APIENTRY glStencilMask(GLuint mask)
-{
-	glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
-}
-
-void APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
-{
-	TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
-
-	switch(face)
-	{
-	case GL_FRONT:
-	case GL_BACK:
-	case GL_FRONT_AND_BACK:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
-		{
-			context->setStencilWritemask(mask);
-		}
-
-		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
-		{
-			context->setStencilBackWritemask(mask);
-		}
-	}
-}
-
-void APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
-{
-	glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
-}
-
-void APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
-{
-	TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
-	      face, fail, zfail, zpass);
-
-	switch(face)
-	{
-	case GL_FRONT:
-	case GL_BACK:
-	case GL_FRONT_AND_BACK:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	switch(fail)
-	{
-	case GL_ZERO:
-	case GL_KEEP:
-	case GL_REPLACE:
-	case GL_INCR:
-	case GL_DECR:
-	case GL_INVERT:
-	case GL_INCR_WRAP:
-	case GL_DECR_WRAP:
-		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:
-	case GL_DECR_WRAP:
-		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:
-	case GL_DECR_WRAP:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
-		{
-			context->setStencilOperations(fail, zfail, zpass);
-		}
-
-		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
-		{
-			context->setStencilBackOperations(fail, zfail, zpass);
-		}
-	}
-}
-
-GLboolean APIENTRY glTestFenceNV(GLuint fence)
-{
-	TRACE("(GLuint fence = %d)", fence);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Fence *fenceObject = context->getFence(fence);
-
-		if(!fenceObject)
-		{
-			return error(GL_INVALID_OPERATION, GL_TRUE);
-		}
-
-		return fenceObject->testFence();
-	}
-
-	return GL_TRUE;
-}
-
-void APIENTRY glTexImage2D(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)
-	{
-		//TRACE("UNIMPLEMENTED!!");
-		//return error(GL_INVALID_OPERATION);
-	}
-
-	switch(format)
-	{
-	case GL_ALPHA:
-	case GL_LUMINANCE:
-	case GL_LUMINANCE_ALPHA:
-		switch(type)
-		{
-		case GL_UNSIGNED_BYTE:
-		case GL_FLOAT:
-		case GL_HALF_FLOAT:
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-		break;
-	case GL_RGB:
-		switch(type)
-		{
-		case GL_UNSIGNED_BYTE:
-		case GL_UNSIGNED_SHORT_5_6_5:
-		case GL_FLOAT:
-		case GL_HALF_FLOAT:
-			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:
-		case GL_FLOAT:
-		case GL_HALF_FLOAT:
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-		break;
-	case GL_BGRA_EXT:
-		switch(type)
-		{
-		case GL_UNSIGNED_BYTE:
-		case GL_UNSIGNED_SHORT_5_6_5:
-		case GL_UNSIGNED_INT_8_8_8_8_REV:
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-		break;
-	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:  // error cases for compressed textures are handled below
-	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-		break;
-	case GL_DEPTH_COMPONENT:
-		switch(type)
-		{
-		case GL_UNSIGNED_SHORT:
-		case GL_UNSIGNED_INT:
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-		break;
-	case GL_DEPTH_STENCIL_EXT:
-		switch(type)
-		{
-		case GL_UNSIGNED_INT_24_8_EXT:
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-		break;
-	default:
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(border != 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	switch(target)
-	{
-	case GL_TEXTURE_2D:
-		if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
-		   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
-		{
-			return error(GL_INVALID_VALUE);
-		}
-		break;
-	case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-	case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-	case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-	case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-		if(width != height)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
-		   height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
-		{
-			return error(GL_INVALID_VALUE);
-		}
-		break;
-	case GL_PROXY_TEXTURE_2D:
-		pixels = 0;
-
-		if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
-		   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
-		{
-			//UNIMPLEMENTED();
-			width = 0;
-			height = 0;
-			internalformat = GL_NONE;
-			format = GL_NONE;
-			type = GL_NONE;
-
-			//return;// error(GL_INVALID_VALUE);
-		}
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
-	   format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
-	   format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
-	   format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
-	{
-		return error(GL_INVALID_OPERATION);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D)
-		{
-			gl::Texture2D *texture = context->getTexture2D(target);
-
-			if(!texture)
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-
-			texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
-		}
-		else
-		{
-			gl::TextureCubeMap *texture = context->getTextureCubeMap();
-
-			if(!texture)
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-
-			texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
-		}
-	}
-}
-
-void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
-{
-	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Texture *texture;
-
-		switch(target)
-		{
-		case GL_TEXTURE_2D:
-			texture = context->getTexture2D(target);
-			break;
-		case GL_TEXTURE_CUBE_MAP:
-			texture = context->getTextureCubeMap();
-			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_TEXTURE_MIN_LOD:
-			//TRACE("() UNIMPLEMENTED!!");   // FIXME
-			//UNIMPLEMENTED();
-			break;
-		case GL_TEXTURE_MAX_LOD:
-			//TRACE("() UNIMPLEMENTED!!");   // FIXME
-			//UNIMPLEMENTED();
-			break;
-		case GL_TEXTURE_LOD_BIAS:
-			if(param != 0.0f)
-			{
-				UNIMPLEMENTED();
-			}
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
-{
-	glTexParameterf(target, pname, *params);
-}
-
-void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
-{
-	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Texture *texture;
-
-		switch(target)
-		{
-		case GL_TEXTURE_2D:
-			texture = context->getTexture2D(target);
-			break;
-		case GL_TEXTURE_CUBE_MAP:
-			texture = context->getTextureCubeMap();
-			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_TEXTURE_MAX_LEVEL:
-			if(!texture->setMaxLevel(param))
-			{
-				return error(GL_INVALID_ENUM);
-			}
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
-{
-	glTexParameteri(target, pname, *params);
-}
-
-void APIENTRY glTexSubImage2D(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(!gl::IsTextureTarget(target))
-	{
-		return error(GL_INVALID_ENUM);
-	}
-
-	if(level < 0 || 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(!gl::CheckTextureFormatType(format, type))
-	{
-		return error(GL_INVALID_ENUM);
-	}
-
-	if(width == 0 || height == 0 || !pixels)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-		{
-			return error(GL_INVALID_VALUE);
-		}
-
-		if(target == GL_TEXTURE_2D)
-		{
-			gl::Texture2D *texture = context->getTexture2D(target);
-
-			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
-			{
-				texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
-			}
-		}
-		else if(gl::IsCubemapTextureTarget(target))
-		{
-			gl::TextureCubeMap *texture = context->getTextureCubeMap();
-
-			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
-			{
-				texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
-			}
-		}
-		else UNREACHABLE(target);
-	}
-}
-
-void APIENTRY glUniform1f(GLint location, GLfloat x)
-{
-	glUniform1fv(location, 1, &x);
-}
-
-void APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
-{
-	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
-
-	if(count < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(location == -1)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Program *program = context->getCurrentProgram();
-
-		if(!program)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!program->setUniform1fv(location, count, v))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glUniform1i(GLint location, GLint x)
-{
-	glUniform1iv(location, 1, &x);
-}
-
-void APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
-{
-	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
-
-	if(count < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(location == -1)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Program *program = context->getCurrentProgram();
-
-		if(!program)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!program->setUniform1iv(location, count, v))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
-{
-	GLfloat xy[2] = {x, y};
-
-	glUniform2fv(location, 1, (GLfloat*)&xy);
-}
-
-void APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
-{
-	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
-
-	if(count < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(location == -1)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Program *program = context->getCurrentProgram();
-
-		if(!program)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!program->setUniform2fv(location, count, v))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glUniform2i(GLint location, GLint x, GLint y)
-{
-	GLint xy[4] = {x, y};
-
-	glUniform2iv(location, 1, (GLint*)&xy);
-}
-
-void APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
-{
-	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
-
-	if(count < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(location == -1)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Program *program = context->getCurrentProgram();
-
-		if(!program)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!program->setUniform2iv(location, count, v))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
-{
-	GLfloat xyz[3] = {x, y, z};
-
-	glUniform3fv(location, 1, (GLfloat*)&xyz);
-}
-
-void APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
-{
-	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
-
-	if(count < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(location == -1)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Program *program = context->getCurrentProgram();
-
-		if(!program)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!program->setUniform3fv(location, count, v))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
-{
-	GLint xyz[3] = {x, y, z};
-
-	glUniform3iv(location, 1, (GLint*)&xyz);
-}
-
-void APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
-{
-	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
-
-	if(count < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(location == -1)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Program *program = context->getCurrentProgram();
-
-		if(!program)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!program->setUniform3iv(location, count, v))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-	GLfloat xyzw[4] = {x, y, z, w};
-
-	glUniform4fv(location, 1, (GLfloat*)&xyzw);
-}
-
-void APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
-{
-	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
-
-	if(count < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(location == -1)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Program *program = context->getCurrentProgram();
-
-		if(!program)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!program->setUniform4fv(location, count, v))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
-{
-	GLint xyzw[4] = {x, y, z, w};
-
-	glUniform4iv(location, 1, (GLint*)&xyzw);
-}
-
-void APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
-{
-	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
-
-	if(count < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(location == -1)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Program *program = context->getCurrentProgram();
-
-		if(!program)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!program->setUniform4iv(location, count, v))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-{
-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
-	      location, count, transpose, value);
-
-	if(count < 0 || transpose != GL_FALSE)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(location == -1)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Program *program = context->getCurrentProgram();
-
-		if(!program)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!program->setUniformMatrix2fv(location, count, value))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-{
-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
-	      location, count, transpose, value);
-
-	if(count < 0 || transpose != GL_FALSE)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(location == -1)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Program *program = context->getCurrentProgram();
-
-		if(!program)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!program->setUniformMatrix3fv(location, count, value))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-{
-	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
-	      location, count, transpose, value);
-
-	if(count < 0 || transpose != GL_FALSE)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(location == -1)
-	{
-		return;
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Program *program = context->getCurrentProgram();
-
-		if(!program)
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		if(!program->setUniformMatrix4fv(location, count, value))
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-	}
-}
-
-void APIENTRY glUseProgram(GLuint program)
-{
-	TRACE("(GLuint program = %d)", program);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject && program != 0)
-		{
-			if(context->getShader(program))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		if(program != 0 && !programObject->isLinked())
-		{
-			return error(GL_INVALID_OPERATION);
-		}
-
-		context->useProgram(program);
-	}
-}
-
-void APIENTRY glValidateProgram(GLuint program)
-{
-	TRACE("(GLuint program = %d)", program);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Program *programObject = context->getProgram(program);
-
-		if(!programObject)
-		{
-			if(context->getShader(program))
-			{
-				return error(GL_INVALID_OPERATION);
-			}
-			else
-			{
-				return error(GL_INVALID_VALUE);
-			}
-		}
-
-		programObject->validate();
-	}
-}
-
-void APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
-{
-	TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
-
-	if(index >= gl::MAX_VERTEX_ATTRIBS)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		//GLfloat vals[4] = { x, 0, 0, 1 };
-		context->setVertexAttrib(index, x, 0, 0, 1);
-	}
-}
-
-void APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
-{
-	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
-
-	if(index >= gl::MAX_VERTEX_ATTRIBS)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		//GLfloat vals[4] = { values[0], 0, 0, 1 };
-		context->setVertexAttrib(index, values[0], 0, 0, 1);
-	}
-}
-
-void APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
-{
-	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
-
-	if(index >= gl::MAX_VERTEX_ATTRIBS)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		//GLfloat vals[4] = { x, y, 0, 1 };
-		context->setVertexAttrib(index, x, y, 0, 1);
-	}
-}
-
-void APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
-{
-	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
-
-	if(index >= gl::MAX_VERTEX_ATTRIBS)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		//GLfloat vals[4] = {  };
-		context->setVertexAttrib(index, values[0], values[1], 0, 1);
-	}
-}
-
-void APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
-{
-	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
-
-	if(index >= gl::MAX_VERTEX_ATTRIBS)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		//GLfloat vals[4] = { x, y, z, 1 };
-		context->setVertexAttrib(index, x, y, z, 1);
-	}
-}
-
-void APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
-{
-	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
-
-	if(index >= gl::MAX_VERTEX_ATTRIBS)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		//GLfloat vals[4] = { values[0], values[1], values[2], 1 };
-		context->setVertexAttrib(index, values[0], values[1], values[2], 1);
-	}
-}
-
-void APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
-
-	if(index >= gl::MAX_VERTEX_ATTRIBS)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		//GLfloat vals[4] = { x, y, z, w };
-		context->setVertexAttrib(index, x, y, z, w);
-	}
-}
-
-void APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
-{
-	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
-
-	if(index >= gl::MAX_VERTEX_ATTRIBS)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setVertexAttrib(index, values[0], values[1], values[2], values[3]);
-	}
-}
-
-void APIENTRY glVertexAttribPointer(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 >= gl::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);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
-	}
-}
-
-void APIENTRY glViewport(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);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setViewportParams(x, y, width, height);
-	}
-}
-
-void APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
-                                     GLbitfield mask, GLenum filter)
-{
-	TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
-	      "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
-	      "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
-	      srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-
-	switch(filter)
-	{
-	case GL_NEAREST:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
-	{
-		ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
-		return error(GL_INVALID_OPERATION);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		if(context->getReadFramebufferName() == context->getDrawFramebufferName())
-		{
-			ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
-			return error(GL_INVALID_OPERATION);
-		}
-
-		context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
-	}
-}
-
-void APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
-                              GLint border, GLenum format, GLenum type, const GLvoid* pixels)
-{
-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
-	      "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
-	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
-	      target, level, internalformat, width, height, depth, border, format, type, pixels);
-
-	UNIMPLEMENTED();   // FIXME
-}
-
-void WINAPI GlmfBeginGlsBlock()
-{
-	UNIMPLEMENTED();
-}
-
-void WINAPI GlmfCloseMetaFile()
-{
-	UNIMPLEMENTED();
-}
-
-void WINAPI GlmfEndGlsBlock()
-{
-	UNIMPLEMENTED();
-}
-
-void WINAPI GlmfEndPlayback()
-{
-	UNIMPLEMENTED();
-}
-
-void WINAPI GlmfInitPlayback()
-{
-	UNIMPLEMENTED();
-}
-
-void WINAPI GlmfPlayGlsRecord()
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glAccum(GLenum op, GLfloat value)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glAlphaFunc(GLenum func, GLclampf ref)
-{
-	TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->alphaFunc(func, ref);
-	}
-}
-
-GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
-{
-	UNIMPLEMENTED();
-	return GL_FALSE;
-}
-
-void APIENTRY glArrayElement(GLint i)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glBegin(GLenum mode)
-{
-	TRACE("(GLenum mode = 0x%X)", mode);
-
-	switch(mode)
-	{
-	case GL_POINTS:
-	case GL_LINES:
-	case GL_LINE_STRIP:
-	case GL_LINE_LOOP:
-	case GL_TRIANGLES:
-	case GL_TRIANGLE_STRIP:
-	case GL_TRIANGLE_FAN:
-	case GL_QUADS:
-	case GL_QUAD_STRIP:
-	case GL_POLYGON:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->begin(mode);
-	}
-}
-
-void APIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glCallList(GLuint list)
-{
-	TRACE("(GLuint list = %d)", list);
-
-	if(list == 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->callList(list);
-	}
-}
-
-void APIENTRY glCallLists(GLsizei n, GLenum type, const GLvoid *lists)
-{
-	TRACE("(GLsizei n = %d, GLenum type = 0x%X, const GLvoid *lists)", n, type);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		for(int i = 0; i < n; i++)
-		{
-			switch(type)
-			{
-			case GL_UNSIGNED_INT: context->callList(((unsigned int*)lists)[i]); break;
-			default:
-				UNIMPLEMENTED();
-				UNREACHABLE(type);
-			}
-		}
-	}
-}
-
-void APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glClearDepth(GLclampd depth)
-{
-	TRACE("(GLclampd depth = %d)", depth);
-
-	glClearDepthf((float)depth);   // FIXME
-}
-
-void APIENTRY glClearIndex(GLfloat c)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glClipPlane(GLenum plane, const GLdouble *equation)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3bv(const GLbyte *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue)
-{
-	TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f)", red, green, blue);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		//context->color(red, green, blue, 1.0f);
-		//GLfloat vals[4] = {};
-		context->setVertexAttrib(sw::Color0, red, green, blue, 1);
-	}
-}
-
-void APIENTRY glColor3fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3i(GLint red, GLint green, GLint blue)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3ubv(const GLubyte *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3uiv(const GLuint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor3usv(const GLushort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4bv(const GLbyte *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4f(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);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		//context->color(red, green, blue, alpha);
-		//GLfloat vals[4] = {red, green, blue, alpha};
-		context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
-	}
-}
-
-void APIENTRY glColor4fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4ubv(const GLubyte *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4uiv(const GLuint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColor4usv(const GLushort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glColorMaterial(GLenum face, GLenum mode)
-{
-	TRACE("(GLenum face = 0x%X, GLenum mode = 0x%X)", face, mode);
-
-	// FIXME: Validate enums
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		switch(face)
-		{
-		case GL_FRONT:
-			context->setColorMaterialMode(mode);   // FIXME: Front only
-			break;
-		case GL_FRONT_AND_BACK:
-			context->setColorMaterialMode(mode);
-			break;
-		default:
-			UNIMPLEMENTED();
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
-{
-	TRACE("(*)");
-
-	glVertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
-}
-
-void APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glDebugEntry()
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glDeleteLists(GLuint list, GLsizei range)
-{
-	TRACE("(GLuint list = %d, GLsizei range = %d)", list, range);
-
-	if(range < 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		for(GLuint i = list; i < list + range; i++)
-		{
-			context->deleteList(i);
-		}
-	}
-}
-
-void APIENTRY glDepthRange(GLclampd zNear, GLclampd zFar)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glDisableClientState(GLenum array)
-{
-	TRACE("(GLenum array = 0x%X)", array);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		GLenum texture = context->getClientActiveTexture();
-
-		switch(array)
-		{
-		case GL_VERTEX_ARRAY:        context->setVertexAttribArrayEnabled(sw::Position, false);                            break;
-		case GL_COLOR_ARRAY:         context->setVertexAttribArrayEnabled(sw::Color0, false);                              break;
-		case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
-		case GL_NORMAL_ARRAY:        context->setVertexAttribArrayEnabled(sw::Normal, false);                              break;
-		default:                     UNIMPLEMENTED();
-		}
-	}
-}
-
-void APIENTRY glDrawBuffer(GLenum mode)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEdgeFlag(GLboolean flag)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEdgeFlagv(const GLboolean *flag)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEnableClientState(GLenum array)
-{
-	TRACE("(GLenum array = 0x%X)", array);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		GLenum texture = context->getClientActiveTexture();
-
-		switch(array)
-		{
-		case GL_VERTEX_ARRAY:        context->setVertexAttribArrayEnabled(sw::Position, true);                            break;
-		case GL_COLOR_ARRAY:         context->setVertexAttribArrayEnabled(sw::Color0, true);                              break;
-		case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
-		case GL_NORMAL_ARRAY:        context->setVertexAttribArrayEnabled(sw::Normal, true);                              break;
-		default:                     UNIMPLEMENTED();
-		}
-	}
-}
-
-void APIENTRY glEnd()
-{
-	TRACE("()");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->end();
-	}
-}
-
-void APIENTRY glEndList()
-{
-	TRACE("()");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		context->endList();
-	}
-}
-
-void APIENTRY glEvalCoord1d(GLdouble u)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEvalCoord1dv(const GLdouble *u)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEvalCoord1f(GLfloat u)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEvalCoord1fv(const GLfloat *u)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEvalCoord2d(GLdouble u, GLdouble v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEvalCoord2dv(const GLdouble *u)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEvalCoord2f(GLfloat u, GLfloat v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEvalCoord2fv(const GLfloat *u)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEvalPoint1(GLint i)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glEvalPoint2(GLint i, GLint j)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glFogf(GLenum pname, GLfloat param)
-{
-	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Device *device = gl::getDevice();   // FIXME
-
-		switch(pname)
-		{
-		case GL_FOG_START: device->setFogStart(param); break;
-		case GL_FOG_END:   device->setFogEnd(param);   break;
-		default:
-			UNIMPLEMENTED();
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glFogfv(GLenum pname, const GLfloat *params)
-{
-	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		switch(pname)
-		{
-		case GL_FOG_COLOR:
-			{
-				gl::Device *device = gl::getDevice();   // FIXME
-				device->setFogColor(sw::Color<float>(params[0], params[1], params[2], params[3]));
-			}
-			break;
-		default:
-			UNIMPLEMENTED();
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glFogi(GLenum pname, GLint param)
-{
-	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		switch(pname)
-		{
-		case GL_FOG_MODE:
-			{
-				gl::Device *device = gl::getDevice();   // FIXME
-				switch(param)
-				{
-				case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
-				default:
-					UNIMPLEMENTED();
-					return error(GL_INVALID_ENUM);
-				}
-			}
-			break;
-		default:
-			UNIMPLEMENTED();
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glFogiv(GLenum pname, const GLint *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
-{
-	TRACE("(GLdouble left = %f, GLdouble right = %f, GLdouble bottom = %f, GLdouble top = %f, GLdouble zNear = %f, GLdouble zFar = %f)", left, right, bottom, top, zNear, zFar);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->frustum(left, right, bottom, top, zNear, zFar);
-	}
-}
-
-GLuint APIENTRY glGenLists(GLsizei range)
-{
-	TRACE("(GLsizei range = %d)", range);
-
-	if(range < 0)
-	{
-		return error(GL_INVALID_VALUE, 0);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		return context->genLists(range);
-	}
-
-	return 0;
-}
-
-void APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetDoublev(GLenum pname, GLdouble *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetPixelMapusv(GLenum map, GLushort *values)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetPointerv(GLenum pname, GLvoid* *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetPolygonStipple(GLubyte *mask)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
-{
-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum format = 0x%X, GLenum type = 0x%X, GLint *pixels%p)", target, level, format, type, pixels);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Texture *texture;
-
-		switch(target)
-		{
-		case GL_TEXTURE_2D:
-			texture = context->getTexture2D(target);
-			break;
-		case GL_TEXTURE_CUBE_MAP:
-			texture = context->getTextureCubeMap();
-			break;
-		default:
-			UNIMPLEMENTED();
-			return error(GL_INVALID_ENUM);
-		}
-
-		if(format == texture->getFormat(target, level) && type == texture->getType(target, level))
-		{
-			gl::Image *image = texture->getRenderTarget(target, level);
-			void *source = image->lock(0, 0, sw::LOCK_READONLY);
-			memcpy(pixels, source, image->getPitch() * image->getHeight());
-			image->unlock();
-		}
-		else
-		{
-			UNIMPLEMENTED();
-		}
-	}
-}
-
-void APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
-{
-	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLint *params = %p)", target, level, pname, params);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		gl::Texture *texture;
-
-		switch(target)
-		{
-		case GL_TEXTURE_2D:
-		case GL_PROXY_TEXTURE_2D:
-			texture = context->getTexture2D(target);
-			break;
-		case GL_TEXTURE_CUBE_MAP:
-			texture = context->getTextureCubeMap();
-			break;
-		default:
-			UNIMPLEMENTED();
-			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_WIDTH:
-			*params = texture->getWidth(target, level);
-			break;
-		case GL_TEXTURE_HEIGHT:
-			*params = texture->getHeight(target, level);
-			break;
-		case GL_TEXTURE_INTERNAL_FORMAT:
-				*params = texture->getInternalFormat(target, level);
-			break;
-		case GL_TEXTURE_BORDER_COLOR:
-			UNIMPLEMENTED();
-			break;
-		case GL_TEXTURE_BORDER:
-			UNIMPLEMENTED();
-			break;
-		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
-			*params = (GLint)texture->getMaxAnisotropy();
-			break;
-		default:
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glIndexMask(GLuint mask)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glIndexd(GLdouble c)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glIndexdv(const GLdouble *c)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glIndexf(GLfloat c)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glIndexfv(const GLfloat *c)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glIndexi(GLint c)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glIndexiv(const GLint *c)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glIndexs(GLshort c)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glIndexsv(const GLshort *c)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glIndexub(GLubyte c)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glIndexubv(const GLubyte *c)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glInitNames(void)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
-{
-	UNIMPLEMENTED();
-}
-
-GLboolean APIENTRY glIsList(GLuint list)
-{
-	UNIMPLEMENTED();
-	return GL_FALSE;
-}
-
-void APIENTRY glLightModelf(GLenum pname, GLfloat param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
-{
-	TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Device *device = gl::getDevice();   // FIXME
-
-		switch(pname)
-		{
-		case GL_LIGHT_MODEL_AMBIENT:
-			device->setGlobalAmbient(sw::Color<float>(params[0], params[1], params[2], params[3]));
-			break;
-		default:
-			UNIMPLEMENTED();
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glLightModeli(GLenum pname, GLint param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glLightModeliv(GLenum pname, const GLint *params)
-{
-	TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
-{
-	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		gl::Device *device = gl::getDevice();   // FIXME
-
-		switch(pname)
-		{
-		case GL_AMBIENT:  device->setLightAmbient(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3]));  break;
-		case GL_DIFFUSE:  device->setLightDiffuse(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3]));  break;
-		case GL_SPECULAR: device->setLightSpecular(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
-		case GL_POSITION:
-			if(params[3] == 0.0f)   // Directional light
-			{
-				// Create a very far out point light
-				float max = sw::max(abs(params[0]), abs(params[1]), abs(params[2]));
-				device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / max * 1e10f, params[1] / max * 1e10f, params[2] / max * 1e10f));
-			}
-			else
-			{
-				device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / params[3], params[1] / params[3], params[2] / params[3]));
-			}
-			break;
-		default:
-			UNIMPLEMENTED();
-			return error(GL_INVALID_ENUM);
-		}
-	}
-}
-
-void APIENTRY glLighti(GLenum light, GLenum pname, GLint param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glLineStipple(GLint factor, GLushort pattern)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glListBase(GLuint base)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glLoadIdentity()
-{
-	TRACE("()");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->loadIdentity();
-	}
-}
-
-void APIENTRY glLoadMatrixd(const GLdouble *m)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glLoadMatrixf(const GLfloat *m)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glLoadName(GLuint name)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glLogicOp(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);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setLogicalOperation(opcode);
-	}
-}
-
-void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glMateriali(GLenum face, GLenum pname, GLint param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glMatrixMode(GLenum mode)
-{
-	TRACE("(*)");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setMatrixMode(mode);
-	}
-}
-
-void APIENTRY glMultMatrixd(const GLdouble *m)
-{
-	TRACE("(*)");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->multiply(m);
-	}
-}
-
-void APIENTRY glMultMatrixm(sw::Matrix m)
-{
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		context->multiply((GLfloat*)m.m);
-	}
-}
-
-void APIENTRY glMultMatrixf(const GLfloat *m)
-{
-	TRACE("(*)");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			return context->listCommand(gl::newCommand(glMultMatrixm, sw::Matrix(m)));
-		}
-
-		context->multiply(m);
-	}
-}
-
-void APIENTRY glNewList(GLuint list, GLenum mode)
-{
-	TRACE("(GLuint list = %d, GLenum mode = 0x%X)", list, mode);
-
-	if(list == 0)
-	{
-		return error(GL_INVALID_VALUE);
-	}
-
-	switch(mode)
-	{
-	case GL_COMPILE:
-	case GL_COMPILE_AND_EXECUTE:
-		break;
-	default:
-		return error(GL_INVALID_ENUM);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->newList(list, mode);
-	}
-}
-
-void APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glNormal3bv(const GLbyte *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glNormal3dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
-{
-	TRACE("(GLfloat nx = %f, GLfloat ny = %f, GLfloat nz = %f)", nx, ny, nz);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		//context->normal(nx, ny, nz);
-		context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
-	}
-}
-
-void APIENTRY glNormal3fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glNormal3iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glNormal3sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
-{
-	TRACE("(*)");
-
-	glVertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);
-}
-
-void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
-{
-	TRACE("(*)");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->ortho(left, right, bottom, top, zNear, zFar);
-	}
-}
-
-void APIENTRY glPassThrough(GLfloat token)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPixelStoref(GLenum pname, GLfloat param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPixelTransferf(GLenum pname, GLfloat param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPixelTransferi(GLenum pname, GLint param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPointSize(GLfloat size)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPolygonMode(GLenum face, GLenum mode)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPolygonStipple(const GLubyte *mask)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPopAttrib(void)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPopClientAttrib(void)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPopMatrix(void)
-{
-	TRACE("()");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			return context->listCommand(gl::newCommand(glPopMatrix));
-		}
-
-		context->popMatrix();
-	}
-}
-
-void APIENTRY glPopName(void)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPushAttrib(GLbitfield mask)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPushClientAttrib(GLbitfield mask)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glPushMatrix(void)
-{
-	TRACE("()");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			return context->listCommand(gl::newCommand(glPushMatrix));
-		}
-
-		context->pushMatrix();
-	}
-}
-
-void APIENTRY glPushName(GLuint name)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos2d(GLdouble x, GLdouble y)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos2dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos2f(GLfloat x, GLfloat y)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos2fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos2i(GLint x, GLint y)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos2iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos2s(GLshort x, GLshort y)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos2sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos3dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos3fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos3i(GLint x, GLint y, GLint z)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos3iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos3sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos4dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos4fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos4iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRasterPos4sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glReadBuffer(GLenum mode)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRectiv(const GLint *v1, const GLint *v2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRectsv(const GLshort *v1, const GLshort *v2)
-{
-	UNIMPLEMENTED();
-}
-
-GLint APIENTRY glRenderMode(GLenum mode)
-{
-	UNIMPLEMENTED();
-	return 0;
-}
-
-void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
-{
-	TRACE("(*)");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->rotate(angle, x, y, z);
-	}
-}
-
-void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
-{
-	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			return context->listCommand(gl::newCommand(glScalef, x, y, z));
-		}
-
-		context->scale(x, y, z);
-	}
-}
-
-void APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glShadeModel(GLenum mode)
-{
-	TRACE("(*)");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->setShadeModel(mode);
-	}
-}
-
-void APIENTRY glTexCoord1d(GLdouble s)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord1dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord1f(GLfloat s)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord1fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord1i(GLint s)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord1iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord1s(GLshort s)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord1sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord2d(GLdouble s, GLdouble t)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord2dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord2f(GLfloat s, GLfloat t)
-{
-	TRACE("(GLfloat s = %f, GLfloat t = %f)", s, t);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		//context->texCoord(s, t, 0.0f, 1.0f);
-		unsigned int texture = context->getActiveTexture();
-		context->setVertexAttrib(sw::TexCoord0/* + texture*/, s, t, 0.0f, 1.0f);
-	}
-}
-
-void APIENTRY glTexCoord2fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord2i(GLint s, GLint t)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord2iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord2s(GLshort s, GLshort t)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord2sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord3dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord3fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord3i(GLint s, GLint t, GLint r)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord3iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord3sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord4dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord4fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord4iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoord4sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
-{
-	TRACE("(*)");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		GLenum texture = context->getClientActiveTexture();
-
-		glVertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
-	}
-}
-
-void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)
-{
-	TRACE("(*)");
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			return context->listCommand(gl::newCommand(glTranslated, x, y, z));
-		}
-
-		context->translate(x, y, z);   // FIXME
-	}
-}
-
-void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
-{
-	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			return context->listCommand(gl::newCommand(glTranslatef, x, y, z));
-		}
-
-		context->translate(x, y, z);
-	}
-}
-
-void APIENTRY glVertex2d(GLdouble x, GLdouble y)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex2dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex2f(GLfloat x, GLfloat y)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex2fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex2i(GLint x, GLint y)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex2iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex2s(GLshort x, GLshort y)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex2sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex3dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
-{
-	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		context->position(x, y, z, 1.0f);
-	}
-}
-
-void APIENTRY glVertex3fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex3i(GLint x, GLint y, GLint z)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex3iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex3sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex4dv(const GLdouble *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex4fv(const GLfloat *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex4iv(const GLint *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertex4sv(const GLshort *v)
-{
-	UNIMPLEMENTED();
-}
-
-void APIENTRY glVertexPointer(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);
-
-	glVertexAttribPointer(sw::Position, size, type, false, stride, pointer);
-}
-
-void APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) {UNIMPLEMENTED();}
-void APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}
-void APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}
-void APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
-
-void APIENTRY glClientActiveTexture(GLenum texture)
-{
-	TRACE("(GLenum texture = 0x%X)", texture);
-
-	switch(texture)
-	{
-	case GL_TEXTURE0:
-	case GL_TEXTURE1:
-		break;
-	default:
-		UNIMPLEMENTED();
-		UNREACHABLE(texture);
-	}
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		context->clientActiveTexture(texture);
-	}
-}
-
-void APIENTRY glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
-void APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
-void APIENTRY glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
-void APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
-void APIENTRY glGetCompressedTexImage(GLenum target, GLint level, void *img) {UNIMPLEMENTED();}
-void APIENTRY glMultiTexCoord1f(GLenum target, GLfloat s) {UNIMPLEMENTED();}
-void APIENTRY glMultiTexCoord1d(GLenum target, GLdouble s) {UNIMPLEMENTED();}
-
-void APIENTRY glMultiTexCoord2f(GLenum texture, GLfloat s, GLfloat t)
-{
-	TRACE("(GLenum texture = 0x%X, GLfloat s = %f, GLfloat t = %f)", texture, s, t);
-
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		if(context->getListIndex() != 0)
-		{
-			UNIMPLEMENTED();
-		}
-
-		//context->texCoord(s, t, 0.0f, 1.0f);
-		context->setVertexAttrib(sw::TexCoord0 + (texture - GL_TEXTURE0), s, t, 0.0f, 1.0f);
-	}
-}
-
-void APIENTRY glMultiTexCoord2d(GLenum target, GLdouble s, GLdouble t) {UNIMPLEMENTED();}
-void APIENTRY glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {UNIMPLEMENTED();}
-void APIENTRY glMultiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r) {UNIMPLEMENTED();}
-void APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {UNIMPLEMENTED();}
-void APIENTRY glMultiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) {UNIMPLEMENTED();}
-void APIENTRY glLoadTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
-void APIENTRY glLoadTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
-void APIENTRY glMultTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
-void APIENTRY glMultTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
-void APIENTRY glFogCoordf(GLfloat coord) {UNIMPLEMENTED();}
-void APIENTRY glFogCoordd(GLdouble coord) {UNIMPLEMENTED();}
-void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
-void APIENTRY glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) {UNIMPLEMENTED();}
-void APIENTRY glPointParameteri(GLenum pname, GLint param) {UNIMPLEMENTED();}
-void APIENTRY glPointParameterf(GLenum pname, GLfloat param) {UNIMPLEMENTED();}
-void APIENTRY glPointParameteriv(GLenum pname, const GLint *params) {UNIMPLEMENTED();}
-void APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params) {UNIMPLEMENTED();}
-void APIENTRY glSecondaryColor3b(GLbyte red, GLbyte green, GLbyte blue) {UNIMPLEMENTED();}
-void APIENTRY glSecondaryColor3f(GLfloat red, GLfloat green, GLfloat blue) {UNIMPLEMENTED();}
-void APIENTRY glSecondaryColor3d(GLdouble red, GLdouble green, GLdouble blue) {UNIMPLEMENTED();}
-void APIENTRY glSecondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue) {UNIMPLEMENTED();}
-void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
-void APIENTRY glWindowPos2f(GLfloat x, GLfloat y) {UNIMPLEMENTED();}
-void APIENTRY glWindowPos2d(GLdouble x, GLdouble y) {UNIMPLEMENTED();}
-void APIENTRY glWindowPos2i(GLint x, GLint y) {UNIMPLEMENTED();}
-void APIENTRY glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) {UNIMPLEMENTED();}
-void APIENTRY glWindowPos3d(GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
-void APIENTRY glWindowPos3i(GLint x, GLint y, GLint z) {UNIMPLEMENTED();}
-void APIENTRY glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data) {UNIMPLEMENTED();}
-void *APIENTRY glMapBuffer(GLenum target, GLenum access) {UNIMPLEMENTED(); return 0;}
-GLboolean APIENTRY glUnmapBuffer(GLenum target) {UNIMPLEMENTED(); return GL_FALSE;}
-void APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params) {UNIMPLEMENTED();}
-void APIENTRY glGenQueries(GLsizei n, GLuint *ids) {UNIMPLEMENTED();}
-void APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids) {UNIMPLEMENTED();}
-GLboolean APIENTRY glIsQuery(GLuint id) {UNIMPLEMENTED(); return 0;}
-void APIENTRY glBeginQuery(GLenum target, GLuint id) {UNIMPLEMENTED();}
-void APIENTRY glEndQuery(GLenum target) {UNIMPLEMENTED();}
-void APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params) {UNIMPLEMENTED();}
-void APIENTRY glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) {UNIMPLEMENTED();}
-void APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) {UNIMPLEMENTED();}
-void APIENTRY glVertexAttrib1s(GLuint index, GLshort x) {UNIMPLEMENTED();}
-void APIENTRY glVertexAttrib1d(GLuint index, GLdouble x) {UNIMPLEMENTED();}
-void APIENTRY glVertexAttrib2s(GLuint index, GLshort x, GLshort y) {UNIMPLEMENTED();}
-void APIENTRY glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y) {UNIMPLEMENTED();}
-void APIENTRY glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z) {UNIMPLEMENTED();}
-void APIENTRY glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
-void APIENTRY glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) {UNIMPLEMENTED();}
-void APIENTRY glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {UNIMPLEMENTED();}
-void APIENTRY glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {UNIMPLEMENTED();}
-void APIENTRY glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {UNIMPLEMENTED();}
-void APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs) {UNIMPLEMENTED();}
-void APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
-void APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
-void APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
-void APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
-void APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
-void APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
-
-void APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {UNIMPLEMENTED();}
-void APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
-void APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {UNIMPLEMENTED();}
-
-BOOL WINAPI wglSwapIntervalEXT(int interval)
-{
-	gl::Surface *drawSurface = static_cast<gl::Surface*>(gl::getCurrentDrawSurface());
-
-	if(drawSurface)
-	{
-		drawSurface->setSwapInterval(interval);
-		return TRUE;
-	}
-
-	SetLastError(ERROR_DC_NOT_FOUND);
-	return FALSE;
-}
-
-int WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)
-{
-	TRACE("(*)");
-
-	return 1;
-}
-
-BOOL WINAPI wglCopyContext(HGLRC, HGLRC, UINT)
-{
-	UNIMPLEMENTED();
-	return FALSE;
-}
-
-HGLRC WINAPI wglCreateContext(HDC hdc)
-{
-	TRACE("(*)");
-
-	gl::Display *display = gl::Display::getDisplay(hdc);
-	display->initialize();
-
-	gl::Context *context = display->createContext(nullptr);
-
-	return (HGLRC)context;
-}
-
-HGLRC WINAPI wglCreateLayerContext(HDC, int)
-{
-	UNIMPLEMENTED();
-	return 0;
-}
-
-BOOL WINAPI wglDeleteContext(HGLRC context)
-{
-	gl::Display *display = gl::getDisplay();
-
-	if(display && context)
-	{
-		display->destroyContext(reinterpret_cast<gl::Context*>(context));
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-BOOL WINAPI wglDescribeLayerPlane(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR)
-{
-	UNIMPLEMENTED();
-	return FALSE;
-}
-
-int WINAPI wglDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
-{
-	TRACE("(*)");
-
-	ASSERT(nBytes == sizeof(PIXELFORMATDESCRIPTOR));   // FIXME
-
-	ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
-	ppfd->nVersion = 1;
-	ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
-	ppfd->iPixelType = PFD_TYPE_RGBA;
-	ppfd->cColorBits = 32;
-	ppfd->cRedBits = 8;
-	ppfd->cRedShift = 16;
-	ppfd->cGreenBits = 8;
-	ppfd->cGreenShift = 8;
-	ppfd->cBlueBits = 8;
-	ppfd->cBlueShift = 0;
-	ppfd->cAlphaBits = 0;
-	ppfd->cAlphaShift = 24;
-	ppfd->cAccumBits = 0;
-	ppfd->cAccumRedBits = 0;
-	ppfd->cAccumGreenBits = 0;
-	ppfd->cAccumBlueBits = 0;
-	ppfd->cAccumAlphaBits = 0;
-	ppfd->cDepthBits = 24;
-	ppfd->cStencilBits = 0;
-	ppfd->cAuxBuffers = 0;
-	ppfd->iLayerType = 0;
-	ppfd->bReserved = 0;
-	ppfd->dwLayerMask = 0;
-	ppfd->dwVisibleMask = 0;
-	ppfd->dwDamageMask = 0;
-
-	return 1;
-}
-
-HGLRC WINAPI wglGetCurrentContext(VOID)
-{
-	TRACE("(*)");
-	return (HGLRC)gl::getContext();
-}
-
-HDC WINAPI wglGetCurrentDC(VOID)
-{
-	TRACE("(*)");
-	gl::Display *display = gl::getDisplay();
-	return display ? display->getNativeDisplay() : 0;
-}
-
-void WINAPI wglGetDefaultProcAddress()
-{
-	UNIMPLEMENTED();
-}
-
-int WINAPI wglGetLayerPaletteEntries(HDC, int, int, int, COLORREF*)
-{
-	UNIMPLEMENTED();
-	return 0;
-}
-
-void WINAPI wglGetPixelFormat()
-{
-	UNIMPLEMENTED();
-}
-
-const char *WINAPI wglGetExtensionsStringARB(HDC hdc)
-{
-	TRACE("(*)");
-
-	return "GL_ARB_framebuffer_object "
-	       "WGL_EXT_extensions_string "
-	       "WGL_EXT_swap_control";
-}
-
-const char *WINAPI wglGetExtensionsStringEXT()
-{
-	TRACE("(*)");
-	return wglGetExtensionsStringARB(0);
-}
-
-PROC WINAPI wglGetProcAddress(LPCSTR lpszProc)
-{
-	TRACE("(LPCSTR lpszProc = \"%s\")", lpszProc);
-
-	struct Extension
-	{
-		const char *name;
-		PROC address;
-	};
-
-	static const Extension glExtensions[] =
-	{
-		#define EXT(function) {#function, (PROC)function}
-
-		// Core 2.1
-		EXT(glDrawRangeElements),
-		EXT(glTexImage3D),
-		EXT(glTexSubImage3D),
-		EXT(glCopyTexSubImage3D),
-		EXT(glActiveTexture),
-		EXT(glClientActiveTexture),
-		EXT(glCompressedTexImage1D),
-		EXT(glCompressedTexImage2D),
-		EXT(glCompressedTexImage3D),
-		EXT(glCompressedTexSubImage1D),
-		EXT(glCompressedTexSubImage2D),
-		EXT(glCompressedTexSubImage3D),
-		EXT(glGetCompressedTexImage),
-		EXT(glMultiTexCoord1f),
-		EXT(glMultiTexCoord1d),
-		EXT(glMultiTexCoord2f),
-		EXT(glMultiTexCoord2d),
-		EXT(glMultiTexCoord3f),
-		EXT(glMultiTexCoord3d),
-		EXT(glMultiTexCoord4f),
-		EXT(glMultiTexCoord4d),
-		EXT(glLoadTransposeMatrixf),
-		EXT(glLoadTransposeMatrixd),
-		EXT(glMultTransposeMatrixf),
-		EXT(glMultTransposeMatrixd),
-		EXT(glSampleCoverage),
-		EXT(glBlendEquation),
-		EXT(glBlendColor),
-		EXT(glFogCoordf),
-		EXT(glFogCoordd),
-		EXT(glFogCoordPointer),
-		EXT(glMultiDrawArrays),
-		EXT(glPointParameteri),
-		EXT(glPointParameterf),
-		EXT(glPointParameteriv),
-		EXT(glPointParameterfv),
-		EXT(glSecondaryColor3b),
-		EXT(glSecondaryColor3f),
-		EXT(glSecondaryColor3d),
-		EXT(glSecondaryColor3ub),
-		EXT(glSecondaryColorPointer),
-		EXT(glBlendFuncSeparate),
-		EXT(glWindowPos2f),
-		EXT(glWindowPos2d),
-		EXT(glWindowPos2i),
-		EXT(glWindowPos3f),
-		EXT(glWindowPos3d),
-		EXT(glWindowPos3i),
-		EXT(glBindBuffer),
-		EXT(glDeleteBuffers),
-		EXT(glGenBuffers),
-		EXT(glIsBuffer),
-		EXT(glBufferData),
-		EXT(glBufferSubData),
-		EXT(glGetBufferSubData),
-		EXT(glMapBuffer),
-		EXT(glUnmapBuffer),
-		EXT(glGetBufferParameteriv),
-		EXT(glGetBufferPointerv),
-		EXT(glGenQueries),
-		EXT(glDeleteQueries),
-		EXT(glIsQuery),
-		EXT(glBeginQuery),
-		EXT(glEndQuery),
-		EXT(glGetQueryiv),
-		EXT(glGetQueryObjectiv),
-		EXT(glGetQueryObjectuiv),
-		EXT(glShaderSource),
-		EXT(glCreateShader),
-		EXT(glIsShader),
-		EXT(glCompileShader),
-		EXT(glDeleteShader),
-		EXT(glCreateProgram),
-		EXT(glIsProgram),
-		EXT(glAttachShader),
-		EXT(glDetachShader),
-		EXT(glLinkProgram),
-		EXT(glUseProgram),
-		EXT(glValidateProgram),
-		EXT(glDeleteProgram),
-		EXT(glUniform1f),
-		EXT(glUniform2f),
-		EXT(glUniform3f),
-		EXT(glUniform4f),
-		EXT(glUniform1i),
-		EXT(glUniform2i),
-		EXT(glUniform3i),
-		EXT(glUniform4i),
-		EXT(glUniform1fv),
-		EXT(glUniform2fv),
-		EXT(glUniform3fv),
-		EXT(glUniform4fv),
-		EXT(glUniform1iv),
-		EXT(glUniform2iv),
-		EXT(glUniform3iv),
-		EXT(glUniform4iv),
-		EXT(glUniformMatrix2fv),
-		EXT(glUniformMatrix3fv),
-		EXT(glUniformMatrix4fv),
-		EXT(glGetShaderiv),
-		EXT(glGetProgramiv),
-		EXT(glGetShaderInfoLog),
-		EXT(glGetProgramInfoLog),
-		EXT(glGetAttachedShaders),
-		EXT(glGetUniformLocation),
-		EXT(glGetActiveUniform),
-		EXT(glGetUniformfv),
-		EXT(glGetUniformiv),
-		EXT(glGetShaderSource),
-		EXT(glVertexAttrib1s),
-		EXT(glVertexAttrib1f),
-		EXT(glVertexAttrib1d),
-		EXT(glVertexAttrib2s),
-		EXT(glVertexAttrib2f),
-		EXT(glVertexAttrib2d),
-		EXT(glVertexAttrib3s),
-		EXT(glVertexAttrib3f),
-		EXT(glVertexAttrib3d),
-		EXT(glVertexAttrib4s),
-		EXT(glVertexAttrib4f),
-		EXT(glVertexAttrib4d),
-		EXT(glVertexAttrib4Nub),
-		EXT(glVertexAttribPointer),
-		EXT(glEnableVertexAttribArray),
-		EXT(glDisableVertexAttribArray),
-		EXT(glGetVertexAttribfv),
-		EXT(glGetVertexAttribdv),
-		EXT(glGetVertexAttribiv),
-		EXT(glGetVertexAttribPointerv),
-		EXT(glBindAttribLocation),
-		EXT(glGetActiveAttrib),
-		EXT(glGetAttribLocation),
-		EXT(glDrawBuffers),
-		EXT(glStencilOpSeparate),
-		EXT(glStencilFuncSeparate),
-		EXT(glStencilMaskSeparate),
-		EXT(glBlendEquationSeparate),
-		EXT(glUniformMatrix2x3fv),
-		EXT(glUniformMatrix3x2fv),
-		EXT(glUniformMatrix2x4fv),
-		EXT(glUniformMatrix4x2fv),
-		EXT(glUniformMatrix3x4fv),
-		EXT(glUniformMatrix4x3fv),
-		EXT(glGenFencesNV),
-		EXT(glDeleteFencesNV),
-		EXT(glSetFenceNV),
-		EXT(glTestFenceNV),
-		EXT(glFinishFenceNV),
-		EXT(glIsFenceNV),
-		EXT(glGetFenceivNV),
-
-		EXT(glIsRenderbuffer),
-		EXT(glBindRenderbuffer),
-		EXT(glDeleteRenderbuffers),
-		EXT(glGenRenderbuffers),
-		EXT(glRenderbufferStorage),
-		EXT(glGetRenderbufferParameteriv),
-		EXT(glIsFramebuffer),
-		EXT(glBindFramebuffer),
-		EXT(glDeleteFramebuffers),
-		EXT(glGenFramebuffers),
-		EXT(glCheckFramebufferStatus),
-		EXT(glFramebufferTexture1D),
-		EXT(glFramebufferTexture2D),
-		EXT(glFramebufferTexture3D),
-		EXT(glFramebufferRenderbuffer),
-		EXT(glGetFramebufferAttachmentParameteriv),
-		EXT(glGenerateMipmap),
-		EXT(glReleaseShaderCompiler),
-		EXT(glShaderBinary),
-		EXT(glGetShaderPrecisionFormat),
-		EXT(glDepthRangef),
-		EXT(glClearDepthf),
-
-		// ARB
-		EXT(wglGetExtensionsStringARB),
-		EXT(glIsRenderbuffer),
-		EXT(glBindRenderbuffer),
-		EXT(glDeleteRenderbuffers),
-		EXT(glGenRenderbuffers),
-		EXT(glRenderbufferStorage),
-		EXT(glRenderbufferStorageMultisample),
-		EXT(glGetRenderbufferParameteriv),
-		EXT(glIsFramebuffer),
-		EXT(glBindFramebuffer),
-		EXT(glDeleteFramebuffers),
-		EXT(glGenFramebuffers),
-		EXT(glCheckFramebufferStatus),
-		EXT(glFramebufferTexture1D),
-		EXT(glFramebufferTexture2D),
-		EXT(glFramebufferTexture3D),
-		EXT(glFramebufferTextureLayer),
-		EXT(glFramebufferRenderbuffer),
-		EXT(glGetFramebufferAttachmentParameteriv),
-		EXT(glBlitFramebuffer),
-		EXT(glGenerateMipmap),
-
-		// EXT
-		EXT(wglSwapIntervalEXT),
-		EXT(wglGetExtensionsStringEXT),
-		#undef EXT
-	};
-
-	for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
-	{
-		if(strcmp(lpszProc, glExtensions[ext].name) == 0)
-		{
-			return (PROC)glExtensions[ext].address;
-		}
-	}
-
-	FARPROC proc = GetProcAddress(GetModuleHandle("opengl32.dll"), lpszProc);  // FIXME?
-
-	if(proc)
-	{
-		return proc;
-	}
-
-	TRACE("(LPCSTR lpszProc = \"%s\") NOT FOUND!!!", lpszProc);
-
-	return 0;
-}
-
-BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
-{
-	TRACE("(*)");
-
-	if(hdc && hglrc)
-	{
-		gl::Display *display = (gl::Display*)gl::Display::getDisplay(hdc);
-		gl::makeCurrent((gl::Context*)hglrc, display, display->getPrimarySurface());
-		gl::setCurrentDrawSurface(display->getPrimarySurface());
-		gl::setCurrentDisplay(display);
-	}
-	else
-	{
-		gl::makeCurrent(0, 0, 0);
-	}
-
-	return TRUE;
-}
-
-BOOL WINAPI wglRealizeLayerPalette(HDC, int, BOOL)
-{
-	UNIMPLEMENTED();
-	return FALSE;
-}
-
-int WINAPI wglSetLayerPaletteEntries(HDC, int, int, int, CONST COLORREF*)
-{
-	UNIMPLEMENTED();
-	return 0;
-}
-
-BOOL WINAPI wglSetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
-{
-	TRACE("(*)");
-	//UNIMPLEMENTED();
-
-	return TRUE;
-}
-
-BOOL WINAPI wglShareLists(HGLRC, HGLRC)
-{
-	UNIMPLEMENTED();
-	return FALSE;
-}
-
-BOOL WINAPI wglSwapBuffers(HDC hdc)
-{
-	TRACE("(*)");
-
-	gl::Display *display = gl::getDisplay();
-
-	if(display)
-	{
-		display->getPrimarySurface()->swap();
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-BOOL WINAPI wglSwapLayerBuffers(HDC, UINT)
-{
-	UNIMPLEMENTED();
-	return FALSE;
-}
-
-DWORD WINAPI wglSwapMultipleBuffers(UINT, CONST WGLSWAP*)
-{
-	UNIMPLEMENTED();
-	return 0;
-}
-
-BOOL WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD)
-{
-	UNIMPLEMENTED();
-	return FALSE;
-}
-
-BOOL WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD)
-{
-	UNIMPLEMENTED();
-	return FALSE;
-}
-
-BOOL WINAPI wglUseFontOutlinesA(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
-{
-	UNIMPLEMENTED();
-	return FALSE;
-}
-
-BOOL WINAPI wglUseFontOutlinesW(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
-{
-	UNIMPLEMENTED();
-	return FALSE;
-}
-
-}
diff --git a/src/OpenGL/libGL/libGL.def b/src/OpenGL/libGL/libGL.def
deleted file mode 100644
index 3b1ba1a..0000000
--- a/src/OpenGL/libGL/libGL.def
+++ /dev/null
@@ -1,370 +0,0 @@
-LIBRARY opengl32
-EXPORTS
-	GlmfBeginGlsBlock	@1
-	GlmfCloseMetaFile	@2
-	GlmfEndGlsBlock	@3
-	GlmfEndPlayback	@4
-	GlmfInitPlayback	@5
-	GlmfPlayGlsRecord	@6
-	glAccum	@7
-	glAlphaFunc	@8
-	glAreTexturesResident	@9
-	glArrayElement	@10
-	glBegin	@11
-	glBindTexture	@12
-	glBitmap	@13
-	glBlendFunc	@14
-	glCallList	@15
-	glCallLists	@16
-	glClear	@17
-	glClearAccum	@18
-	glClearColor	@19
-	glClearDepth	@20
-	glClearIndex	@21
-	glClearStencil	@22
-	glClipPlane	@23
-	glColor3b	@24
-	glColor3bv	@25
-	glColor3d	@26
-	glColor3dv	@27
-	glColor3f	@28
-	glColor3fv	@29
-	glColor3i	@30
-	glColor3iv	@31
-	glColor3s	@32
-	glColor3sv	@33
-	glColor3ub	@34
-	glColor3ubv	@35
-	glColor3ui	@36
-	glColor3uiv	@37
-	glColor3us	@38
-	glColor3usv	@39
-	glColor4b	@40
-	glColor4bv	@41
-	glColor4d	@42
-	glColor4dv	@43
-	glColor4f	@44
-	glColor4fv	@45
-	glColor4i	@46
-	glColor4iv	@47
-	glColor4s	@48
-	glColor4sv	@49
-	glColor4ub	@50
-	glColor4ubv	@51
-	glColor4ui	@52
-	glColor4uiv	@53
-	glColor4us	@54
-	glColor4usv	@55
-	glColorMask	@56
-	glColorMaterial	@57
-	glColorPointer	@58
-	glCopyPixels	@59
-	glCopyTexImage1D	@60
-	glCopyTexImage2D	@61
-	glCopyTexSubImage1D	@62
-	glCopyTexSubImage2D	@63
-	glCullFace	@64
-	glDebugEntry	@65
-	glDeleteLists	@66
-	glDeleteTextures	@67
-	glDepthFunc	@68
-	glDepthMask	@69
-	glDepthRange	@70
-	glDisable	@71
-	glDisableClientState	@72
-	glDrawArrays	@73
-	glDrawBuffer	@74
-	glDrawElements	@75
-	glDrawPixels	@76
-	glEdgeFlag	@77
-	glEdgeFlagPointer	@78
-	glEdgeFlagv	@79
-	glEnable	@80
-	glEnableClientState	@81
-	glEnd	@82
-	glEndList	@83
-	glEvalCoord1d	@84
-	glEvalCoord1dv	@85
-	glEvalCoord1f	@86
-	glEvalCoord1fv	@87
-	glEvalCoord2d	@88
-	glEvalCoord2dv	@89
-	glEvalCoord2f	@90
-	glEvalCoord2fv	@91
-	glEvalMesh1	@92
-	glEvalMesh2	@93
-	glEvalPoint1	@94
-	glEvalPoint2	@95
-	glFeedbackBuffer	@96
-	glFinish	@97
-	glFlush	@98
-	glFogf	@99
-	glFogfv	@100
-	glFogi	@101
-	glFogiv	@102
-	glFrontFace	@103
-	glFrustum	@104
-	glGenLists	@105
-	glGenTextures	@106
-	glGetBooleanv	@107
-	glGetClipPlane	@108
-	glGetDoublev	@109
-	glGetError	@110
-	glGetFloatv	@111
-	glGetIntegerv	@112
-	glGetLightfv	@113
-	glGetLightiv	@114
-	glGetMapdv	@115
-	glGetMapfv	@116
-	glGetMapiv	@117
-	glGetMaterialfv	@118
-	glGetMaterialiv	@119
-	glGetPixelMapfv	@120
-	glGetPixelMapuiv	@121
-	glGetPixelMapusv	@122
-	glGetPointerv	@123
-	glGetPolygonStipple	@124
-	glGetString	@125
-	glGetTexEnvfv	@126
-	glGetTexEnviv	@127
-	glGetTexGendv	@128
-	glGetTexGenfv	@129
-	glGetTexGeniv	@130
-	glGetTexImage	@131
-	glGetTexLevelParameterfv	@132
-	glGetTexLevelParameteriv	@133
-	glGetTexParameterfv	@134
-	glGetTexParameteriv	@135
-	glHint	@136
-	glIndexMask	@137
-	glIndexPointer	@138
-	glIndexd	@139
-	glIndexdv	@140
-	glIndexf	@141
-	glIndexfv	@142
-	glIndexi	@143
-	glIndexiv	@144
-	glIndexs	@145
-	glIndexsv	@146
-	glIndexub	@147
-	glIndexubv	@148
-	glInitNames	@149
-	glInterleavedArrays	@150
-	glIsEnabled	@151
-	glIsList	@152
-	glIsTexture	@153
-	glLightModelf	@154
-	glLightModelfv	@155
-	glLightModeli	@156
-	glLightModeliv	@157
-	glLightf	@158
-	glLightfv	@159
-	glLighti	@160
-	glLightiv	@161
-	glLineStipple	@162
-	glLineWidth	@163
-	glListBase	@164
-	glLoadIdentity	@165
-	glLoadMatrixd	@166
-	glLoadMatrixf	@167
-	glLoadName	@168
-	glLogicOp	@169
-	glMap1d	@170
-	glMap1f	@171
-	glMap2d	@172
-	glMap2f	@173
-	glMapGrid1d	@174
-	glMapGrid1f	@175
-	glMapGrid2d	@176
-	glMapGrid2f	@177
-	glMaterialf	@178
-	glMaterialfv	@179
-	glMateriali	@180
-	glMaterialiv	@181
-	glMatrixMode	@182
-	glMultMatrixd	@183
-	glMultMatrixf	@184
-	glNewList	@185
-	glNormal3b	@186
-	glNormal3bv	@187
-	glNormal3d	@188
-	glNormal3dv	@189
-	glNormal3f	@190
-	glNormal3fv	@191
-	glNormal3i	@192
-	glNormal3iv	@193
-	glNormal3s	@194
-	glNormal3sv	@195
-	glNormalPointer	@196
-	glOrtho	@197
-	glPassThrough	@198
-	glPixelMapfv	@199
-	glPixelMapuiv	@200
-	glPixelMapusv	@201
-	glPixelStoref	@202
-	glPixelStorei	@203
-	glPixelTransferf	@204
-	glPixelTransferi	@205
-	glPixelZoom	@206
-	glPointSize	@207
-	glPolygonMode	@208
-	glPolygonOffset	@209
-	glPolygonStipple	@210
-	glPopAttrib	@211
-	glPopClientAttrib	@212
-	glPopMatrix	@213
-	glPopName	@214
-	glPrioritizeTextures	@215
-	glPushAttrib	@216
-	glPushClientAttrib	@217
-	glPushMatrix	@218
-	glPushName	@219
-	glRasterPos2d	@220
-	glRasterPos2dv	@221
-	glRasterPos2f	@222
-	glRasterPos2fv	@223
-	glRasterPos2i	@224
-	glRasterPos2iv	@225
-	glRasterPos2s	@226
-	glRasterPos2sv	@227
-	glRasterPos3d	@228
-	glRasterPos3dv	@229
-	glRasterPos3f	@230
-	glRasterPos3fv	@231
-	glRasterPos3i	@232
-	glRasterPos3iv	@233
-	glRasterPos3s	@234
-	glRasterPos3sv	@235
-	glRasterPos4d	@236
-	glRasterPos4dv	@237
-	glRasterPos4f	@238
-	glRasterPos4fv	@239
-	glRasterPos4i	@240
-	glRasterPos4iv	@241
-	glRasterPos4s	@242
-	glRasterPos4sv	@243
-	glReadBuffer	@244
-	glReadPixels	@245
-	glRectd	@246
-	glRectdv	@247
-	glRectf	@248
-	glRectfv	@249
-	glRecti	@250
-	glRectiv	@251
-	glRects	@252
-	glRectsv	@253
-	glRenderMode	@254
-	glRotated	@255
-	glRotatef	@256
-	glScaled	@257
-	glScalef	@258
-	glScissor	@259
-	glSelectBuffer	@260
-	glShadeModel	@261
-	glStencilFunc	@262
-	glStencilMask	@263
-	glStencilOp	@264
-	glTexCoord1d	@265
-	glTexCoord1dv	@266
-	glTexCoord1f	@267
-	glTexCoord1fv	@268
-	glTexCoord1i	@269
-	glTexCoord1iv	@270
-	glTexCoord1s	@271
-	glTexCoord1sv	@272
-	glTexCoord2d	@273
-	glTexCoord2dv	@274
-	glTexCoord2f	@275
-	glTexCoord2fv	@276
-	glTexCoord2i	@277
-	glTexCoord2iv	@278
-	glTexCoord2s	@279
-	glTexCoord2sv	@280
-	glTexCoord3d	@281
-	glTexCoord3dv	@282
-	glTexCoord3f	@283
-	glTexCoord3fv	@284
-	glTexCoord3i	@285
-	glTexCoord3iv	@286
-	glTexCoord3s	@287
-	glTexCoord3sv	@288
-	glTexCoord4d	@289
-	glTexCoord4dv	@290
-	glTexCoord4f	@291
-	glTexCoord4fv	@292
-	glTexCoord4i	@293
-	glTexCoord4iv	@294
-	glTexCoord4s	@295
-	glTexCoord4sv	@296
-	glTexCoordPointer	@297
-	glTexEnvf	@298
-	glTexEnvfv	@299
-	glTexEnvi	@300
-	glTexEnviv	@301
-	glTexGend	@302
-	glTexGendv	@303
-	glTexGenf	@304
-	glTexGenfv	@305
-	glTexGeni	@306
-	glTexGeniv	@307
-	glTexImage1D	@308
-	glTexImage2D	@309
-	glTexParameterf	@310
-	glTexParameterfv	@311
-	glTexParameteri	@312
-	glTexParameteriv	@313
-	glTexSubImage1D	@314
-	glTexSubImage2D	@315
-	glTranslated	@316
-	glTranslatef	@317
-	glVertex2d	@318
-	glVertex2dv	@319
-	glVertex2f	@320
-	glVertex2fv	@321
-	glVertex2i	@322
-	glVertex2iv	@323
-	glVertex2s	@324
-	glVertex2sv	@325
-	glVertex3d	@326
-	glVertex3dv	@327
-	glVertex3f	@328
-	glVertex3fv	@329
-	glVertex3i	@330
-	glVertex3iv	@331
-	glVertex3s	@332
-	glVertex3sv	@333
-	glVertex4d	@334
-	glVertex4dv	@335
-	glVertex4f	@336
-	glVertex4fv	@337
-	glVertex4i	@338
-	glVertex4iv	@339
-	glVertex4s	@340
-	glVertex4sv	@341
-	glVertexPointer	@342
-	glViewport	@343
-	wglChoosePixelFormat	@344
-	wglCopyContext	@345
-	wglCreateContext	@346
-	wglCreateLayerContext	@347
-	wglDeleteContext	@348
-	wglDescribeLayerPlane	@349
-	wglDescribePixelFormat	@350
-	wglGetCurrentContext	@351
-	wglGetCurrentDC	@352
-	wglGetDefaultProcAddress	@353
-	wglGetLayerPaletteEntries	@354
-	wglGetPixelFormat	@355
-	wglGetProcAddress	@356
-	wglMakeCurrent	@357
-	wglRealizeLayerPalette	@358
-	wglSetLayerPaletteEntries	@359
-	wglSetPixelFormat	@360
-	wglShareLists	@361
-	wglSwapBuffers	@362
-	wglSwapLayerBuffers	@363
-	wglSwapMultipleBuffers	@364
-	wglUseFontBitmapsA	@365
-	wglUseFontBitmapsW	@366
-	wglUseFontOutlinesA	@367
-	wglUseFontOutlinesW	@368
diff --git a/src/OpenGL/libGL/libGL.rc b/src/OpenGL/libGL/libGL.rc
deleted file mode 100644
index 2ae08ae..0000000
--- a/src/OpenGL/libGL/libGL.rc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include <windows.h>
-#include "../../Common/Version.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (United States) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE 
-BEGIN
-    "resource.h\0"
-END
-
-2 TEXTINCLUDE 
-BEGIN
-    "#include ""afxres.h""\r\n"
-    "#include ""../Common/Version.h""\0"
-END
-
-3 TEXTINCLUDE 
-BEGIN
-    "\r\n"
-    "\0"
-END
-
-#endif    // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION
- PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION
- FILEFLAGSMASK 0x17L
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x4L
- FILETYPE 0x2L
- FILESUBTYPE 0x0L
-BEGIN
-    BLOCK "StringFileInfo"
-    BEGIN
-        BLOCK "040904b0"
-        BEGIN
-			#ifdef WIN64
-				VALUE "FileDescription", "SwiftShader OpenGL 64-bit Dynamic Link Library"
-			#else
-				VALUE "FileDescription", "SwiftShader OpenGL 32-bit Dynamic Link Library"
-			#endif
-            VALUE "FileVersion", VERSION_STRING
-            VALUE "InternalName", "libGL"
-            VALUE "LegalCopyright", "Copyright (C) 2016 Google Inc."
-            VALUE "OriginalFilename", "opengl32.dll"
-            VALUE "PrivateBuild", VERSION_STRING
-            VALUE "ProductName", "SwiftShader openGL Dynamic Link Library"
-            VALUE "ProductVersion", VERSION_STRING
-        END
-    END
-    BLOCK "VarFileInfo"
-    BEGIN
-        VALUE "Translation", 0x409, 1200
-    END
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-IDD_DIALOG1 DIALOGEX 0, 0, 129, 47
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Waiting for debugger"
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
-    PUSHBUTTON      "Cancel",IDCANCEL,72,26,50,14
-    LTEXT           "Attach a debugger or ESC to cancel",IDC_STATIC,7,7,115,8
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// DESIGNINFO
-//
-
-#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO
-BEGIN
-    IDD_DIALOG1, DIALOG
-    BEGIN
-        LEFTMARGIN, 7
-        RIGHTMARGIN, 122
-        TOPMARGIN, 7
-        BOTTOMMARGIN, 40
-    END
-END
-#endif    // APSTUDIO_INVOKED
-
-#endif    // English (United States) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif    // not APSTUDIO_INVOKED
-
diff --git a/src/OpenGL/libGL/libGL.vcxproj b/src/OpenGL/libGL/libGL.vcxproj
deleted file mode 100644
index c940f25..0000000
--- a/src/OpenGL/libGL/libGL.vcxproj
+++ /dev/null
@@ -1,416 +0,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Profile|Win32">
-      <Configuration>Profile</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Profile|x64">
-      <Configuration>Profile</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{3EF851E7-4AAB-4C7C-9A79-3122CEA1EB67}</ProjectGuid>
-    <RootNamespace>libGL</RootNamespace>
-    <Keyword>Win32Proj</Keyword>
-    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <CharacterSet>NotSet</CharacterSet>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <PlatformToolset>v141</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <CharacterSet>NotSet</CharacterSet>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <PlatformToolset>v141</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <CharacterSet>NotSet</CharacterSet>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <PlatformToolset>v141</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <CharacterSet>NotSet</CharacterSet>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <PlatformToolset>v141</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <CharacterSet>NotSet</CharacterSet>
-    <PlatformToolset>v141</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <CharacterSet>NotSet</CharacterSet>
-    <PlatformToolset>v141</PlatformToolset>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup>
-    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)bin\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</OutDir>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)bin\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)obj\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</IntDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)obj\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)bin\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</OutDir>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)bin\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</OutDir>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(SolutionDir)bin\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</OutDir>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">$(SolutionDir)bin\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)obj\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</IntDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)obj\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</IntDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(SolutionDir)obj\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</IntDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">$(SolutionDir)obj\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">false</LinkIncremental>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">false</LinkIncremental>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\include;$(IncludePath)</IncludePath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\include;$(IncludePath)</IncludePath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(SolutionDir)\include;$(IncludePath)</IncludePath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">$(SolutionDir)\include;$(IncludePath)</IncludePath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\include;$(IncludePath)</IncludePath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\include;$(IncludePath)</IncludePath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(DXSDK_DIR)\Lib\x86;$(VCInstallDir)PlatformSDK\lib;$(LibraryPath)</LibraryPath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(DXSDK_DIR)\Lib\x64;$(VCInstallDir)PlatformSDK\lib;$(LibraryPath)</LibraryPath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(DXSDK_DIR)\Lib\x86;$(VCInstallDir)PlatformSDK\lib;$(LibraryPath)</LibraryPath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">$(DXSDK_DIR)\Lib\x64;$(VCInstallDir)PlatformSDK\lib;$(LibraryPath)</LibraryPath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(DXSDK_DIR)\Lib\x86;$(VCInstallDir)PlatformSDK\lib;$(LibraryPath)</LibraryPath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(DXSDK_DIR)\Lib\x64;$(VCInstallDir)PlatformSDK\lib;$(LibraryPath)</LibraryPath>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
-    <TargetName>opengl32</TargetName>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <TargetName>opengl32</TargetName>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <TargetName>opengl32</TargetName>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">
-    <TargetName>opengl32</TargetName>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <TargetName>opengl32</TargetName>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <TargetName>opengl32</TargetName>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>$(SolutionDir)\src;$(ProjectDir)/..;$(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;GL_API=;GL_GLEXT_PROTOTYPES;_DEBUG;_WINDOWS;_USRDLL;LIBGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <MinimalRebuild>true</MinimalRebuild>
-      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <BrowseInformation>true</BrowseInformation>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <TreatSpecificWarningsAsErrors>4018;5038;4838</TreatSpecificWarningsAsErrors>
-    </ClCompile>
-    <Link>
-      <AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <ModuleDefinitionFile>libGL.def</ModuleDefinitionFile>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Windows</SubSystem>
-      <TargetMachine>MachineX86</TargetMachine>
-    </Link>
-    <PostBuildEvent>
-      <Command>mkdir "$(SolutionDir)out\$(Configuration)_$(Platform)\"
-copy "$(OutDir)opengl32.dll" "$(SolutionDir)out\$(Configuration)_$(Platform)\"</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>$(SolutionDir)\src;$(ProjectDir)/..;$(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;GL_API=;GL_GLEXT_PROTOTYPES;_DEBUG;_WINDOWS;_USRDLL;LIBGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <BrowseInformation>true</BrowseInformation>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <TreatSpecificWarningsAsErrors>4018;5038;4838</TreatSpecificWarningsAsErrors>
-    </ClCompile>
-    <Link>
-      <AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <ModuleDefinitionFile>libGL.def</ModuleDefinitionFile>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Windows</SubSystem>
-    </Link>
-    <PostBuildEvent>
-      <Command>mkdir "$(SolutionDir)out\$(Configuration)_$(Platform)\"
-copy "$(OutDir)opengl32.dll" "$(SolutionDir)out\$(Configuration)_$(Platform)\"</Command>
-    </PostBuildEvent>
-    <ResourceCompile>
-      <PreprocessorDefinitions>WIN64</PreprocessorDefinitions>
-    </ResourceCompile>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <Optimization>Full</Optimization>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <AdditionalIncludeDirectories>$(ProjectDir)/..;$(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;GL_API=;GL_GLEXT_PROTOTYPES;NDEBUG;_WINDOWS;_USRDLL;LIBGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>
-      </DebugInformationFormat>
-      <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <WholeProgramOptimization>true</WholeProgramOptimization>
-      <IntrinsicFunctions>false</IntrinsicFunctions>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <TreatSpecificWarningsAsErrors>4018;5038;4838</TreatSpecificWarningsAsErrors>
-    </ClCompile>
-    <Link>
-      <AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
-      <ModuleDefinitionFile>libGL.def</ModuleDefinitionFile>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Windows</SubSystem>
-      <OptimizeReferences>true</OptimizeReferences>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <TargetMachine>MachineX86</TargetMachine>
-    </Link>
-    <PostBuildEvent>
-      <Command>mkdir "$(SolutionDir)out\$(Configuration)_$(Platform)\"
-copy "$(OutDir)opengl32.dll" "$(SolutionDir)out\$(Configuration)_$(Platform)\"</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <Optimization>Full</Optimization>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <AdditionalIncludeDirectories>$(ProjectDir)/..;$(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;GL_API=;GL_GLEXT_PROTOTYPES;NDEBUG;_WINDOWS;_USRDLL;LIBGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>
-      </DebugInformationFormat>
-      <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <WholeProgramOptimization>true</WholeProgramOptimization>
-      <IntrinsicFunctions>false</IntrinsicFunctions>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <TreatSpecificWarningsAsErrors>4018;5038;4838</TreatSpecificWarningsAsErrors>
-    </ClCompile>
-    <Link>
-      <AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
-      <ModuleDefinitionFile>libGL.def</ModuleDefinitionFile>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Windows</SubSystem>
-      <OptimizeReferences>true</OptimizeReferences>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-    </Link>
-    <PostBuildEvent>
-      <Command>mkdir "$(SolutionDir)out\$(Configuration)_$(Platform)\"
-copy "$(OutDir)opengl32.dll" "$(SolutionDir)out\$(Configuration)_$(Platform)\"</Command>
-    </PostBuildEvent>
-    <ResourceCompile>
-      <PreprocessorDefinitions>WIN64</PreprocessorDefinitions>
-    </ResourceCompile>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
-    <ClCompile>
-      <Optimization>Full</Optimization>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <AdditionalIncludeDirectories>$(ProjectDir)/..; $(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;GL_API=;GL_GLEXT_PROTOTYPES;NDEBUG;_WINDOWS;_USRDLL;LIBGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
-      <OmitFramePointers>false</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <WholeProgramOptimization>true</WholeProgramOptimization>
-      <IntrinsicFunctions>false</IntrinsicFunctions>
-      <TreatSpecificWarningsAsErrors>4018;5038;4838</TreatSpecificWarningsAsErrors>
-    </ClCompile>
-    <Link>
-      <AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
-      <ModuleDefinitionFile>libGL.def</ModuleDefinitionFile>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Windows</SubSystem>
-      <OptimizeReferences>true</OptimizeReferences>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <TargetMachine>MachineX86</TargetMachine>
-    </Link>
-    <PostBuildEvent>
-      <Command>mkdir "$(SolutionDir)out\$(Configuration)_$(Platform)\"
-copy "$(OutDir)opengl32.dll" "$(SolutionDir)out\$(Configuration)_$(Platform)\"</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">
-    <ClCompile>
-      <Optimization>Full</Optimization>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <AdditionalIncludeDirectories>$(ProjectDir)/..; $(ProjectDir)/../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;GL_API=;GL_GLEXT_PROTOTYPES;NDEBUG;_WINDOWS;_USRDLL;LIBGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
-      <OmitFramePointers>false</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <WholeProgramOptimization>true</WholeProgramOptimization>
-      <IntrinsicFunctions>false</IntrinsicFunctions>
-      <TreatSpecificWarningsAsErrors>4018;5038;4838</TreatSpecificWarningsAsErrors>
-    </ClCompile>
-    <Link>
-      <AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
-      <ModuleDefinitionFile>libGL.def</ModuleDefinitionFile>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Windows</SubSystem>
-      <OptimizeReferences>true</OptimizeReferences>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-    </Link>
-    <PostBuildEvent>
-      <Command>mkdir "$(SolutionDir)out\$(Configuration)_$(Platform)\"
-copy "$(OutDir)opengl32.dll" "$(SolutionDir)out\$(Configuration)_$(Platform)\"</Command>
-    </PostBuildEvent>
-    <ResourceCompile>
-      <PreprocessorDefinitions>WIN64</PreprocessorDefinitions>
-    </ResourceCompile>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="..\common\MatrixStack.cpp" />
-    <ClCompile Include="..\common\Object.cpp" />
-    <ClCompile Include="Buffer.cpp" />
-    <ClCompile Include="Context.cpp" />
-    <ClCompile Include="..\common\debug.cpp" />
-    <ClCompile Include="Device.cpp" />
-    <ClCompile Include="Display.cpp" />
-    <ClCompile Include="Fence.cpp" />
-    <ClCompile Include="Framebuffer.cpp" />
-    <ClCompile Include="Image.cpp" />
-    <ClCompile Include="IndexDataManager.cpp" />
-    <ClCompile Include="libGL.cpp" />
-    <ClCompile Include="main.cpp" />
-    <ClCompile Include="Program.cpp" />
-    <ClCompile Include="Query.cpp" />
-    <ClCompile Include="Renderbuffer.cpp" />
-    <ClCompile Include="ResourceManager.cpp" />
-    <ClCompile Include="Shader.cpp" />
-    <ClCompile Include="Surface.cpp" />
-    <ClCompile Include="Texture.cpp" />
-    <ClCompile Include="utilities.cpp" />
-    <ClCompile Include="VertexDataManager.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\common\debug.h" />
-    <ClInclude Include="..\common\MatrixStack.hpp" />
-    <ClInclude Include="..\common\NameSpace.hpp" />
-    <ClInclude Include="..\common\Object.hpp" />
-    <ClInclude Include="..\include\GL\glcorearb.h" />
-    <ClInclude Include="..\include\GL\glext.h" />
-    <ClInclude Include="..\include\GL\glxext.h" />
-    <ClInclude Include="..\include\GL\wglext.h" />
-    <ClInclude Include="Buffer.h" />
-    <ClInclude Include="Context.h" />
-    <ClInclude Include="Device.hpp" />
-    <ClInclude Include="Display.h" />
-    <ClInclude Include="Fence.h" />
-    <ClInclude Include="Framebuffer.h" />
-    <ClInclude Include="Image.hpp" />
-    <ClInclude Include="IndexDataManager.h" />
-    <ClInclude Include="main.h" />
-    <ClInclude Include="mathutil.h" />
-    <ClInclude Include="Program.h" />
-    <ClInclude Include="Query.h" />
-    <ClInclude Include="Renderbuffer.h" />
-    <ClInclude Include="resource.h" />
-    <ClInclude Include="ResourceManager.h" />
-    <ClInclude Include="Shader.h" />
-    <ClInclude Include="Surface.h" />
-    <ClInclude Include="Texture.h" />
-    <ClInclude Include="utilities.h" />
-    <ClInclude Include="VertexDataManager.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="libGL.def" />
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include="libGL.rc" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\SwiftShader\SwiftShader.vcxproj">
-      <Project>{7b02cb19-4cdf-4f79-bc9b-7f3f6164a003}</Project>
-      <Private>true</Private>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-      <UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
-    </ProjectReference>
-    <ProjectReference Include="..\compiler\Compiler.vcxproj">
-      <Project>{5b3a6db8-1e7e-40d7-92b9-da8aae619fad}</Project>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/src/OpenGL/libGL/libGL.vcxproj.filters b/src/OpenGL/libGL/libGL.vcxproj.filters
deleted file mode 100644
index 59d106a..0000000
--- a/src/OpenGL/libGL/libGL.vcxproj.filters
+++ /dev/null
@@ -1,173 +0,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="Buffer.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Context.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\common\debug.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Fence.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Framebuffer.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="IndexDataManager.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="libGL.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="main.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Program.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Renderbuffer.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="ResourceManager.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Shader.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Texture.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="utilities.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="VertexDataManager.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Device.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Image.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Query.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Display.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Surface.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\common\Object.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\common\MatrixStack.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="Buffer.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Context.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Fence.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Framebuffer.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="IndexDataManager.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="main.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="mathutil.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Program.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Renderbuffer.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="resource.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="ResourceManager.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Shader.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Texture.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="utilities.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="VertexDataManager.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Device.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Image.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Query.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\common\debug.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Display.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Surface.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\common\NameSpace.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\include\GL\glcorearb.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\include\GL\glext.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\include\GL\glxext.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\include\GL\wglext.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\common\Object.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\common\MatrixStack.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include="libGL.rc" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="libGL.def" />
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/src/OpenGL/libGL/main.cpp b/src/OpenGL/libGL/main.cpp
deleted file mode 100644
index 5533321..0000000
--- a/src/OpenGL/libGL/main.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-// 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.
-
-// main.cpp: DLL entry point and management of thread-local data.
-
-#include "main.h"
-
-#include "resource.h"
-#include "Framebuffer.h"
-#include "Surface.h"
-#include "Common/Thread.hpp"
-#include "common/debug.h"
-
-static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;
-
-#if !defined(_MSC_VER)
-#define CONSTRUCTOR __attribute__((constructor))
-#define DESTRUCTOR __attribute__((destructor))
-#else
-#define CONSTRUCTOR
-#define DESTRUCTOR
-#endif
-
-static void glAttachThread()
-{
-	TRACE("()");
-
-	gl::Current *current = (gl::Current*)sw::Thread::allocateLocalStorage(currentTLS, sizeof(gl::Current));
-
-	if(current)
-	{
-		current->context = nullptr;
-		current->display = nullptr;
-		current->drawSurface = nullptr;
-		current->readSurface = nullptr;
-	}
-}
-
-static void glDetachThread()
-{
-	TRACE("()");
-
-	wglMakeCurrent(NULL, NULL);
-
-	sw::Thread::freeLocalStorage(currentTLS);
-}
-
-CONSTRUCTOR static bool glAttachProcess()
-{
-	TRACE("()");
-
-	#if !(ANGLE_DISABLE_TRACE)
-		FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
-
-		if(debug)
-		{
-			fclose(debug);
-			debug = fopen(TRACE_OUTPUT_FILE, "wt");   // Erase
-			fclose(debug);
-		}
-	#endif
-
-	currentTLS = sw::Thread::allocateLocalStorageKey();
-
-	if(currentTLS == TLS_OUT_OF_INDEXES)
-	{
-		return false;
-	}
-
-	glAttachThread();
-
-	return true;
-}
-
-DESTRUCTOR static void glDetachProcess()
-{
-	TRACE("()");
-
-	glDetachThread();
-
-	sw::Thread::freeLocalStorageKey(currentTLS);
-}
-
-#if defined(_WIN32)
-static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
-	RECT rect;
-
-	switch(uMsg)
-	{
-	case WM_INITDIALOG:
-		GetWindowRect(GetDesktopWindow(), &rect);
-		SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
-		SetTimer(hwnd, 1, 100, NULL);
-		return TRUE;
-	case WM_COMMAND:
-		if(LOWORD(wParam) == IDCANCEL)
-		{
-			EndDialog(hwnd, 0);
-		}
-		break;
-	case WM_TIMER:
-		if(IsDebuggerPresent())
-		{
-			EndDialog(hwnd, 0);
-		}
-	}
-
-	return FALSE;
-}
-
-static void WaitForDebugger(HINSTANCE instance)
-{
-	if(!IsDebuggerPresent())
-	{
-		HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);
-		DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);
-		DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);
-	}
-}
-
-extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
-{
-	switch(reason)
-	{
-	case DLL_PROCESS_ATTACH:
-		#ifndef NDEBUG
-			WaitForDebugger(instance);
-		#endif
-		return glAttachProcess();
-		break;
-	case DLL_THREAD_ATTACH:
-		glAttachThread();
-		break;
-	case DLL_THREAD_DETACH:
-		glDetachThread();
-		break;
-	case DLL_PROCESS_DETACH:
-		glDetachProcess();
-		break;
-	default:
-		break;
-	}
-
-	return TRUE;
-}
-#endif
-
-namespace gl
-{
-static gl::Current *getCurrent(void)
-{
-	Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
-
-	if(!current)
-	{
-		glAttachThread();
-	}
-
-	return (Current*)sw::Thread::getLocalStorage(currentTLS);
-}
-
-void makeCurrent(Context *context, Display *display, Surface *surface)
-{
-	Current *current = getCurrent();
-
-	current->context = context;
-	current->display = display;
-
-	if(context && display && surface)
-	{
-		context->makeCurrent(surface);
-	}
-}
-
-Context *getContext()
-{
-	Current *current = getCurrent();
-
-	return current->context;
-}
-
-Display *getDisplay()
-{
-	Current *current = getCurrent();
-
-	return current->display;
-}
-
-Device *getDevice()
-{
-	Context *context = getContext();
-
-	return context ? context->getDevice() : nullptr;
-}
-
-void setCurrentDisplay(Display *dpy)
-{
-	Current *current = getCurrent();
-
-	current->display = dpy;
-}
-
-void setCurrentContext(gl::Context *ctx)
-{
-	Current *current = getCurrent();
-
-	current->context = ctx;
-}
-
-void setCurrentDrawSurface(Surface *surface)
-{
-	Current *current = getCurrent();
-
-	current->drawSurface = surface;
-}
-
-Surface *getCurrentDrawSurface()
-{
-	Current *current = getCurrent();
-
-	return current->drawSurface;
-}
-
-void setCurrentReadSurface(Surface *surface)
-{
-	Current *current = getCurrent();
-
-	current->readSurface = surface;
-}
-
-Surface *getCurrentReadSurface()
-{
-	Current *current = getCurrent();
-
-	return current->readSurface;
-}
-}
-
-// Records an error code
-void error(GLenum errorCode)
-{
-	gl::Context *context = gl::getContext();
-
-	if(context)
-	{
-		switch(errorCode)
-		{
-		case GL_INVALID_ENUM:
-			context->recordInvalidEnum();
-			TRACE("\t! Error generated: invalid enum\n");
-			break;
-		case GL_INVALID_VALUE:
-			context->recordInvalidValue();
-			TRACE("\t! Error generated: invalid value\n");
-			break;
-		case GL_INVALID_OPERATION:
-			context->recordInvalidOperation();
-			TRACE("\t! Error generated: invalid operation\n");
-			break;
-		case GL_OUT_OF_MEMORY:
-			context->recordOutOfMemory();
-			TRACE("\t! Error generated: out of memory\n");
-			break;
-		case GL_INVALID_FRAMEBUFFER_OPERATION:
-			context->recordInvalidFramebufferOperation();
-			TRACE("\t! Error generated: invalid framebuffer operation\n");
-			break;
-		default: UNREACHABLE(errorCode);
-		}
-	}
-}
diff --git a/src/OpenGL/libGL/main.h b/src/OpenGL/libGL/main.h
deleted file mode 100644
index 5a49b2b..0000000
--- a/src/OpenGL/libGL/main.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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.
-
-// main.h: Management of thread-local data.
-
-#ifndef LIBGL_MAIN_H_
-#define LIBGL_MAIN_H_
-
-#include "Context.h"
-#include "Device.hpp"
-#include "common/debug.h"
-#include "Display.h"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-namespace gl
-{
-	struct Current
-	{
-		Context *context;
-		Display *display;
-		Surface *drawSurface;
-		Surface *readSurface;
-	};
-
-	void makeCurrent(Context *context, Display *display, Surface *surface);
-
-	Context *getContext();
-	Display *getDisplay();
-	Device *getDevice();
-	Surface *getCurrentDrawSurface();
-	Surface *getCurrentReadSurface();
-
-	void setCurrentDisplay(Display *dpy);
-	void setCurrentContext(gl::Context *ctx);
-	void setCurrentDrawSurface(Surface *surface);
-	void setCurrentReadSurface(Surface *surface);
-}
-
-void error(GLenum errorCode);
-
-template<class T>
-T &error(GLenum errorCode, T &returnValue)
-{
-	error(errorCode);
-
-	return returnValue;
-}
-
-template<class T>
-const T &error(GLenum errorCode, const T &returnValue)
-{
-	error(errorCode);
-
-	return returnValue;
-}
-
-extern sw::FrameBuffer *createFrameBuffer(void *display, NativeWindowType window, int width, int height);
-
-#endif   // LIBGL_MAIN_H_
diff --git a/src/OpenGL/libGL/mathutil.h b/src/OpenGL/libGL/mathutil.h
deleted file mode 100644
index e6f9ddd..0000000
--- a/src/OpenGL/libGL/mathutil.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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.
-
-// mathutil.h: Math and bit manipulation functions.
-
-#ifndef LIBGL_MATHUTIL_H_
-#define LIBGL_MATHUTIL_H_
-
-#include "common/debug.h"
-#include "Common/Math.hpp"
-
-namespace gl
-{
-inline bool isPow2(int x)
-{
-	return (x & (x - 1)) == 0 && (x != 0);
-}
-
-inline int log2(int x)
-{
-	int r = 0;
-	while((x >> r) > 1) r++;
-	return r;
-}
-
-inline unsigned int ceilPow2(unsigned int x)
-{
-	if(x != 0) x--;
-	x |= x >> 1;
-	x |= x >> 2;
-	x |= x >> 4;
-	x |= x >> 8;
-	x |= x >> 16;
-	x++;
-
-	return x;
-}
-
-using sw::clamp;
-using sw::clamp01;
-
-template<const int n>
-inline unsigned int unorm(float x)
-{
-	const unsigned int max = 0xFFFFFFFF >> (32 - n);
-
-	if(x > 1)
-	{
-		return max;
-	}
-	else if(x < 0)
-	{
-		return 0;
-	}
-	else
-	{
-		return (unsigned int)(max * x + 0.5f);
-	}
-}
-}
-
-#endif   // LIBGL_MATHUTIL_H_
diff --git a/src/OpenGL/libGL/resource.h b/src/OpenGL/libGL/resource.h
deleted file mode 100644
index c2ad392..0000000
--- a/src/OpenGL/libGL/resource.h
+++ /dev/null
@@ -1,17 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by libGL.rc
-//
-#define IDD_DIALOG1                     101
-#define IDC_STATIC                      -1
-
-// Next default values for new objects
-// 
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        102
-#define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1001
-#define _APS_NEXT_SYMED_VALUE           101
-#endif
-#endif
diff --git a/src/OpenGL/libGL/utilities.cpp b/src/OpenGL/libGL/utilities.cpp
deleted file mode 100644
index 5f1e0c2..0000000
--- a/src/OpenGL/libGL/utilities.cpp
+++ /dev/null
@@ -1,871 +0,0 @@
-// 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.
-
-// utilities.cpp: Conversion functions and other utility routines.
-
-#include "utilities.h"
-
-#include "mathutil.h"
-#include "Context.h"
-#include "common/debug.h"
-
-#include <limits>
-#include <stdio.h>
-
-namespace gl
-{
-	unsigned int UniformComponentCount(GLenum type)
-	{
-		switch(type)
-		{
-		case GL_BOOL:
-		case GL_FLOAT:
-		case GL_INT:
-		case GL_SAMPLER_2D:
-		case GL_SAMPLER_CUBE:
-			return 1;
-		case GL_BOOL_VEC2:
-		case GL_FLOAT_VEC2:
-		case GL_INT_VEC2:
-			return 2;
-		case GL_INT_VEC3:
-		case GL_FLOAT_VEC3:
-		case GL_BOOL_VEC3:
-			return 3;
-		case GL_BOOL_VEC4:
-		case GL_FLOAT_VEC4:
-		case GL_INT_VEC4:
-		case GL_FLOAT_MAT2:
-			return 4;
-		case GL_FLOAT_MAT3:
-			return 9;
-		case GL_FLOAT_MAT4:
-			return 16;
-		default:
-			UNREACHABLE(type);
-		}
-
-		return 0;
-	}
-
-	GLenum UniformComponentType(GLenum type)
-	{
-		switch(type)
-		{
-		case GL_BOOL:
-		case GL_BOOL_VEC2:
-		case GL_BOOL_VEC3:
-		case GL_BOOL_VEC4:
-			return GL_BOOL;
-		case GL_FLOAT:
-		case GL_FLOAT_VEC2:
-		case GL_FLOAT_VEC3:
-		case GL_FLOAT_VEC4:
-		case GL_FLOAT_MAT2:
-		case GL_FLOAT_MAT3:
-		case GL_FLOAT_MAT4:
-			return GL_FLOAT;
-		case GL_INT:
-		case GL_SAMPLER_2D:
-		case GL_SAMPLER_CUBE:
-		case GL_INT_VEC2:
-		case GL_INT_VEC3:
-		case GL_INT_VEC4:
-			return GL_INT;
-		default:
-			UNREACHABLE(type);
-		}
-
-		return GL_NONE;
-	}
-
-	size_t UniformTypeSize(GLenum type)
-	{
-		switch(type)
-		{
-		case GL_BOOL:  return sizeof(GLboolean);
-		case GL_FLOAT: return sizeof(GLfloat);
-		case GL_INT:   return sizeof(GLint);
-		}
-
-		return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type);
-	}
-
-	int VariableRowCount(GLenum type)
-	{
-		switch(type)
-		{
-		case GL_NONE:
-			return 0;
-		case GL_BOOL:
-		case GL_FLOAT:
-		case GL_INT:
-		case GL_BOOL_VEC2:
-		case GL_FLOAT_VEC2:
-		case GL_INT_VEC2:
-		case GL_INT_VEC3:
-		case GL_FLOAT_VEC3:
-		case GL_BOOL_VEC3:
-		case GL_BOOL_VEC4:
-		case GL_FLOAT_VEC4:
-		case GL_INT_VEC4:
-		case GL_SAMPLER_2D:
-		case GL_SAMPLER_CUBE:
-			return 1;
-		case GL_FLOAT_MAT2:
-			return 2;
-		case GL_FLOAT_MAT3:
-			return 3;
-		case GL_FLOAT_MAT4:
-			return 4;
-		default:
-			UNREACHABLE(type);
-		}
-
-		return 0;
-	}
-
-	int VariableColumnCount(GLenum type)
-	{
-		switch(type)
-		{
-		case GL_NONE:
-			return 0;
-		case GL_BOOL:
-		case GL_FLOAT:
-		case GL_INT:
-			return 1;
-		case GL_BOOL_VEC2:
-		case GL_FLOAT_VEC2:
-		case GL_INT_VEC2:
-		case GL_FLOAT_MAT2:
-			return 2;
-		case GL_INT_VEC3:
-		case GL_FLOAT_VEC3:
-		case GL_BOOL_VEC3:
-		case GL_FLOAT_MAT3:
-			return 3;
-		case GL_BOOL_VEC4:
-		case GL_FLOAT_VEC4:
-		case GL_INT_VEC4:
-		case GL_FLOAT_MAT4:
-			return 4;
-		default:
-			UNREACHABLE(type);
-		}
-
-		return 0;
-	}
-
-	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
-	{
-		ASSERT(allocationSize <= bitsSize);
-
-		unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
-
-		for(unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
-		{
-			if((*bits & mask) == 0)
-			{
-				*bits |= mask;
-				return i;
-			}
-
-			mask <<= 1;
-		}
-
-		return -1;
-	}
-
-	GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
-	{
-		ASSERT(alignment > 0 && isPow2(alignment));
-
-		GLsizei rawPitch = ComputePixelSize(format, type) * width;
-		return (rawPitch + alignment - 1) & ~(alignment - 1);
-	}
-
-	GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
-	{
-		return ComputeCompressedSize(width, 1, format);
-	}
-
-	GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
-	{
-		switch(format)
-		{
-		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-			return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
-		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-			return 16 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
-		default:
-			return 0;
-		}
-	}
-
-	bool IsCompressed(GLenum format)
-	{
-		return format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
-		       format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
-		       format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
-		       format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
-	}
-
-	bool IsDepthTexture(GLenum format)
-	{
-		return format == GL_DEPTH_COMPONENT ||
-		       format == GL_DEPTH_STENCIL_EXT;
-	}
-
-	bool IsStencilTexture(GLenum format)
-	{
-		return format == GL_STENCIL_INDEX ||
-		       format == GL_DEPTH_STENCIL_EXT;
-	}
-
-	// Returns the size, in bytes, of a single texel in an Image
-	int ComputePixelSize(GLenum format, GLenum type)
-	{
-		switch(type)
-		{
-		case GL_UNSIGNED_BYTE:
-			switch(format)
-			{
-			case GL_ALPHA:           return sizeof(unsigned char);
-			case GL_LUMINANCE:       return sizeof(unsigned char);
-			case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
-			case GL_RGB:             return sizeof(unsigned char) * 3;
-			case GL_RGBA:            return sizeof(unsigned char) * 4;
-			case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;
-			default: UNREACHABLE(format);
-			}
-			break;
-		case GL_UNSIGNED_SHORT_4_4_4_4:
-		case GL_UNSIGNED_SHORT_5_5_5_1:
-		case GL_UNSIGNED_SHORT_5_6_5:
-		case GL_UNSIGNED_SHORT:
-			return sizeof(unsigned short);
-		case GL_UNSIGNED_INT:
-		case GL_UNSIGNED_INT_24_8_EXT:
-		case GL_UNSIGNED_INT_8_8_8_8_REV:
-			return sizeof(unsigned int);
-		case GL_FLOAT:
-			switch(format)
-			{
-			case GL_ALPHA:           return sizeof(float);
-			case GL_LUMINANCE:       return sizeof(float);
-			case GL_DEPTH_COMPONENT: return sizeof(float);
-			case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
-			case GL_RGB:             return sizeof(float) * 3;
-			case GL_RGBA:            return sizeof(float) * 4;
-			default: UNREACHABLE(format);
-			}
-			break;
-		case GL_HALF_FLOAT:
-			switch(format)
-			{
-			case GL_ALPHA:           return sizeof(unsigned short);
-			case GL_LUMINANCE:       return sizeof(unsigned short);
-			case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
-			case GL_RGB:             return sizeof(unsigned short) * 3;
-			case GL_RGBA:            return sizeof(unsigned short) * 4;
-			default: UNREACHABLE(format);
-			}
-			break;
-		default: UNREACHABLE(type);
-		}
-
-		return 0;
-	}
-
-	bool IsCubemapTextureTarget(GLenum target)
-	{
-		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
-	}
-
-	int CubeFaceIndex(GLenum cubeFace)
-	{
-		switch(cubeFace)
-		{
-		case GL_TEXTURE_CUBE_MAP:
-		case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0;
-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1;
-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2;
-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3;
-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4;
-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5;
-		default: UNREACHABLE(cubeFace); return 0;
-		}
-	}
-
-	bool IsTextureTarget(GLenum target)
-	{
-		return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
-	}
-
-	// Verify that format/type are one of the combinations from table 3.4.
-	bool CheckTextureFormatType(GLenum format, GLenum type)
-	{
-		switch(type)
-		{
-		case GL_UNSIGNED_BYTE:
-			switch(format)
-			{
-			case GL_RGBA:
-			case GL_BGRA_EXT:
-			case GL_RGB:
-			case GL_ALPHA:
-			case GL_LUMINANCE:
-			case GL_LUMINANCE_ALPHA:
-				return true;
-			default:
-				return false;
-			}
-		case GL_FLOAT:
-		case GL_HALF_FLOAT:
-			switch(format)
-			{
-			case GL_RGBA:
-			case GL_RGB:
-			case GL_ALPHA:
-			case GL_LUMINANCE:
-			case GL_LUMINANCE_ALPHA:
-				return true;
-			default:
-				return false;
-			}
-		case GL_UNSIGNED_SHORT_4_4_4_4:
-		case GL_UNSIGNED_SHORT_5_5_5_1:
-			return (format == GL_RGBA);
-		case GL_UNSIGNED_SHORT_5_6_5:
-			return (format == GL_RGB);
-		case GL_UNSIGNED_INT:
-			return (format == GL_DEPTH_COMPONENT);
-		case GL_UNSIGNED_INT_24_8_EXT:
-			return (format == GL_DEPTH_STENCIL_EXT);
-		case GL_UNSIGNED_INT_8_8_8_8_REV:
-			return (format == GL_BGRA);
-		default:
-			return false;
-		}
-	}
-
-	bool IsColorRenderable(GLenum internalformat)
-	{
-		switch(internalformat)
-		{
-		case GL_RGBA4:
-		case GL_RGB5_A1:
-		case GL_RGB565:
-		case GL_RGB8_EXT:
-		case GL_RGBA8_EXT:
-			return true;
-		case GL_DEPTH_COMPONENT16:
-		case GL_DEPTH_COMPONENT24:
-		case GL_STENCIL_INDEX8:
-		case GL_DEPTH24_STENCIL8_EXT:
-			return false;
-		default:
-			UNIMPLEMENTED();
-		}
-
-		return false;
-	}
-
-	bool IsDepthRenderable(GLenum internalformat)
-	{
-		switch(internalformat)
-		{
-		case GL_DEPTH_COMPONENT16:
-		case GL_DEPTH_COMPONENT24:
-		case GL_DEPTH24_STENCIL8_EXT:
-			return true;
-		case GL_STENCIL_INDEX8:
-		case GL_RGBA4:
-		case GL_RGB5_A1:
-		case GL_RGB565:
-		case GL_RGB8_EXT:
-		case GL_RGBA8_EXT:
-			return false;
-		default:
-			UNIMPLEMENTED();
-		}
-
-		return false;
-	}
-
-	bool IsStencilRenderable(GLenum internalformat)
-	{
-		switch(internalformat)
-		{
-		case GL_STENCIL_INDEX8:
-		case GL_DEPTH24_STENCIL8_EXT:
-			return true;
-		case GL_RGBA4:
-		case GL_RGB5_A1:
-		case GL_RGB565:
-		case GL_RGB8_EXT:
-		case GL_RGBA8_EXT:
-		case GL_DEPTH_COMPONENT16:
-		case GL_DEPTH_COMPONENT24:
-			return false;
-		default:
-			UNIMPLEMENTED();
-		}
-
-		return false;
-	}
-}
-
-namespace es2sw
-{
-	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison)
-	{
-		switch(comparison)
-		{
-		case GL_NEVER:    return sw::DEPTH_NEVER;
-		case GL_ALWAYS:   return sw::DEPTH_ALWAYS;
-		case GL_LESS:     return sw::DEPTH_LESS;
-		case GL_LEQUAL:   return sw::DEPTH_LESSEQUAL;
-		case GL_EQUAL:    return sw::DEPTH_EQUAL;
-		case GL_GREATER:  return sw::DEPTH_GREATER;
-		case GL_GEQUAL:   return sw::DEPTH_GREATEREQUAL;
-		case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL;
-		default: UNREACHABLE(comparison);
-		}
-
-		return sw::DEPTH_ALWAYS;
-	}
-
-	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison)
-	{
-		switch(comparison)
-		{
-		case GL_NEVER:    return sw::STENCIL_NEVER;
-		case GL_ALWAYS:   return sw::STENCIL_ALWAYS;
-		case GL_LESS:     return sw::STENCIL_LESS;
-		case GL_LEQUAL:   return sw::STENCIL_LESSEQUAL;
-		case GL_EQUAL:    return sw::STENCIL_EQUAL;
-		case GL_GREATER:  return sw::STENCIL_GREATER;
-		case GL_GEQUAL:   return sw::STENCIL_GREATEREQUAL;
-		case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL;
-		default: UNREACHABLE(comparison);
-		}
-
-		return sw::STENCIL_ALWAYS;
-	}
-
-	sw::Color<float> ConvertColor(gl::Color color)
-	{
-		return sw::Color<float>(color.red, color.green, color.blue, color.alpha);
-	}
-
-	sw::BlendFactor ConvertBlendFunc(GLenum blend)
-	{
-		switch(blend)
-		{
-		case GL_ZERO:                     return sw::BLEND_ZERO;
-		case GL_ONE:                      return sw::BLEND_ONE;
-		case GL_SRC_COLOR:                return sw::BLEND_SOURCE;
-		case GL_ONE_MINUS_SRC_COLOR:      return sw::BLEND_INVSOURCE;
-		case GL_DST_COLOR:                return sw::BLEND_DEST;
-		case GL_ONE_MINUS_DST_COLOR:      return sw::BLEND_INVDEST;
-		case GL_SRC_ALPHA:                return sw::BLEND_SOURCEALPHA;
-		case GL_ONE_MINUS_SRC_ALPHA:      return sw::BLEND_INVSOURCEALPHA;
-		case GL_DST_ALPHA:                return sw::BLEND_DESTALPHA;
-		case GL_ONE_MINUS_DST_ALPHA:      return sw::BLEND_INVDESTALPHA;
-		case GL_CONSTANT_COLOR:           return sw::BLEND_CONSTANT;
-		case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT;
-		case GL_CONSTANT_ALPHA:           return sw::BLEND_CONSTANTALPHA;
-		case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA;
-		case GL_SRC_ALPHA_SATURATE:       return sw::BLEND_SRCALPHASAT;
-		default: UNREACHABLE(blend);
-		}
-
-		return sw::BLEND_ZERO;
-	}
-
-	sw::BlendOperation ConvertBlendOp(GLenum blendOp)
-	{
-		switch(blendOp)
-		{
-		case GL_FUNC_ADD:              return sw::BLENDOP_ADD;
-		case GL_FUNC_SUBTRACT:         return sw::BLENDOP_SUB;
-		case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB;
-		case GL_MIN_EXT:               return sw::BLENDOP_MIN;
-		case GL_MAX_EXT:               return sw::BLENDOP_MAX;
-		default: UNREACHABLE(blendOp);
-		}
-
-		return sw::BLENDOP_ADD;
-	}
-
-	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation)
-	{
-		switch(logicalOperation)
-		{
-		case GL_CLEAR:         return sw::LOGICALOP_CLEAR;
-		case GL_SET:           return sw::LOGICALOP_SET;
-		case GL_COPY:          return sw::LOGICALOP_COPY;
-		case GL_COPY_INVERTED: return sw::LOGICALOP_COPY_INVERTED;
-		case GL_NOOP:          return sw::LOGICALOP_NOOP;
-		case GL_INVERT:        return sw::LOGICALOP_INVERT;
-		case GL_AND:           return sw::LOGICALOP_AND;
-		case GL_NAND:          return sw::LOGICALOP_NAND;
-		case GL_OR:            return sw::LOGICALOP_OR;
-		case GL_NOR:           return sw::LOGICALOP_NOR;
-		case GL_XOR:           return sw::LOGICALOP_XOR;
-		case GL_EQUIV:         return sw::LOGICALOP_EQUIV;
-		case GL_AND_REVERSE:   return sw::LOGICALOP_AND_REVERSE;
-		case GL_AND_INVERTED:  return sw::LOGICALOP_AND_INVERTED;
-		case GL_OR_REVERSE:    return sw::LOGICALOP_OR_REVERSE;
-		case GL_OR_INVERTED:   return sw::LOGICALOP_OR_INVERTED;
-		default: UNREACHABLE(logicalOperation);
-		}
-
-		return sw::LOGICALOP_COPY;
-	}
-
-	sw::StencilOperation ConvertStencilOp(GLenum stencilOp)
-	{
-		switch(stencilOp)
-		{
-		case GL_ZERO:      return sw::OPERATION_ZERO;
-		case GL_KEEP:      return sw::OPERATION_KEEP;
-		case GL_REPLACE:   return sw::OPERATION_REPLACE;
-		case GL_INCR:      return sw::OPERATION_INCRSAT;
-		case GL_DECR:      return sw::OPERATION_DECRSAT;
-		case GL_INVERT:    return sw::OPERATION_INVERT;
-		case GL_INCR_WRAP: return sw::OPERATION_INCR;
-		case GL_DECR_WRAP: return sw::OPERATION_DECR;
-		default: UNREACHABLE(stencilOp);
-		}
-
-		return sw::OPERATION_KEEP;
-	}
-
-	sw::AddressingMode ConvertTextureWrap(GLenum wrap)
-	{
-		switch(wrap)
-		{
-		case GL_CLAMP:             return sw::ADDRESSING_CLAMP;
-		case GL_REPEAT:            return sw::ADDRESSING_WRAP;
-		case GL_CLAMP_TO_EDGE:     return sw::ADDRESSING_CLAMP;
-		case GL_MIRRORED_REPEAT:   return sw::ADDRESSING_MIRROR;
-		default: UNREACHABLE(wrap);
-		}
-
-		return sw::ADDRESSING_WRAP;
-	}
-
-	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace)
-	{
-		switch(cullFace)
-		{
-		case GL_FRONT:
-			return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE);
-		case GL_BACK:
-			return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE);
-		case GL_FRONT_AND_BACK:
-			return sw::CULL_NONE;   // culling will be handled during draw
-		default: UNREACHABLE(cullFace);
-		}
-
-		return sw::CULL_COUNTERCLOCKWISE;
-	}
-
-	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha)
-	{
-		return (red   ? 0x00000001 : 0) |
-			   (green ? 0x00000002 : 0) |
-			   (blue  ? 0x00000004 : 0) |
-			   (alpha ? 0x00000008 : 0);
-	}
-
-	sw::MipmapType ConvertMipMapFilter(GLenum minFilter)
-	{
-		switch(minFilter)
-		{
-		case GL_NEAREST:
-		case GL_LINEAR:
-			return sw::MIPMAP_NONE;
-			break;
-		case GL_NEAREST_MIPMAP_NEAREST:
-		case GL_LINEAR_MIPMAP_NEAREST:
-			return sw::MIPMAP_POINT;
-			break;
-		case GL_NEAREST_MIPMAP_LINEAR:
-		case GL_LINEAR_MIPMAP_LINEAR:
-			return sw::MIPMAP_LINEAR;
-			break;
-		default:
-			UNREACHABLE(minFilter);
-			return sw::MIPMAP_NONE;
-		}
-	}
-
-	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
-	{
-		if(maxAnisotropy > 1.0f)
-		{
-			return sw::FILTER_ANISOTROPIC;
-		}
-
-		switch(minFilter)
-		{
-		case GL_NEAREST:
-		case GL_NEAREST_MIPMAP_NEAREST:
-		case GL_NEAREST_MIPMAP_LINEAR:
-			return (magFilter == GL_NEAREST) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
-		case GL_LINEAR:
-		case GL_LINEAR_MIPMAP_NEAREST:
-		case GL_LINEAR_MIPMAP_LINEAR:
-			return (magFilter == GL_NEAREST) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
-		default:
-			UNREACHABLE(minFilter);
-			return sw::FILTER_LINEAR;
-		}
-	}
-
-	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,  gl::PrimitiveType &swPrimitiveType, int &primitiveCount)
-	{
-		switch(primitiveType)
-		{
-		case GL_POINTS:
-			swPrimitiveType = gl::DRAW_POINTLIST;
-			primitiveCount = elementCount;
-			break;
-		case GL_LINES:
-			swPrimitiveType = gl::DRAW_LINELIST;
-			primitiveCount = elementCount / 2;
-			break;
-		case GL_LINE_LOOP:
-			swPrimitiveType = gl::DRAW_LINELOOP;
-			primitiveCount = elementCount;
-			break;
-		case GL_LINE_STRIP:
-			swPrimitiveType = gl::DRAW_LINESTRIP;
-			primitiveCount = elementCount - 1;
-			break;
-		case GL_TRIANGLES:
-			swPrimitiveType = gl::DRAW_TRIANGLELIST;
-			primitiveCount = elementCount / 3;
-			break;
-		case GL_TRIANGLE_STRIP:
-			swPrimitiveType = gl::DRAW_TRIANGLESTRIP;
-			primitiveCount = elementCount - 2;
-			break;
-		case GL_TRIANGLE_FAN:
-			swPrimitiveType = gl::DRAW_TRIANGLEFAN;
-			primitiveCount = elementCount - 2;
-			break;
-		case GL_QUADS:
-			swPrimitiveType = gl::DRAW_QUADLIST;
-			primitiveCount = (elementCount / 4) * 2;
-			break;
-		default:
-			return false;
-		}
-
-		return true;
-	}
-
-	sw::Format ConvertRenderbufferFormat(GLenum format)
-	{
-		switch(format)
-		{
-		case GL_RGBA4:
-		case GL_RGB5_A1:
-		case GL_RGBA8_EXT:            return sw::FORMAT_A8R8G8B8;
-		case GL_RGB565:               return sw::FORMAT_R5G6B5;
-		case GL_RGB8_EXT:             return sw::FORMAT_X8R8G8B8;
-		case GL_DEPTH_COMPONENT16:
-		case GL_DEPTH_COMPONENT24:
-		case GL_STENCIL_INDEX8:
-		case GL_DEPTH24_STENCIL8_EXT: return sw::FORMAT_D24S8;
-		default: UNREACHABLE(format); return sw::FORMAT_A8R8G8B8;
-		}
-	}
-}
-
-namespace sw2es
-{
-	unsigned int GetStencilSize(sw::Format stencilFormat)
-	{
-		switch(stencilFormat)
-		{
-		case sw::FORMAT_D24FS8:
-		case sw::FORMAT_D24S8:
-		case sw::FORMAT_D32FS8_TEXTURE:
-			return 8;
-	//	case sw::FORMAT_D24X4S4:
-	//		return 4;
-	//	case sw::FORMAT_D15S1:
-	//		return 1;
-	//	case sw::FORMAT_D16_LOCKABLE:
-		case sw::FORMAT_D32:
-		case sw::FORMAT_D24X8:
-		case sw::FORMAT_D32F_LOCKABLE:
-		case sw::FORMAT_D16:
-			return 0;
-	//	case sw::FORMAT_D32_LOCKABLE:  return 0;
-	//	case sw::FORMAT_S8_LOCKABLE:   return 8;
-		default:
-			return 0;
-		}
-	}
-
-	unsigned int GetAlphaSize(sw::Format colorFormat)
-	{
-		switch(colorFormat)
-		{
-		case sw::FORMAT_A16B16G16R16F:
-			return 16;
-		case sw::FORMAT_A32B32G32R32F:
-			return 32;
-		case sw::FORMAT_A2R10G10B10:
-			return 2;
-		case sw::FORMAT_A8R8G8B8:
-			return 8;
-		case sw::FORMAT_A1R5G5B5:
-			return 1;
-		case sw::FORMAT_X8R8G8B8:
-		case sw::FORMAT_R5G6B5:
-			return 0;
-		default:
-			return 0;
-		}
-	}
-
-	unsigned int GetRedSize(sw::Format colorFormat)
-	{
-		switch(colorFormat)
-		{
-		case sw::FORMAT_A16B16G16R16F:
-			return 16;
-		case sw::FORMAT_A32B32G32R32F:
-			return 32;
-		case sw::FORMAT_A2R10G10B10:
-			return 10;
-		case sw::FORMAT_A8R8G8B8:
-		case sw::FORMAT_X8R8G8B8:
-			return 8;
-		case sw::FORMAT_A1R5G5B5:
-		case sw::FORMAT_R5G6B5:
-			return 5;
-		default:
-			return 0;
-		}
-	}
-
-	unsigned int GetGreenSize(sw::Format colorFormat)
-	{
-		switch(colorFormat)
-		{
-		case sw::FORMAT_A16B16G16R16F:
-			return 16;
-		case sw::FORMAT_A32B32G32R32F:
-			return 32;
-		case sw::FORMAT_A2R10G10B10:
-			return 10;
-		case sw::FORMAT_A8R8G8B8:
-		case sw::FORMAT_X8R8G8B8:
-			return 8;
-		case sw::FORMAT_A1R5G5B5:
-			return 5;
-		case sw::FORMAT_R5G6B5:
-			return 6;
-		default:
-			return 0;
-		}
-	}
-
-	unsigned int GetBlueSize(sw::Format colorFormat)
-	{
-		switch(colorFormat)
-		{
-		case sw::FORMAT_A16B16G16R16F:
-			return 16;
-		case sw::FORMAT_A32B32G32R32F:
-			return 32;
-		case sw::FORMAT_A2R10G10B10:
-			return 10;
-		case sw::FORMAT_A8R8G8B8:
-		case sw::FORMAT_X8R8G8B8:
-			return 8;
-		case sw::FORMAT_A1R5G5B5:
-		case sw::FORMAT_R5G6B5:
-			return 5;
-		default:
-			return 0;
-		}
-	}
-
-	unsigned int GetDepthSize(sw::Format depthFormat)
-	{
-		switch(depthFormat)
-		{
-	//	case sw::FORMAT_D16_LOCKABLE:   return 16;
-		case sw::FORMAT_D32:            return 32;
-	//	case sw::FORMAT_D15S1:          return 15;
-		case sw::FORMAT_D24S8:          return 24;
-		case sw::FORMAT_D24X8:          return 24;
-	//	case sw::FORMAT_D24X4S4:        return 24;
-		case sw::FORMAT_D16:            return 16;
-		case sw::FORMAT_D32F_LOCKABLE:  return 32;
-		case sw::FORMAT_D24FS8:         return 24;
-	//	case sw::FORMAT_D32_LOCKABLE:   return 32;
-	//	case sw::FORMAT_S8_LOCKABLE:    return 0;
-		case sw::FORMAT_D32FS8_TEXTURE: return 32;
-		default:                        return 0;
-		}
-	}
-
-	GLenum ConvertBackBufferFormat(sw::Format format)
-	{
-		switch(format)
-		{
-		case sw::FORMAT_A4R4G4B4: return GL_RGBA4;
-		case sw::FORMAT_A8R8G8B8: return GL_RGBA8_EXT;
-		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1;
-		case sw::FORMAT_R5G6B5:   return GL_RGB565;
-		case sw::FORMAT_X8R8G8B8: return GL_RGB8_EXT;
-		default:
-			UNREACHABLE(format);
-		}
-
-		return GL_RGBA4;
-	}
-
-	GLenum ConvertDepthStencilFormat(sw::Format format)
-	{
-		switch(format)
-		{
-		case sw::FORMAT_D16:
-			return GL_DEPTH_COMPONENT16;
-		case sw::FORMAT_D32:
-			return GL_DEPTH_COMPONENT32;
-		case sw::FORMAT_D24X8:
-			return GL_DEPTH_COMPONENT24;
-		case sw::FORMAT_D24S8:
-			return GL_DEPTH24_STENCIL8_EXT;
-		default:
-			UNREACHABLE(format);
-		}
-
-		return GL_DEPTH24_STENCIL8_EXT;
-	}
-}
diff --git a/src/OpenGL/libGL/utilities.h b/src/OpenGL/libGL/utilities.h
deleted file mode 100644
index 82feeaf..0000000
--- a/src/OpenGL/libGL/utilities.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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.
-
-// utilities.h: Conversion functions and other utility routines.
-
-#ifndef LIBGL_UTILITIES_H
-#define LIBGL_UTILITIES_H
-
-#include "Device.hpp"
-#include "Image.hpp"
-#include "Texture.h"
-
-#define _GDI32_
-#include <windows.h>
-#include <GL/GL.h>
-#include <GL/glext.h>
-
-#include <string>
-
-namespace gl
-{
-	struct Color;
-
-	unsigned int UniformComponentCount(GLenum type);
-	GLenum UniformComponentType(GLenum type);
-	size_t UniformTypeSize(GLenum type);
-	int VariableRowCount(GLenum type);
-	int VariableColumnCount(GLenum type);
-
-	int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
-
-	int ComputePixelSize(GLenum format, GLenum type);
-	GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment);
-	GLsizei ComputeCompressedPitch(GLsizei width, GLenum format);
-	GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format);
-	bool IsCompressed(GLenum format);
-	bool IsDepthTexture(GLenum format);
-	bool IsStencilTexture(GLenum format);
-	bool IsCubemapTextureTarget(GLenum target);
-	int CubeFaceIndex(GLenum cubeTarget);
-	bool IsTextureTarget(GLenum target);
-	bool CheckTextureFormatType(GLenum format, GLenum type);
-
-	bool IsColorRenderable(GLenum internalformat);
-	bool IsDepthRenderable(GLenum internalformat);
-	bool IsStencilRenderable(GLenum internalformat);
-}
-
-namespace es2sw
-{
-	sw::DepthCompareMode ConvertDepthComparison(GLenum comparison);
-	sw::StencilCompareMode ConvertStencilComparison(GLenum comparison);
-	sw::Color<float> ConvertColor(gl::Color color);
-	sw::BlendFactor ConvertBlendFunc(GLenum blend);
-	sw::BlendOperation ConvertBlendOp(GLenum blendOp);
-	sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation);
-	sw::StencilOperation ConvertStencilOp(GLenum stencilOp);
-	sw::AddressingMode ConvertTextureWrap(GLenum wrap);
-	sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace);
-	unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha);
-	sw::MipmapType ConvertMipMapFilter(GLenum minFilter);
-	sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);
-	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,  gl::PrimitiveType &swPrimitiveType, int &primitiveCount);
-	sw::Format ConvertRenderbufferFormat(GLenum format);
-}
-
-namespace sw2es
-{
-	GLuint GetAlphaSize(sw::Format colorFormat);
-	GLuint GetRedSize(sw::Format colorFormat);
-	GLuint GetGreenSize(sw::Format colorFormat);
-	GLuint GetBlueSize(sw::Format colorFormat);
-	GLuint GetDepthSize(sw::Format depthFormat);
-	GLuint GetStencilSize(sw::Format stencilFormat);
-
-	GLenum ConvertBackBufferFormat(sw::Format format);
-	GLenum ConvertDepthStencilFormat(sw::Format format);
-}
-
-#endif  // LIBGL_UTILITIES_H
diff --git a/tests/OGLSimpleCube/OGLSimpleCube.cpp b/tests/OGLSimpleCube/OGLSimpleCube.cpp
deleted file mode 100644
index bfcf569..0000000
--- a/tests/OGLSimpleCube/OGLSimpleCube.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-// 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.
-
-/******************************************************************************
-
-@File			OGLSimpleCube.cpp
-
-@Title			OpenGL Simple cube application
-
-@Version		1.0
-
-@Platform		Windows
-
-@Description	Basic window with a cube drawn in it, using libGL (opengl32).
-Inspired by http://www.cs.rit.edu/~ncs/Courses/570/UserGuide/OpenGLonWin-11.html
-
-******************************************************************************/
-#include <windows.h>
-#include <math.h>
-
-#include <gl\GL.h>
-
-#define PI 3.14159265
-#define SCALE_FACTOR 0.5
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
-
-const char *className = "OpenGL";
-const char *windowName = "OpenGL Cube";
-int winX = 0, winY = 0;
-int winWidth = 300, winHeight = 300;
-float angle = 0.1f;
-double theta = angle * PI / 180.0;
-int listIndex;
-
-// Rotation matrix
-GLfloat R[16] = { 1, 0, 0, 0, 0, cos(theta), -sin(theta), 0, 0, sin(theta), cos(theta), 0, 0, 0, 0, 1 };
-
-// Scaling matrix
-GLfloat S[16] = { SCALE_FACTOR, 0, 0, 0, 0, SCALE_FACTOR, 0, 0, 0, 0, SCALE_FACTOR, 0, 0, 0, 0, 1 };
-
-HDC hDC;
-HGLRC hGLRC;
-HPALETTE hPalette;
-
-GLfloat vertices1[] = {
-	0.5F, 0.5F, 0.5F, -0.5F, 0.5F, 0.5F, -0.5F, -0.5F, 0.5F, 0.5F, -0.5F, 0.5F,
-	-0.5F, -0.5F, -0.5F, -0.5F, 0.5F, -0.5F, 0.5F, 0.5F, -0.5F, 0.5F, -0.5F, -0.5F,
-	0.5F, 0.5F, 0.5F, 0.5F, 0.5F, -0.5F, -0.5F, 0.5F, -0.5F, -0.5F, 0.5F, 0.5F,
-	-0.5F, -0.5F, -0.5F, 0.5F, -0.5F, -0.5F, 0.5F, -0.5F, 0.5F, -0.5F, -0.5F, 0.5F,
-	0.5F, 0.5F, 0.5F, 0.5F, -0.5F, 0.5F, 0.5F, -0.5F, -0.5F, 0.5F, 0.5F, -0.5F,
-	-0.5F, -0.5F, -0.5F, -0.5F, -0.5F, 0.5F, -0.5F, 0.5F, 0.5F, -0.5F, 0.5F, -0.5F
-};
-
-GLfloat normals1[] = {
-	0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
-	0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1,
-	0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
-	0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
-	1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
-	-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0
-};
-
-GLfloat colors1[] = {
-	1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0,
-	0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0,
-	1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0,
-	0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0,
-	0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1
-};
-
-void initializeView(void)
-{
-	// Set viewing projection
-	glMatrixMode(GL_PROJECTION);
-	glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0);
-
-	// Position viewer
-	glMatrixMode(GL_MODELVIEW);
-	glTranslatef(0.0F, 0.0F, -2.0F);
-
-	// Position object
-	glRotatef(30.0F, 1.0F, 0.0F, 0.0F);
-	glRotatef(30.0F, 0.0F, 1.0F, 0.0F);
-
-	glEnable(GL_DEPTH_TEST);
-	glEnable(GL_COLOR_MATERIAL);
-}
-
-void initDisplayList(void)
-{
-	listIndex = glGenLists(1);
-	glNewList(listIndex, GL_COMPILE);
-	glNormalPointer(GL_FLOAT, 0, normals1);
-	glColorPointer(3, GL_FLOAT, 0, colors1);
-	glVertexPointer(3, GL_FLOAT, 0, vertices1);
-
-	glEnableClientState(GL_NORMAL_ARRAY);
-	glEnableClientState(GL_COLOR_ARRAY);
-	glEnableClientState(GL_VERTEX_ARRAY);
-
-	glPushMatrix();
-	glMultMatrixf(S);
-	glDrawArrays(GL_QUADS, 0, 24);
-	glPopMatrix();
-
-	glDisableClientState(GL_VERTEX_ARRAY);
-	glDisableClientState(GL_COLOR_ARRAY);
-	glDisableClientState(GL_NORMAL_ARRAY);
-	glEndList();
-}
-
-void redraw(void)
-{
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-	glCallList(listIndex);
-
-	// Rotation
-	glMultMatrixf(R);
-
-	SwapBuffers(hDC);
-}
-
-void resize(void)
-{
-	// Set viewport to cover the window
-	glViewport(0, 0, winWidth, winHeight);
-}
-
-void setupPixelFormat(HDC hDC)
-{
-	PIXELFORMATDESCRIPTOR pfd = {
-		sizeof(PIXELFORMATDESCRIPTOR),  // Size
-		1,                              // Version
-		PFD_SUPPORT_OPENGL |
-		PFD_DRAW_TO_WINDOW |
-		PFD_DOUBLEBUFFER,               // Support double-buffering
-		PFD_TYPE_RGBA,                  // Color type
-		16,                             // Prefered color depth
-		0, 0, 0, 0, 0, 0,               // Color bits (ignored)
-		0,                              // No alpha buffer
-		0,                              // Alpha bits (ignored)
-		0,                              // No accumulation buffer
-		0, 0, 0, 0,                     // Accum bits (ignored)
-		16,                             // Depth buffer
-		0,                              // No stencil buffer
-		0,                              // No auxiliary buffers
-		PFD_MAIN_PLANE,                 // Main layer
-		0,                              // Reserved
-		0, 0, 0,                        // No layer, visible, damage masks
-	};
-	int pixelFormat;
-
-	pixelFormat = ChoosePixelFormat(hDC, &pfd);
-	if(pixelFormat == 0) {
-		MessageBox(WindowFromDC(hDC), L"ChoosePixelFormat failed.", L"Error",
-			MB_ICONERROR | MB_OK);
-		exit(1);
-	}
-
-	if(SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) {
-		MessageBox(WindowFromDC(hDC), L"SetPixelFormat failed.", L"Error",
-			MB_ICONERROR | MB_OK);
-		exit(1);
-	}
-}
-
-int __stdcall WinMain(__in HINSTANCE hCurrentInst, __in_opt HINSTANCE hPreviousInst, __in_opt LPSTR lpCmdLine, __in int nShowCmd)
-{
-	WNDCLASS wndClass;
-	HWND hWnd;
-	MSG msg;
-
-	// Register window class
-	wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
-	wndClass.lpfnWndProc = WndProc;
-	wndClass.cbClsExtra = 0;
-	wndClass.cbWndExtra = 0;
-	wndClass.hInstance = hCurrentInst;
-	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
-	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
-	wndClass.hbrBackground = (HBRUSH)BLACK_BRUSH;
-	wndClass.lpszMenuName = NULL;
-	wndClass.lpszClassName = L"OpenGL cube";
-	RegisterClass(&wndClass);
-
-	// Create window
-	hWnd = CreateWindow(
-		L"OpenGL cube", L"OpenGL",
-		WS_OVERLAPPEDWINDOW,
-		winX, winY, winWidth, winHeight,
-		NULL, NULL, hCurrentInst, NULL);
-
-	// Display window
-	ShowWindow(hWnd, nShowCmd);
-
-	hDC = GetDC(hWnd);
-	setupPixelFormat(hDC);
-	hGLRC = wglCreateContext(hDC);
-	wglMakeCurrent(hDC, hGLRC);
-	initializeView();
-	initDisplayList();
-
-	while(true)
-	{
-		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
-		{
-			if(msg.message == WM_QUIT)
-			{
-				break;
-			}
-
-			TranslateMessage(&msg);
-			DispatchMessage(&msg);
-		}
-		else
-		{
-			redraw();
-		}
-	}
-
-	wglMakeCurrent(NULL, NULL);
-	wglDeleteContext(hGLRC);
-	ReleaseDC(hWnd, hDC);
-
-	return msg.wParam;
-}
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
-	switch(message) {
-	case WM_DESTROY:
-		// Finish OpenGL rendering
-		if(hGLRC) {
-			wglMakeCurrent(NULL, NULL);
-			wglDeleteContext(hGLRC);
-		}
-		if(hPalette) {
-			DeleteObject(hPalette);
-		}
-		ReleaseDC(hWnd, hDC);
-		PostQuitMessage(0);
-		return 0;
-	case WM_SIZE:
-		// Track window size changes
-		if(hGLRC) {
-			winWidth = (int)LOWORD(lParam);
-			winHeight = (int)HIWORD(lParam);
-			resize();
-			return 0;
-		}
-	case WM_PALETTECHANGED:
-		// Realize palette if this is *not* the current window
-		if(hGLRC && hPalette && (HWND)wParam != hWnd) {
-			UnrealizeObject(hPalette);
-			SelectPalette(hDC, hPalette, FALSE);
-			RealizePalette(hDC);
-			redraw();
-			break;
-		}
-		break;
-	case WM_QUERYNEWPALETTE:
-		// Realize palette if this is the current window
-		if(hGLRC && hPalette) {
-			UnrealizeObject(hPalette);
-			SelectPalette(hDC, hPalette, FALSE);
-			RealizePalette(hDC);
-			return TRUE;
-		}
-		break;
-	default:
-		break;
-	}
-
-	return DefWindowProc(hWnd, message, wParam, lParam);
-}
\ No newline at end of file
diff --git a/tests/OGLSimpleCube/OGLSimpleCube.vcxproj b/tests/OGLSimpleCube/OGLSimpleCube.vcxproj
deleted file mode 100644
index 39e95bb..0000000
--- a/tests/OGLSimpleCube/OGLSimpleCube.vcxproj
+++ /dev/null
@@ -1,180 +0,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{27E15292-4A8D-4BA0-8D9B-5D1ECFF85747}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>OGLSimpleCube</RootNamespace>
-    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v141</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v141</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v141</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v141</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(SolutionDir)bin\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)obj\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(SolutionDir)bin\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)obj\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>$(SolutionDir)bin\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)obj\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LinkIncremental>false</LinkIncremental>
-    <OutDir>$(SolutionDir)bin\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>$(SolutionDir)obj\$(MSBuildProjectName)\$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>
-      </AdditionalLibraryDirectories>
-      <AdditionalDependencies>%(AdditionalDependencies);opengl32.lib</AdditionalDependencies>
-    </Link>
-    <PostBuildEvent>
-      <Command>XCOPY /Y "$(SolutionDir)out\$(Configuration)_$(Platform)\opengl32.dll" "$(SolutionDir)src\$(Configuration)\$(Platform)\" /Q /E /I</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>
-      </AdditionalLibraryDirectories>
-      <AdditionalDependencies>%(AdditionalDependencies);opengl32.lib</AdditionalDependencies>
-    </Link>
-    <PostBuildEvent>
-      <Command>XCOPY /Y "$(SolutionDir)out\$(Configuration)_$(Platform)\opengl32.dll" "$(SolutionDir)src\$(Configuration)\$(Platform)\" /Q /E /I</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>
-      </AdditionalLibraryDirectories>
-      <AdditionalDependencies>%(AdditionalDependencies);opengl32.lib</AdditionalDependencies>
-    </Link>
-    <PostBuildEvent>
-      <Command>XCOPY /Y "$(SolutionDir)out\$(Configuration)_$(Platform)\opengl32.dll" "$(SolutionDir)src\$(Configuration)\$(Platform)\" /Q /E /I</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>
-      </AdditionalLibraryDirectories>
-      <AdditionalDependencies>%(AdditionalDependencies);opengl32.lib</AdditionalDependencies>
-    </Link>
-    <PostBuildEvent>
-      <Command>XCOPY /Y "$(SolutionDir)out\$(Configuration)_$(Platform)\opengl32.dll" "$(SolutionDir)src\$(Configuration)\$(Platform)\" /Q /E /I</Command>
-    </PostBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="OGLSimpleCube.cpp" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/tests/OGLSimpleCube/OGLSimpleCube.vcxproj.filters b/tests/OGLSimpleCube/OGLSimpleCube.vcxproj.filters
deleted file mode 100644
index 1e4107f..0000000
--- a/tests/OGLSimpleCube/OGLSimpleCube.vcxproj.filters
+++ /dev/null
@@ -1,22 +0,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="OGLSimpleCube.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-</Project>
\ No newline at end of file
