diff --git a/src/OpenGL ES 2.0/libGLESv2/Device.cpp b/src/OpenGL ES 2.0/libGLESv2/Device.cpp
new file mode 100644
index 0000000..68e293f
--- /dev/null
+++ b/src/OpenGL ES 2.0/libGLESv2/Device.cpp
@@ -0,0 +1,1042 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#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/Timer.hpp"
+#include "../common/debug.h"
+
+bool localShaderConstants = true;
+
+namespace gl
+{
+	using namespace sw;
+
+	Device::Device(Context *context) : Renderer(context), context(context)
+	{
+		depthStencil = 0;
+		renderTarget = 0;
+
+		setDepthBufferEnable(true);
+		setFillMode(Context::FILL_SOLID);
+		setShadingMode(Context::SHADING_GOURAUD);
+		setDepthWriteEnable(true);
+		setAlphaTestEnable(false);
+		setSourceBlendFactor(Context::BLEND_ONE);
+		setDestBlendFactor(Context::BLEND_ZERO);
+		setCullMode(Context::CULL_COUNTERCLOCKWISE);
+		setDepthCompare(Context::DEPTH_LESSEQUAL);
+		setAlphaReference(0);
+		setAlphaCompare(Context::ALPHA_ALWAYS);
+		setAlphaBlendEnable(false);
+		setFogEnable(false);
+		setSpecularEnable(false);
+		setFogColor(0);
+		setPixelFogMode(Context::FOG_NONE);
+		setFogStart(0.0f);
+		setFogEnd(1.0f);
+		setFogDensity(1.0f);
+		setRangeFogEnable(false);
+		setStencilEnable(false);
+		setStencilFailOperation(Context::OPERATION_KEEP);
+		setStencilZFailOperation(Context::OPERATION_KEEP);
+		setStencilPassOperation(Context::OPERATION_KEEP);
+		setStencilCompare(Context::STENCIL_ALWAYS);
+		setStencilReference(0);
+		setStencilMask(0xFFFFFFFF);
+		setStencilWriteMask(0xFFFFFFFF);
+		setVertexFogMode(Context::FOG_NONE);
+		setClipFlags(0);
+		setPointSize(1.0f);
+		setPointSizeMin(1.0f);
+		setPointSpriteEnable(false);
+		setPointSizeMax(64.0f);
+		setColorWriteMask(0, 0x0000000F);
+		setBlendOperation(Context::BLENDOP_ADD);
+		scissorEnable = false;
+		setSlopeDepthBias(0.0f);
+		setTwoSidedStencil(false);
+		setStencilFailOperationCCW(Context::OPERATION_KEEP);
+		setStencilZFailOperationCCW(Context::OPERATION_KEEP);
+		setStencilPassOperationCCW(Context::OPERATION_KEEP);
+		setStencilCompareCCW(Context::STENCIL_ALWAYS);
+		setColorWriteMask(1, 0x0000000F);
+		setColorWriteMask(2, 0x0000000F);
+		setColorWriteMask(3, 0x0000000F);
+		setBlendConstant(0xFFFFFFFF);
+		setWriteSRGB(false);
+		setDepthBias(0.0f);
+		setSeparateAlphaBlendEnable(false);
+		setSourceBlendFactorAlpha(Context::BLEND_ONE);
+		setDestBlendFactorAlpha(Context::BLEND_ZERO);
+		setBlendOperationAlpha(Context::BLENDOP_ADD);
+
+		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 < 224; i++)
+		{
+			float zero[4] = {0, 0, 0, 0};
+
+			setPixelShaderConstantF(i, zero, 1);
+		}
+
+		for(int i = 0; i < 256; i++)
+		{
+			float zero[4] = {0, 0, 0, 0};
+
+			setVertexShaderConstantF(i, zero, 1);
+		}
+	}
+
+	Device::~Device()
+	{		
+		if(depthStencil)
+		{
+			depthStencil->unbind();
+			depthStencil = 0;
+		}
+		
+		if(renderTarget)
+		{
+			renderTarget->unbind();
+			renderTarget = 0;
+		}
+
+		delete context;
+	}
+
+	void Device::clearColor(unsigned int color, unsigned int rgbaMask)
+	{
+		TRACE("unsigned long color = 0x%0.8X", color);
+
+		int x = viewport.x;
+		int y = viewport.y;
+		int width = viewport.width;
+		int height = viewport.height;
+
+		// Clamp against scissor rectangle
+		if(scissorEnable)
+		{
+			if(x < scissorRect.left) x = scissorRect.left;
+			if(y < scissorRect.top) y = scissorRect.top;
+			if(width > scissorRect.right - scissorRect.left) width = scissorRect.right - scissorRect.left;
+			if(height > scissorRect.bottom - scissorRect.top) height = scissorRect.bottom - scissorRect.top;
+		}
+
+		if(renderTarget)
+		{
+			renderTarget->clearColorBuffer(color, rgbaMask, x, y, width, height);
+		}
+	}
+
+	void Device::clearDepth(float z)
+	{
+		TRACE("float z = %f", z);
+
+		if(z > 1) z = 1;
+		if(z < 0) z = 0;
+
+		int x = viewport.x;
+		int y = viewport.y;
+		int width = viewport.width;
+		int height = viewport.height;
+
+		// Clamp against scissor rectangle
+		if(scissorEnable)
+		{
+			if(x < scissorRect.left) x = scissorRect.left;
+			if(y < scissorRect.top) y = scissorRect.top;
+			if(width > scissorRect.right - scissorRect.left) width = scissorRect.right - scissorRect.left;
+			if(height > scissorRect.bottom - scissorRect.top) height = scissorRect.bottom - scissorRect.top;
+		}
+
+		if(depthStencil)
+		{
+			depthStencil->clearDepthBuffer(z, x, y, width, height);
+		}
+	}
+
+	void Device::clearStencil(unsigned int stencil, unsigned int mask)
+	{
+		TRACE("unsigned long stencil = %d", stencil);
+
+		int x = viewport.x;
+		int y = viewport.y;
+		int width = viewport.width;
+		int height = viewport.height;
+
+		// Clamp against scissor rectangle
+		if(scissorEnable)
+		{
+			if(x < scissorRect.left) x = scissorRect.left;
+			if(y < scissorRect.top) y = scissorRect.top;
+			if(width > scissorRect.right - scissorRect.left) width = scissorRect.right - scissorRect.left;
+			if(height > scissorRect.bottom - scissorRect.top) height = scissorRect.bottom - scissorRect.top;
+		}
+
+		if(depthStencil)
+		{
+			depthStencil->clearStencilBuffer(stencil, mask, x, y, width, height);
+		}
+	}
+
+	Image *Device::createDepthStencilSurface(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)
+	{
+		TRACE("unsigned int width = %d, unsigned int height = %d, sw::Format format = %d, int multiSampleDepth = %d, bool discard = %d", width, height, format, multiSampleDepth, discard);
+
+		if(width == 0 || height == 0 || height > OUTLINE_RESOLUTION)
+		{
+			ERR("Invalid parameters");
+			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_DF24:
+		case FORMAT_DF16:
+			lockable = true;
+			break;
+		default:
+			UNREACHABLE();
+		}
+
+		Image *surface = new Image(0, width, height, format, GL_NONE, GL_NONE, multiSampleDepth, lockable, true);
+
+		if(!surface)
+		{
+			ERR("Out of memory");
+			return 0;
+		}
+
+		surface->addRef();
+
+		return surface;
+	}
+
+	Image *Device::createOffscreenPlainSurface(unsigned int width, unsigned int height, sw::Format format)
+	{
+		TRACE("unsigned int width = %d, unsigned int height = %d, sw::Format format = %d", width, height, format);
+		
+		Image *surface = new Image(0, width, height, format, GL_NONE, GL_NONE, 1, true, false);
+
+		if(!surface)
+		{
+			ERR("Out of memory");
+			return 0;
+		}
+
+		surface->addRef();
+
+		return surface;
+	}
+
+	Image *Device::createRenderTarget(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool lockable)
+	{
+		TRACE("unsigned int width = %d, unsigned int height = %d, sw::Format format = %d, int multiSampleDepth = %d, bool lockable = %d", width, height, format, multiSampleDepth, lockable);
+
+		if(height > OUTLINE_RESOLUTION)
+		{
+			ERR("Invalid parameters");
+			return 0;
+		}
+
+		Image *surface = new Image(0, width, height, format, GL_NONE, GL_NONE, multiSampleDepth, lockable != FALSE, true);
+
+		if(!surface)
+		{
+			ERR("Out of memory");
+			return 0;
+		}
+
+		surface->addRef();
+		
+		return surface;
+	}
+
+	void Device::drawIndexedPrimitive(PrimitiveType type, unsigned int indexOffset, unsigned int primitiveCount, int indexSize)
+	{
+		TRACE("");
+
+		if(!bindResources() || !primitiveCount)
+		{
+			return;
+		}
+
+		Context::DrawType drawType;
+
+		if(indexSize == 4)
+		{
+			switch(type)
+			{
+			case DRAW_POINTLIST:     drawType = Context::DRAW_INDEXEDPOINTLIST32;     break;
+			case DRAW_LINELIST:      drawType = Context::DRAW_INDEXEDLINELIST32;      break;
+			case DRAW_LINESTRIP:     drawType = Context::DRAW_INDEXEDLINESTRIP32;     break;
+			case DRAW_LINELOOP:      drawType = Context::DRAW_INDEXEDLINELOOP32;      break;
+			case DRAW_TRIANGLELIST:  drawType = Context::DRAW_INDEXEDTRIANGLELIST32;  break;
+			case DRAW_TRIANGLESTRIP: drawType = Context::DRAW_INDEXEDTRIANGLESTRIP32; break;
+			case DRAW_TRIANGLEFAN:   drawType = Context::DRAW_INDEXEDTRIANGLEFAN32;	  break;
+			default: UNREACHABLE();
+			}
+		}
+		else if(indexSize == 2)
+		{
+			switch(type)
+			{
+			case DRAW_POINTLIST:     drawType = Context::DRAW_INDEXEDPOINTLIST16;     break;
+			case DRAW_LINELIST:      drawType = Context::DRAW_INDEXEDLINELIST16;      break;
+			case DRAW_LINESTRIP:     drawType = Context::DRAW_INDEXEDLINESTRIP16;     break;
+			case DRAW_LINELOOP:      drawType = Context::DRAW_INDEXEDLINELOOP16;      break;
+			case DRAW_TRIANGLELIST:  drawType = Context::DRAW_INDEXEDTRIANGLELIST16;  break;
+			case DRAW_TRIANGLESTRIP: drawType = Context::DRAW_INDEXEDTRIANGLESTRIP16; break;
+			case DRAW_TRIANGLEFAN:   drawType = Context::DRAW_INDEXEDTRIANGLEFAN16;   break;
+			default: UNREACHABLE();
+			}
+		}
+		else if(indexSize == 1)
+		{
+			switch(type)
+			{
+			case DRAW_POINTLIST:     drawType = Context::DRAW_INDEXEDPOINTLIST8;     break;
+			case DRAW_LINELIST:      drawType = Context::DRAW_INDEXEDLINELIST8;      break;
+			case DRAW_LINESTRIP:     drawType = Context::DRAW_INDEXEDLINESTRIP8;     break;
+			case DRAW_LINELOOP:      drawType = Context::DRAW_INDEXEDLINELOOP8;      break;
+			case DRAW_TRIANGLELIST:  drawType = Context::DRAW_INDEXEDTRIANGLELIST8;  break;
+			case DRAW_TRIANGLESTRIP: drawType = Context::DRAW_INDEXEDTRIANGLESTRIP8; break;
+			case DRAW_TRIANGLEFAN:   drawType = Context::DRAW_INDEXEDTRIANGLEFAN8;   break;
+			default: UNREACHABLE();
+			}
+		}
+		else UNREACHABLE();
+
+		draw(drawType, indexOffset, primitiveCount);
+	}
+
+	void Device::drawPrimitive(PrimitiveType primitiveType, unsigned int primitiveCount)
+	{
+		TRACE("");
+
+		if(!bindResources() || !primitiveCount)
+		{
+			return;
+		}
+
+		setIndexBuffer(0);
+		
+		Context::DrawType drawType;
+
+		switch(primitiveType)
+		{
+		case DRAW_POINTLIST:     drawType = Context::DRAW_POINTLIST;     break;
+		case DRAW_LINELIST:      drawType = Context::DRAW_LINELIST;      break;
+		case DRAW_LINESTRIP:     drawType = Context::DRAW_LINESTRIP;     break;
+		case DRAW_LINELOOP:      drawType = Context::DRAW_LINELOOP;      break;
+		case DRAW_TRIANGLELIST:  drawType = Context::DRAW_TRIANGLELIST;  break;
+		case DRAW_TRIANGLESTRIP: drawType = Context::DRAW_TRIANGLESTRIP; break;
+		case DRAW_TRIANGLEFAN:   drawType = Context::DRAW_TRIANGLEFAN;   break;
+		default: UNREACHABLE();
+		}
+
+		draw(drawType, 0, primitiveCount);
+	}
+
+	Image *Device::getDepthStencilSurface()
+	{
+		TRACE("void");
+
+		if(depthStencil)
+		{
+			depthStencil->addRef();
+		}
+
+		return depthStencil;
+	}
+
+	bool Device::getRenderTargetData(Image *renderTarget, Image *destSurface)
+	{
+		TRACE("Image *renderTarget = 0x%0.8p, Image *destSurface = 0x%0.8p", renderTarget, destSurface);
+
+		if(!renderTarget || !destSurface)
+		{
+			ERR("Invalid parameters");
+			return false;
+		}
+		
+		if(renderTarget->getWidth()  != destSurface->getWidth() ||
+		   renderTarget->getHeight() != destSurface->getHeight() ||
+		   renderTarget->getInternalFormat() != destSurface->getInternalFormat())
+		{
+			ERR("Invalid parameters");
+			return false;
+		}
+
+		static void (__cdecl *blitFunction)(void *dst, void *src);
+		static Routine *blitRoutine;
+		static BlitState blitState = {0};
+
+		BlitState update;
+		update.width = renderTarget->getInternalWidth();
+		update.height = renderTarget->getInternalHeight();
+		update.depth = 32;
+		update.stride = destSurface->getInternalPitchB();
+		update.HDR = false;
+		update.cursorHeight = 0;
+		update.cursorWidth = 0;
+		
+		if(memcmp(&blitState, &update, sizeof(BlitState)) != 0)
+		{
+			blitState = update;
+			delete blitRoutine;
+
+			blitRoutine = FrameBuffer::copyRoutine(blitState);
+			blitFunction = (void(__cdecl*)(void*, void*))blitRoutine->getEntry();
+		}
+
+		void *dst = destSurface->lockInternal(0, 0, 0, LOCK_WRITEONLY, PUBLIC);
+		void *src = renderTarget->lockInternal(0, 0, 0, LOCK_WRITEONLY, PUBLIC);
+
+		blitFunction(dst, src);
+
+		destSurface->unlockInternal();
+		renderTarget->unlockInternal();
+
+		return true;
+	}
+
+	void Device::setDepthStencilSurface(Image *depthStencil)
+	{
+		TRACE("Image *newDepthStencil = 0x%0.8p", depthStencil);
+
+		if(this->depthStencil == depthStencil)
+		{
+			return;
+		}
+
+		if(depthStencil)
+		{
+			depthStencil->bind();
+		}
+
+		if(this->depthStencil)
+		{
+			this->depthStencil->unbind();
+		}
+
+		this->depthStencil = depthStencil;
+
+		setDepthStencil(depthStencil);
+	}
+
+	void Device::setPixelShader(PixelShader *pixelShader)
+	{
+		TRACE("PixelShader *shader = 0x%0.8p", pixelShader);
+
+		this->pixelShader = pixelShader;
+		pixelShaderDirty = true;
+	}
+
+	void Device::setPixelShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+	{
+		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		for(unsigned int i = 0; i < count && startRegister + i < 224; 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(Image *iRenderTarget)
+	{
+		TRACE("Image *newRenderTarget = 0x%0.8p", iRenderTarget);
+
+		Image *renderTarget = static_cast<Image*>(iRenderTarget);
+
+		if(renderTarget)
+		{
+			renderTarget->bind();
+		}
+
+		if(this->renderTarget)
+		{
+			this->renderTarget->unbind();
+		}
+
+		this->renderTarget = renderTarget;
+
+		if(renderTarget)
+		{
+			// Reset viewport to size of current render target
+			viewport.x = 0;
+			viewport.y = 0;
+			viewport.width = renderTarget->getWidth();
+			viewport.height = renderTarget->getHeight();
+			viewport.minZ = 0;
+			viewport.maxZ = 1;
+
+			// Reset scissor rectangle to size of current render target
+			scissorRect.left = 0;
+			scissorRect.top = 0;
+			scissorRect.right = renderTarget->getWidth();
+			scissorRect.bottom = renderTarget->getHeight();
+		}
+
+		Renderer::setRenderTarget(0, renderTarget);
+	}
+
+	void Device::setScissorRect(const sw::Rect &rect)
+	{
+		TRACE("const sw::Rect *rect = 0x%0.8p", rect);
+
+		scissorRect = rect;
+	}
+
+	void Device::setVertexShader(VertexShader *vertexShader)
+	{
+		TRACE("VertexShader *shader = 0x%0.8p", vertexShader);
+
+		this->vertexShader = vertexShader;
+		vertexShaderDirty = true;
+	}
+
+	void Device::setVertexShaderConstantF(unsigned int startRegister, const float *constantData, unsigned int count)
+	{
+		TRACE("unsigned int startRegister = %d, const int *constantData = 0x%0.8p, unsigned int count = %d", startRegister, constantData, count);
+
+		for(unsigned int i = 0; i < count && startRegister + i < 256; 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)
+	{
+		TRACE("const Viewport *viewport = 0x%0.8p", viewport);
+
+		this->viewport = viewport;
+	}
+
+	bool Device::stretchRect(Image *sourceSurface, const sw::Rect *sourceRect, Image *destSurface, const sw::Rect *destRect, bool filter)
+	{
+		TRACE("Image *sourceSurface = 0x%0.8p, const sw::Rect *sourceRect = 0x%0.8p, Image *destSurface = 0x%0.8p, const sw::Rect *destRect = 0x%0.8p, bool filter = %d", sourceSurface, sourceRect, destSurface, destRect, filter);
+
+		if(!sourceSurface || !destSurface || !validRectangle(sourceRect, sourceSurface) || !validRectangle(destRect, destSurface))
+		{
+			ERR("Invalid parameters");
+			return false;
+		}
+		
+		Image *source = static_cast<Image*>(sourceSurface);
+		Image *dest = static_cast<Image*>(destSurface);
+
+		int sWidth = source->getExternalWidth();
+		int sHeight = source->getExternalHeight();
+		int dWidth = dest->getExternalWidth();
+		int dHeight = dest->getExternalHeight();
+
+		Rect sRect;
+		Rect dRect;
+
+		if(sourceRect)
+		{
+			sRect = *sourceRect;
+		}
+		else
+		{
+			sRect.top = 0;
+			sRect.left = 0;
+			sRect.bottom = sHeight;
+			sRect.right = sWidth;
+		}
+
+		if(destRect)
+		{
+			dRect = *destRect;
+		}
+		else
+		{
+			dRect.top = 0;
+			dRect.left = 0;
+			dRect.bottom = dHeight;
+			dRect.right = dWidth;
+		}
+
+		bool scaling = (sRect.right - sRect.left != dRect.right - dRect.left) || (sRect.bottom - sRect.top != dRect.bottom - dRect.top);
+		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, 0, LOCK_READONLY, PUBLIC);
+				sw::byte *destBuffer = (sw::byte*)dest->lockInternal(0, 0, 0, LOCK_DISCARD, PUBLIC);
+
+				unsigned int width = source->getInternalWidth();
+				unsigned int height = source->getInternalHeight();
+				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, PUBLIC);
+				sw::byte *destBuffer = (sw::byte*)dest->lockStencil(0, PUBLIC);
+
+				unsigned int width = source->getInternalWidth();
+				unsigned int height = source->getInternalHeight();
+				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.left, sRect.top, 0, LOCK_READONLY, PUBLIC);
+			unsigned char *destBytes = (unsigned char*)dest->lockInternal(dRect.left, dRect.top, 0, LOCK_READWRITE, PUBLIC);
+			unsigned int sourcePitch = source->getInternalPitchB();
+			unsigned int destPitch = dest->getInternalPitchB();
+
+			unsigned int width = dRect.right - dRect.left;
+			unsigned int height = dRect.bottom - dRect.top;
+			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
+		{
+			blit(source, sRect, dest, dRect, scaling && filter);
+		}
+
+		return true;
+	}
+
+	bool Device::updateSurface(Image *sourceSurface, const sw::Rect *sourceRect, Image *destinationSurface, const POINT *destPoint)
+	{
+		TRACE("Image *sourceSurface = 0x%0.8p, const sw::Rect *sourceRect = 0x%0.8p, Image *destinationSurface = 0x%0.8p, const POINT *destPoint = 0x%0.8p", sourceSurface, sourceRect, destinationSurface, destPoint);
+
+		if(!sourceSurface || !destinationSurface)
+		{
+			ERR("Invalid parameters");
+			return false;
+		}
+
+		Rect sRect;
+		Rect dRect;
+		
+		if(sourceRect)
+		{
+			sRect.left = sourceRect->left;
+			sRect.top = sourceRect->top;
+			sRect.right = sourceRect->right;
+			sRect.bottom = sourceRect->bottom;
+		}
+		else
+		{
+			sRect.left = 0;
+			sRect.top = 0;
+			sRect.right = sourceSurface->getWidth();
+			sRect.bottom = sourceSurface->getHeight();
+		}
+
+		if(destPoint)
+		{
+			dRect.left = destPoint->x;
+			dRect.top = destPoint->y;
+			dRect.right = destPoint->x + sRect.right - sRect.left;
+			dRect.bottom = destPoint->y + sRect.bottom - sRect.top;
+		}
+		else
+		{
+			dRect.left = 0;
+			dRect.top = 0;
+			dRect.right = sRect.right - sRect.left;
+			dRect.bottom = sRect.bottom - sRect.top;
+		}
+
+		if(!validRectangle(&sRect, sourceSurface) || !validRectangle(&dRect, destinationSurface))
+		{
+			ERR("Invalid parameters");
+			return false;
+		}
+
+		int sWidth = sRect.right - sRect.left;
+		int sHeight = sRect.bottom - sRect.top;
+
+		int dWidth = dRect.right - dRect.left;
+		int dHeight = dRect.bottom - dRect.top;
+
+		if(sourceSurface->getMultiSampleDepth() > 1 ||
+		   destinationSurface->getMultiSampleDepth() > 1 ||
+		   sourceSurface->getInternalFormat() != destinationSurface->getInternalFormat())
+		{
+			ERR("Invalid parameters");
+			return false;
+		}
+		
+		unsigned char *sourceBuffer = (unsigned char*)sourceSurface->lock(sRect.left, sRect.top, LOCK_READONLY);
+		unsigned char *destinationBuffer = (unsigned char*)destinationSurface->lock(dRect.left, dRect.top, LOCK_WRITEONLY);
+
+		unsigned int width;
+		unsigned int height;
+		unsigned int bytes;
+
+		switch(sourceSurface->getInternalFormat())
+		{
+		#if S3TC_SUPPORT
+		case FORMAT_DXT1:
+		case FORMAT_ATI1:
+			width = (dWidth + 3) / 4;
+			height = (dHeight + 3) / 4;
+			bytes = width * 8;   // 64 bit per 4x4 block
+			break;
+	//	case FORMAT_DXT2:
+		case FORMAT_DXT3:
+	//	case FORMAT_DXT4:
+		case FORMAT_DXT5:
+		case FORMAT_ATI2:
+			width = (dWidth + 3) / 4;
+			height = (dHeight + 3) / 4;
+			bytes = width * 16;   // 128 bit per 4x4 block
+			break;
+		#endif
+		default:
+			width = dWidth;
+			height = dHeight;
+			bytes = width * Image::bytes(sourceSurface->getInternalFormat());
+		}
+
+		int sourcePitch = sourceSurface->getPitch();
+		int destinationPitch = destinationSurface->getPitch();
+
+		#if S3TC_SUPPORT
+		if(sourceSurface->getInternalFormat() == FORMAT_ATI1 || sourceSurface->getInternalFormat() == FORMAT_ATI2)
+		{
+			// Make the pitch correspond to 4 rows
+			sourcePitch *= 4;
+			destinationPitch *= 4;
+		}
+		#endif
+
+		for(unsigned int y = 0; y < height; y++)
+		{
+			memcpy(destinationBuffer, sourceBuffer, bytes);
+			
+			sourceBuffer += sourcePitch;
+			destinationBuffer += destinationPitch;
+		}
+
+		sourceSurface->unlock();
+		destinationSurface->unlock();
+		
+		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)
+		{
+			Rect scissor = scissorRect;
+
+			long viewportLeft = viewport.x;
+			long viewportRight = viewport.x + viewport.width;
+			long viewportTop = viewport.y;
+			long viewportBottom = viewport.y + viewport.height;
+
+			// Intersection of scissor rectangle and viewport
+			if(viewportLeft > scissor.left) scissor.left = viewportLeft;
+			if(viewportTop > scissor.top) scissor.top = viewportTop;
+			if(viewportRight < scissor.right) scissor.right = viewportRight;
+			if(viewportBottom < scissor.bottom) scissor.bottom = viewportBottom;
+
+			if(scissor.left == scissor.right ||
+			   scissor.top == scissor.bottom)
+			{
+				return false;
+			}
+
+			// Dimensions of scissor rectangle relative to viewport
+			float relativeLeft = (float)(scissor.left - viewportLeft) / viewport.width;
+			float relativeRight = (float)(scissor.right - viewportLeft) / viewport.width;
+			float relativeTop = (float)(scissor.top - viewportTop) / viewport.height;
+			float relativeBottom = (float)(scissor.bottom - viewportTop) / viewport.height;
+
+			// Transformation of clip space coordinates
+			float sX = 1.0f / (relativeRight - relativeLeft);   // Scale
+			float tX = sX * ((0.5f - relativeLeft) - (relativeRight - 0.5f));   // Translate
+			float sY = 1.0f / (relativeBottom - relativeTop);   // Scale
+			float tY = sY * ((0.5f - relativeTop) - (relativeBottom - 0.5f));   // Translate
+
+			// Set the new viewport
+			sw::Viewport view;
+
+			view.setLeft((float)scissor.left);
+			view.setTop((float)scissor.top);
+			view.setWidth((float)(scissor.right - scissor.left));
+			view.setHeight((float)(scissor.bottom - scissor.top));
+
+			view.setNear(viewport.minZ);
+			view.setFar(viewport.maxZ);
+
+			Renderer::setViewport(view);
+			setPostTransformEnable(true);
+			setPosScale(sX, sY);
+			setPosOffset(tX, -tY);
+		}
+		else
+		{
+			// Set viewport
+			sw::Viewport view;
+
+			view.setLeft((float)viewport.x);
+			view.setTop((float)viewport.y);
+			view.setWidth((float)viewport.width);
+			view.setHeight((float)viewport.height);
+
+			view.setNear(viewport.minZ);
+			view.setFar(viewport.maxZ);
+
+			Renderer::setViewport(view);
+			setPostTransformEnable(false);
+		}
+
+		return true;
+	}
+
+	bool Device::validRectangle(const sw::Rect *rect, Image *surface)
+	{
+		if(!rect)
+		{
+			return true;
+		}
+
+		if(rect->right <= rect->left || rect->bottom <= rect->top)
+		{
+			return false;
+		}
+
+		if(rect->left < 0 || rect->top < 0)
+		{
+			return false;
+		}
+
+		if(rect->right > (int)surface->getWidth() || rect->bottom > (int)surface->getHeight())
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	void Device::finish()
+	{
+		if(renderTarget)
+		{
+			renderTarget->lock(0, 0, sw::LOCK_READWRITE);
+			renderTarget->unlock();
+		}
+	}
+}
+
+extern "C"
+{
+	gl::Device *createDevice()
+	{
+		sw::Context *context = new sw::Context();
+
+		if(context)
+		{
+			return new gl::Device(context);
+		}
+
+		return 0;
+	}
+}
\ No newline at end of file
