Texture load functionality for integer types

- Added cases required to load integer type textures into
  swiftshader's internal formats.
- Cleaned up copy functions that simply perform a memcpy
  for a given number of bytes per row.
- Removed unused functionality for mini floats. Right now,
  all we need is the ability to import these formats, so
  there's currently no need to keep the export code.

Change-Id: I61500c41e668f885d3ec1e687b6f888c117221f2
Reviewed-on: https://swiftshader-review.googlesource.com/4140
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/common/Image.cpp b/src/OpenGL/common/Image.cpp
index b77f6a7..04914c8 100644
--- a/src/OpenGL/common/Image.cpp
+++ b/src/OpenGL/common/Image.cpp
@@ -14,6 +14,7 @@
 #include "Renderer/Blitter.hpp"
 #include "../libEGL/Texture.hpp"
 #include "../common/debug.h"
+#include "Common/Math.hpp"
 #include "Common/Thread.hpp"
 
 #include <GLES/glext.h>
@@ -31,28 +32,39 @@
 
 	enum DataType
 	{
-		Alpha,
+		Bytes_1,
+		Bytes_2,
+		Bytes_4,
+		Bytes_8,
+		Bytes_16,
 		AlphaFloat,
 		AlphaHalfFloat,
-		Luminance,
 		LuminanceFloat,
 		LuminanceHalfFloat,
-		LuminanceAlpha,
 		LuminanceAlphaFloat,
 		LuminanceAlphaHalfFloat,
+		ByteRGB,
 		UByteRGB,
+		ShortRGB,
+		UShortRGB,
+		IntRGB,
+		UIntRGB,
 		RGB565,
 		FloatRGB,
 		HalfFloatRGB,
-		UByte4,
 		RGBA4444,
 		RGBA5551,
-		Float4,
-		HalfFloat4,
+		RGB10A2UI,
+		R11G11B10F,
+		RGB9E5,
+		SRGB,
+		SRGBA,
 		D16,
 		D24,
 		D32,
+		D32F,
 		S8,
+		S24_8,
 	};
 
 	template<DataType dataType>
@@ -62,12 +74,36 @@
 	}
 
 	template<>
-	void LoadImageRow<Alpha>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	void LoadImageRow<Bytes_1>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		memcpy(dest + xoffset, source, width);
 	}
 
 	template<>
+	void LoadImageRow<Bytes_2>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		memcpy(dest + xoffset * 2, source, width * 2);
+	}
+
+	template<>
+	void LoadImageRow<Bytes_4>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		memcpy(dest + xoffset * 4, source, width * 4);
+	}
+
+	template<>
+	void LoadImageRow<Bytes_8>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		memcpy(dest + xoffset * 8, source, width * 8);
+	}
+
+	template<>
+	void LoadImageRow<Bytes_16>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		memcpy(dest + xoffset * 16, source, width * 16);
+	}
+
+	template<>
 	void LoadImageRow<AlphaFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const float *sourceF = reinterpret_cast<const float*>(source);
@@ -98,12 +134,6 @@
 	}
 
 	template<>
-	void LoadImageRow<Luminance>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
-	{
-		memcpy(dest + xoffset, source, width);
-	}
-
-	template<>
 	void LoadImageRow<LuminanceFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const float *sourceF = reinterpret_cast<const float*>(source);
@@ -134,12 +164,6 @@
 	}
 
 	template<>
-	void LoadImageRow<LuminanceAlpha>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
-	{
-		memcpy(dest + xoffset * 2, source, width * 2);
-	}
-
-	template<>
 	void LoadImageRow<LuminanceAlphaFloat>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const float *sourceF = reinterpret_cast<const float*>(source);
@@ -170,6 +194,20 @@
 	}
 
 	template<>
+	void LoadImageRow<ByteRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		unsigned char *destB = dest + xoffset * 4;
+
+		for(int x = 0; x < width; x++)
+		{
+			destB[4 * x + 0] = source[x * 3 + 0];
+			destB[4 * x + 1] = source[x * 3 + 1];
+			destB[4 * x + 2] = source[x * 3 + 2];
+			destB[4 * x + 3] = 0x7F;
+		}
+	}
+
+	template<>
 	void LoadImageRow<UByteRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		unsigned char *destB = dest + xoffset * 4;
@@ -184,6 +222,66 @@
 	}
 
 	template<>
+	void LoadImageRow<ShortRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		const unsigned short *sourceS = reinterpret_cast<const unsigned short*>(source);
+		unsigned short *destS = reinterpret_cast<unsigned short*>(dest + xoffset * 8);
+
+		for(int x = 0; x < width; x++)
+		{
+			destS[4 * x + 0] = sourceS[x * 3 + 0];
+			destS[4 * x + 1] = sourceS[x * 3 + 1];
+			destS[4 * x + 2] = sourceS[x * 3 + 2];
+			destS[4 * x + 3] = 0x7FFF;
+		}
+	}
+
+	template<>
+	void LoadImageRow<UShortRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		const unsigned short *sourceS = reinterpret_cast<const unsigned short*>(source);
+		unsigned short *destS = reinterpret_cast<unsigned short*>(dest + xoffset * 8);
+
+		for(int x = 0; x < width; x++)
+		{
+			destS[4 * x + 0] = sourceS[x * 3 + 0];
+			destS[4 * x + 1] = sourceS[x * 3 + 1];
+			destS[4 * x + 2] = sourceS[x * 3 + 2];
+			destS[4 * x + 3] = 0xFFFF;
+		}
+	}
+
+	template<>
+	void LoadImageRow<IntRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
+		unsigned int *destI = reinterpret_cast<unsigned int*>(dest + xoffset * 16);
+
+		for(int x = 0; x < width; x++)
+		{
+			destI[4 * x + 0] = sourceI[x * 3 + 0];
+			destI[4 * x + 1] = sourceI[x * 3 + 1];
+			destI[4 * x + 2] = sourceI[x * 3 + 2];
+			destI[4 * x + 3] = 0x7FFFFFFF;
+		}
+	}
+
+	template<>
+	void LoadImageRow<UIntRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		const unsigned int *sourceI = reinterpret_cast<const unsigned int*>(source);
+		unsigned int *destI = reinterpret_cast<unsigned int*>(dest + xoffset * 16);
+
+		for(int x = 0; x < width; x++)
+		{
+			destI[4 * x + 0] = sourceI[x * 3 + 0];
+			destI[4 * x + 1] = sourceI[x * 3 + 1];
+			destI[4 * x + 2] = sourceI[x * 3 + 2];
+			destI[4 * x + 3] = 0xFFFFFFFF;
+		}
+	}
+
+	template<>
 	void LoadImageRow<RGB565>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		memcpy(dest + xoffset * 2, source, width * 2);
@@ -220,12 +318,6 @@
 	}
 
 	template<>
-	void LoadImageRow<UByte4>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
-	{
-		memcpy(dest + xoffset * 4, source, width * 4);
-	}
-
-	template<>
 	void LoadImageRow<RGBA4444>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
 		const unsigned short *source4444 = reinterpret_cast<const unsigned short*>(source);
@@ -258,15 +350,75 @@
 	}
 
 	template<>
-	void LoadImageRow<Float4>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	void LoadImageRow<RGB10A2UI>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
-		memcpy(dest + xoffset * 16, source, width * 16);
+		const unsigned int *source1010102U = reinterpret_cast<const unsigned int*>(source);
+		unsigned short *dest16U = reinterpret_cast<unsigned short*>(dest + xoffset * 8);
+
+		for(int x = 0; x < width; x++)
+		{
+			unsigned int rgba = source1010102U[x];
+			dest16U[4 * x + 0] = (rgba & 0x00000FFC) >> 2;
+			dest16U[4 * x + 1] = (rgba & 0x003FF000) >> 12;
+			dest16U[4 * x + 2] = (rgba & 0xFFC00000) >> 22;
+			dest16U[4 * x + 3] = (rgba & 0x00000003);
+		}
 	}
 
 	template<>
-	void LoadImageRow<HalfFloat4>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	void LoadImageRow<R11G11B10F>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
 	{
-		memcpy(dest + xoffset * 8, source, width * 8);
+		const sw::R11G11B10FData *sourceRGB = reinterpret_cast<const sw::R11G11B10FData*>(source);
+		float *destF = reinterpret_cast<float*>(dest + xoffset * 16);
+
+		for(int x = 0; x < width; x++, sourceRGB++, destF+=4)
+		{
+			sourceRGB->toRGBFloats(destF);
+			destF[3] = 1.0f;
+		}
+	}
+
+	template<>
+	void LoadImageRow<RGB9E5>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		const sw::RGB9E5Data *sourceRGB = reinterpret_cast<const sw::RGB9E5Data*>(source);
+		float *destF = reinterpret_cast<float*>(dest + xoffset * 16);
+
+		for(int x = 0; x < width; x++, sourceRGB++, destF += 4)
+		{
+			sourceRGB->toRGBFloats(destF);
+			destF[3] = 1.0f;
+		}
+	}
+
+	template<>
+	void LoadImageRow<SRGB>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		dest += xoffset * 4;
+
+		for(int x = 0; x < width; x++)
+		{
+			for(int rgb = 0; rgb < 3; ++rgb)
+			{
+				*dest++ = sw::sRGB8toLinear8(*source++);
+			}
+			*dest++ = 255;
+		}
+	}
+
+	template<>
+	void LoadImageRow<SRGBA>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		dest += xoffset * 4;
+
+		for(int x = 0; x < width; x++)
+		{
+			for(int rgb = 0; rgb < 3; ++rgb)
+			{
+				*dest++ = sw::sRGB8toLinear8(*source++);
+			}
+			*dest++ = *source++;
+		}
 	}
 
 	template<>
@@ -317,6 +469,32 @@
 		}
 	}
 
+	template<>
+	void LoadImageRow<D32F>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		struct D32FS8 { float depth32f; unsigned int stencil24_8; };
+		const D32FS8 *sourceD32FS8 = reinterpret_cast<const D32FS8*>(source);
+		float *destF = reinterpret_cast<float*>(dest + xoffset * 4);
+
+		for(int x = 0; x < width; x++)
+		{
+			destF[x] = sourceD32FS8[x].depth32f;
+		}
+	}
+
+	template<>
+	void LoadImageRow<S24_8>(const unsigned char *source, unsigned char *dest, GLint xoffset, GLsizei width)
+	{
+		struct D32FS8 { float depth32f; unsigned int stencil24_8; };
+		const D32FS8 *sourceD32FS8 = reinterpret_cast<const D32FS8*>(source);
+		unsigned char *destI = dest + xoffset;
+
+		for(int x = 0; x < width; x++)
+		{
+			destI[x] = static_cast<unsigned char>(sourceD32FS8[x].stencil24_8 & 0x000000FF);   // FIXME: Quad layout
+		}
+	}
+
 	template<DataType dataType>
 	void LoadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, int destPitch, GLsizei destHeight, const void *input, void *buffer)
 	{
@@ -351,6 +529,12 @@
 			default: UNREACHABLE(type);
 			}
 			break;
+		case GL_LUMINANCE8_EXT:
+			return sw::FORMAT_L8;
+		case GL_LUMINANCE16F_EXT:
+			return sw::FORMAT_L16F;
+		case GL_LUMINANCE32F_EXT:
+			return sw::FORMAT_L32F;
 		case GL_LUMINANCE_ALPHA:
 			switch(type)
 			{
@@ -361,6 +545,12 @@
 			default: UNREACHABLE(type);
 			}
 			break;
+		case GL_LUMINANCE8_ALPHA8_EXT:
+			return sw::FORMAT_A8L8;
+		case GL_LUMINANCE_ALPHA16F_EXT:
+			return sw::FORMAT_A16L16F;
+		case GL_LUMINANCE_ALPHA32F_EXT:
+			return sw::FORMAT_A32L32F;
 		case GL_RGBA:
 			switch(type)
 			{
@@ -401,6 +591,12 @@
 			default: UNREACHABLE(type);
 			}
 			break;
+		case GL_ALPHA8_EXT:
+			return sw::FORMAT_A8;
+		case GL_ALPHA16F_EXT:
+			return sw::FORMAT_A16F;
+		case GL_ALPHA32F_EXT:
+			return sw::FORMAT_A32F;
 		default:
 			UNREACHABLE(format);
 		}
@@ -503,85 +699,248 @@
 			break;
 		}
 
-		if(type == GL_FLOAT)
+		switch(type)
 		{
+		case GL_FLOAT:
+			switch(format)
+			{
+			case GL_RED:
+			case GL_R32F:
+				return sw::FORMAT_R32F;
+			case GL_RG:
+			case GL_RG32F:
+				return sw::FORMAT_G32R32F;
+			case GL_RGB:
+			case GL_RGB32F:
+			case GL_RGBA:
+			case GL_RGBA32F:
 			return sw::FORMAT_A32B32G32R32F;
-		}
-		else if(type == GL_HALF_FLOAT || type == GL_HALF_FLOAT_OES)
-		{
+			case GL_DEPTH_COMPONENT:
+			case GL_DEPTH_COMPONENT32F:
+				return sw::FORMAT_D32F;
+			default:
+				UNREACHABLE(format);
+			}
+		case GL_HALF_FLOAT:
+		case GL_HALF_FLOAT_OES:
+			switch(format)
+			{
+			case GL_RED:
+			case GL_R16F:
+				return sw::FORMAT_R16F;
+			case GL_RG:
+			case GL_RG16F:
+				return sw::FORMAT_G16R16F;
+			case GL_RGB:
+			case GL_RGB16F:
+			case GL_RGBA:
+			case GL_RGBA16F:
 			return sw::FORMAT_A16B16G16R16F;
-		}
-		else if(type == GL_UNSIGNED_BYTE)
-		{
-			if(format == GL_LUMINANCE)
+			default:
+				UNREACHABLE(format);
+			}
+		case GL_BYTE:
+			switch(format)
 			{
+			case GL_R8_SNORM:
+			case GL_R8:
+			case GL_RED:
+				return sw::FORMAT_R8I_SNORM;
+			case GL_R8I:
+			case GL_RED_INTEGER:
+				return sw::FORMAT_R8I;
+			case GL_RG8_SNORM:
+			case GL_RG8:
+			case GL_RG:
+				return sw::FORMAT_G8R8I_SNORM;
+			case GL_RG8I:
+			case GL_RG_INTEGER:
+				return sw::FORMAT_G8R8I;
+			case GL_RGB8_SNORM:
+			case GL_RGB8:
+			case GL_RGB:
+				return sw::FORMAT_X8B8G8R8I_SNORM;
+			case GL_RGB8I:
+			case GL_RGB_INTEGER:
+				return sw::FORMAT_X8B8G8R8I;
+			case GL_RGBA8_SNORM:
+			case GL_RGBA8:
+			case GL_RGBA:
+				return sw::FORMAT_A8B8G8R8I_SNORM;
+			case GL_RGBA8I:
+			case GL_RGBA_INTEGER:
+				return sw::FORMAT_A8B8G8R8I;
+			default:
+				UNREACHABLE(format);
+			}
+		case GL_UNSIGNED_BYTE:
+			switch(format)
+			{
+			case GL_LUMINANCE:
+			case GL_LUMINANCE8_EXT:
 				return sw::FORMAT_L8;
-			}
-			else if(format == GL_LUMINANCE_ALPHA)
-			{
+			case GL_LUMINANCE_ALPHA:
+			case GL_LUMINANCE8_ALPHA8_EXT:
 				return sw::FORMAT_A8L8;
-			}
-			else if(format == GL_RGBA)
-			{
-				return sw::FORMAT_A8B8G8R8;
-			}
-			else if(format == GL_BGRA_EXT)
-			{
-				return sw::FORMAT_A8R8G8B8;
-			}
-			else if(format == GL_RGB)
-			{
+			case GL_R8_SNORM:
+			case GL_R8:
+			case GL_RED:
+				return sw::FORMAT_R8;
+			case GL_R8UI:
+			case GL_RED_INTEGER:
+				return sw::FORMAT_R8UI;
+			case GL_RG8_SNORM:
+			case GL_RG8:
+			case GL_RG:
+				return sw::FORMAT_G8R8;
+			case GL_RG8UI:
+			case GL_RG_INTEGER:
+				return sw::FORMAT_G8R8UI;
+			case GL_RGB8_SNORM:
+			case GL_RGB8:
+			case GL_RGB:
+			case GL_SRGB8:
 				return sw::FORMAT_X8B8G8R8;
-			}
-			else if(format == GL_ALPHA)
-			{
+			case GL_RGB8UI:
+			case GL_RGB_INTEGER:
+				return sw::FORMAT_X8B8G8R8UI;
+			case GL_RGBA8_SNORM:
+			case GL_RGBA8:
+			case GL_RGBA:
+			case GL_SRGB8_ALPHA8:
+				return sw::FORMAT_A8B8G8R8;
+			case GL_RGBA8UI:
+			case GL_RGBA_INTEGER:
+				return sw::FORMAT_A8B8G8R8UI;
+			case GL_BGRA_EXT:
+				return sw::FORMAT_A8R8G8B8;
+			case GL_ALPHA:
+			case GL_ALPHA8_EXT:
 				return sw::FORMAT_A8;
+			default:
+				UNREACHABLE(format);
 			}
-			else if(format == SW_YV12_BT601)
+		case GL_SHORT:
+			switch(format)
 			{
-				return sw::FORMAT_YV12_BT601;
+			case GL_R16I:
+			case GL_RED_INTEGER:
+				return sw::FORMAT_R16I;
+			case GL_RG16I:
+			case GL_RG_INTEGER:
+				return sw::FORMAT_G16R16I;
+			case GL_RGB16I:
+			case GL_RGB_INTEGER:
+				return sw::FORMAT_X16B16G16R16I;
+			case GL_RGBA16I:
+			case GL_RGBA_INTEGER:
+				return sw::FORMAT_A16B16G16R16I;
+			default:
+				UNREACHABLE(format);
 			}
-			else if(format == SW_YV12_BT709)
+		case GL_UNSIGNED_SHORT:
+			switch(format)
 			{
-				return sw::FORMAT_YV12_BT709;
+			case GL_R16UI:
+			case GL_RED_INTEGER:
+				return sw::FORMAT_R16UI;
+			case GL_RG16UI:
+			case GL_RG_INTEGER:
+				return sw::FORMAT_G16R16UI;
+			case GL_RGB16UI:
+			case GL_RGB_INTEGER:
+				return sw::FORMAT_X16B16G16R16UI;
+			case GL_RGBA16UI:
+			case GL_RGBA_INTEGER:
+				return sw::FORMAT_A16B16G16R16UI;
+			case GL_DEPTH_COMPONENT:
+			case GL_DEPTH_COMPONENT16:
+				return sw::FORMAT_D32FS8_TEXTURE;
+			default:
+				UNREACHABLE(format);
 			}
-			else if(format == SW_YV12_JFIF)
+		case GL_INT:
+			switch(format)
 			{
-				return sw::FORMAT_YV12_JFIF;
+			case GL_RED_INTEGER:
+			case GL_R32I:
+				return sw::FORMAT_R32I;
+			case GL_RG_INTEGER:
+			case GL_RG32I:
+				return sw::FORMAT_G32R32I;
+			case GL_RGB_INTEGER:
+			case GL_RGB32I:
+				return sw::FORMAT_X32B32G32R32I;
+			case GL_RGBA_INTEGER:
+			case GL_RGBA32I:
+				return sw::FORMAT_A32B32G32R32I;
+			default:
+				UNREACHABLE(format);
 			}
-			else UNREACHABLE(format);
-		}
-		else if(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT)
-		{
-			if(format == GL_DEPTH_COMPONENT)
+		case GL_UNSIGNED_INT:
+			switch(format)
+			{
+			case GL_RED_INTEGER:
+			case GL_R32UI:
+				return sw::FORMAT_R32UI;
+			case GL_RG_INTEGER:
+			case GL_RG32UI:
+				return sw::FORMAT_G32R32UI;
+			case GL_RGB_INTEGER:
+			case GL_RGB32UI:
+				return sw::FORMAT_X32B32G32R32UI;
+			case GL_RGBA_INTEGER:
+			case GL_RGBA32UI:
+				return sw::FORMAT_A32B32G32R32UI;
+			case GL_DEPTH_COMPONENT:
+			case GL_DEPTH_COMPONENT16:
+			case GL_DEPTH_COMPONENT24:
+			case GL_DEPTH_COMPONENT32_OES:
+				return sw::FORMAT_D32FS8_TEXTURE;
+			default:
+				UNREACHABLE(format);
+			}
+		case GL_UNSIGNED_INT_24_8_OES:
+			if(format == GL_DEPTH_STENCIL || format == GL_DEPTH24_STENCIL8)
 			{
 				return sw::FORMAT_D32FS8_TEXTURE;
 			}
 			else UNREACHABLE(format);
-		}
-		else if(type == GL_UNSIGNED_INT_24_8_OES)
-		{
-			if(format == GL_DEPTH_STENCIL_OES)
+		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+			if(format == GL_DEPTH_STENCIL || format == GL_DEPTH32F_STENCIL8)
 			{
 				return sw::FORMAT_D32FS8_TEXTURE;
 			}
 			else UNREACHABLE(format);
-		}
-		else if(type == GL_UNSIGNED_SHORT_4_4_4_4)
-		{
+		case GL_UNSIGNED_SHORT_4_4_4_4:
 			return sw::FORMAT_A8R8G8B8;
-		}
-		else if(type == GL_UNSIGNED_SHORT_5_5_5_1)
-		{
+		case GL_UNSIGNED_SHORT_5_5_5_1:
 			return sw::FORMAT_A8R8G8B8;
-		}
-		else if(type == GL_UNSIGNED_SHORT_5_6_5)
-		{
+		case GL_UNSIGNED_SHORT_5_6_5:
 			return sw::FORMAT_R5G6B5;
+		case GL_UNSIGNED_INT_2_10_10_10_REV:
+			if(format == GL_RGB10_A2UI)
+			{
+				return sw::FORMAT_A16B16G16R16UI;
+			}
+			else
+			{
+				return sw::FORMAT_A2B10G10R10;
+			}
+		case GL_UNSIGNED_INT_10F_11F_11F_REV:
+		case GL_UNSIGNED_INT_5_9_9_9_REV:
+			return sw::FORMAT_A32B32G32R32F;
+		case SW_YV12_BT601:
+			return sw::FORMAT_YV12_BT601;
+		case SW_YV12_BT709:
+			return sw::FORMAT_YV12_BT709;
+		case SW_YV12_JFIF:
+			return sw::FORMAT_YV12_JFIF;
+		default:
+			UNREACHABLE(type);
 		}
-		else UNREACHABLE(type);
 
-		return sw::FORMAT_A8B8G8R8;
+		return sw::FORMAT_NULL;
 	}
 
 	// Returns the size, in bytes, of a single texel in an Image
@@ -589,34 +948,155 @@
 	{
 		switch(type)
 		{
+		case GL_BYTE:
+			switch(format)
+			{
+			case GL_R8:
+			case GL_R8I:
+			case GL_R8_SNORM:
+			case GL_RED:             return sizeof(char);
+			case GL_RED_INTEGER:     return sizeof(char);
+			case GL_RG8:
+			case GL_RG8I:
+			case GL_RG8_SNORM:
+			case GL_RG:              return sizeof(char) * 2;
+			case GL_RG_INTEGER:      return sizeof(char) * 2;
+			case GL_RGB8:
+			case GL_RGB8I:
+			case GL_RGB8_SNORM:
+			case GL_RGB:             return sizeof(char) * 3;
+			case GL_RGB_INTEGER:     return sizeof(char) * 3;
+			case GL_RGBA8:
+			case GL_RGBA8I:
+			case GL_RGBA8_SNORM:
+			case GL_RGBA:            return sizeof(char) * 4;
+			case GL_RGBA_INTEGER:    return sizeof(char) * 4;
+			default: UNREACHABLE(format);
+			}
+			break;
 		case GL_UNSIGNED_BYTE:
 			switch(format)
 			{
+			case GL_R8:
+			case GL_R8UI:
+			case GL_RED:             return sizeof(unsigned char);
+			case GL_RED_INTEGER:     return sizeof(unsigned char);
+			case GL_ALPHA8_EXT:
 			case GL_ALPHA:           return sizeof(unsigned char);
+			case GL_LUMINANCE8_EXT:
 			case GL_LUMINANCE:       return sizeof(unsigned char);
+			case GL_LUMINANCE8_ALPHA8_EXT:
 			case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
+			case GL_RG8:
+			case GL_RG8UI:
+			case GL_RG:              return sizeof(unsigned char) * 2;
+			case GL_RG_INTEGER:      return sizeof(unsigned char) * 2;
+			case GL_RGB8:
+			case GL_RGB8UI:
+			case GL_SRGB8:
 			case GL_RGB:             return sizeof(unsigned char) * 3;
+			case GL_RGB_INTEGER:     return sizeof(unsigned char) * 3;
+			case GL_RGBA8:
+			case GL_RGBA8UI:
+			case GL_SRGB8_ALPHA8:
 			case GL_RGBA:            return sizeof(unsigned char) * 4;
+			case GL_RGBA_INTEGER:    return sizeof(unsigned char) * 4;
 			case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;
 			default: UNREACHABLE(format);
 			}
 			break;
+		case GL_SHORT:
+			switch(format)
+			{
+			case GL_R16I:
+			case GL_RED_INTEGER:     return sizeof(short);
+			case GL_RG16I:
+			case GL_RG_INTEGER:      return sizeof(short) * 2;
+			case GL_RGB16I:
+			case GL_RGB_INTEGER:     return sizeof(short) * 3;
+			case GL_RGBA16I:
+			case GL_RGBA_INTEGER:    return sizeof(short) * 4;
+			default: UNREACHABLE(format);
+			}
+			break;
+		case GL_UNSIGNED_SHORT:
+			switch(format)
+			{
+			case GL_DEPTH_COMPONENT16:
+			case GL_DEPTH_COMPONENT: return sizeof(unsigned short);
+			case GL_R16UI:
+			case GL_RED_INTEGER:     return sizeof(unsigned short);
+			case GL_RG16UI:
+			case GL_RG_INTEGER:      return sizeof(unsigned short) * 2;
+			case GL_RGB16UI:
+			case GL_RGB_INTEGER:     return sizeof(unsigned short) * 3;
+			case GL_RGBA16UI:
+			case GL_RGBA_INTEGER:    return sizeof(unsigned short) * 4;
+			default: UNREACHABLE(format);
+			}
+			break;
+		case GL_INT:
+			switch(format)
+			{
+			case GL_R32I:
+			case GL_RED_INTEGER:     return sizeof(int);
+			case GL_RG32I:
+			case GL_RG_INTEGER:      return sizeof(int) * 2;
+			case GL_RGB32I:
+			case GL_RGB_INTEGER:     return sizeof(int) * 3;
+			case GL_RGBA32I:
+			case GL_RGBA_INTEGER:    return sizeof(int) * 4;
+			default: UNREACHABLE(format);
+			}
+			break;
+		case GL_UNSIGNED_INT:
+			switch(format)
+			{
+			case GL_DEPTH_COMPONENT16:
+			case GL_DEPTH_COMPONENT24:
+			case GL_DEPTH_COMPONENT32_OES:
+			case GL_DEPTH_COMPONENT: return sizeof(unsigned int);
+			case GL_R32UI:
+			case GL_RED_INTEGER:     return sizeof(unsigned int);
+			case GL_RG32UI:
+			case GL_RG_INTEGER:      return sizeof(unsigned int) * 2;
+			case GL_RGB32UI:
+			case GL_RGB_INTEGER:     return sizeof(unsigned int) * 3;
+			case GL_RGBA32UI:
+			case GL_RGBA_INTEGER:    return sizeof(unsigned int) * 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_10F_11F_11F_REV:
+		case GL_UNSIGNED_INT_5_9_9_9_REV:
+		case GL_UNSIGNED_INT_2_10_10_10_REV:
 		case GL_UNSIGNED_INT_24_8_OES:
 			return sizeof(unsigned int);
+		case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+			return sizeof(float) + sizeof(unsigned int);
 		case GL_FLOAT:
 			switch(format)
 			{
+			case GL_DEPTH_COMPONENT32F:
+			case GL_DEPTH_COMPONENT: return sizeof(float);
+			case GL_ALPHA32F_EXT:
 			case GL_ALPHA:           return sizeof(float);
+			case GL_LUMINANCE32F_EXT:
 			case GL_LUMINANCE:       return sizeof(float);
+			case GL_LUMINANCE_ALPHA32F_EXT:
 			case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
+			case GL_RED:             return sizeof(float);
+			case GL_R32F:            return sizeof(float);
+			case GL_RG:              return sizeof(float) * 2;
+			case GL_RG32F:           return sizeof(float) * 2;
 			case GL_RGB:             return sizeof(float) * 3;
+			case GL_RGB32F:          return sizeof(float) * 3;
 			case GL_RGBA:            return sizeof(float) * 4;
+			case GL_RGBA32F:         return sizeof(float) * 4;
 			default: UNREACHABLE(format);
 			}
 			break;
@@ -624,11 +1104,20 @@
 		case GL_HALF_FLOAT_OES:
 			switch(format)
 			{
+			case GL_ALPHA16F_EXT:
 			case GL_ALPHA:           return sizeof(unsigned short);
+			case GL_LUMINANCE16F_EXT:
 			case GL_LUMINANCE:       return sizeof(unsigned short);
+			case GL_LUMINANCE_ALPHA16F_EXT:
 			case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
+			case GL_RED:             return sizeof(unsigned short);
+			case GL_R16F:            return sizeof(unsigned short);
+			case GL_RG:              return sizeof(unsigned short) * 2;
+			case GL_RG16F:           return sizeof(unsigned short) * 2;
 			case GL_RGB:             return sizeof(unsigned short) * 3;
+			case GL_RGB16F:          return sizeof(unsigned short) * 3;
 			case GL_RGBA:            return sizeof(unsigned short) * 4;
+			case GL_RGBA16F:         return sizeof(unsigned short) * 4;
 			default: UNREACHABLE(format);
 			}
 			break;
@@ -765,8 +1254,13 @@
 		GLsizei inputPitch = ComputePitch((unpackInfo.rowLength == 0) ? width : unpackInfo.rowLength, format, type, unpackInfo.alignment);
 		GLsizei inputHeight = (unpackInfo.imageHeight == 0) ? height : unpackInfo.imageHeight;
 		input = ((char*)input) + (unpackInfo.skipImages * inputHeight + unpackInfo.skipRows) * inputPitch + unpackInfo.skipPixels;
+		sw::Format selectedInternalFormat = SelectInternalFormat(format, type);
+		if(selectedInternalFormat == sw::FORMAT_NULL)
+		{
+			return;
+		}
 
-		if(SelectInternalFormat(format, type) == internalFormat)
+		if(selectedInternalFormat == internalFormat)
 		{
 			void *buffer = lock(0, 0, sw::LOCK_WRITEONLY);
 
@@ -774,24 +1268,90 @@
 			{
 				switch(type)
 				{
+				case GL_BYTE:
+					switch(format)
+					{
+					case GL_R8:
+					case GL_R8I:
+					case GL_R8_SNORM:
+					case GL_RED:
+					case GL_RED_INTEGER:
+					case GL_ALPHA:
+					case GL_ALPHA8_EXT:
+					case GL_LUMINANCE:
+					case GL_LUMINANCE8_EXT:
+						LoadImageData<Bytes_1>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RG8:
+					case GL_RG8I:
+					case GL_RG8_SNORM:
+					case GL_RG:
+					case GL_RG_INTEGER:
+					case GL_LUMINANCE_ALPHA:
+					case GL_LUMINANCE8_ALPHA8_EXT:
+						LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RGB8:
+					case GL_RGB8I:
+					case GL_RGB8_SNORM:
+					case GL_RGB:
+					case GL_RGB_INTEGER:
+						LoadImageData<ByteRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RGBA8:
+					case GL_RGBA8I:
+					case GL_RGBA8_SNORM:
+					case GL_RGBA:
+					case GL_RGBA_INTEGER:
+					case GL_BGRA_EXT:
+						LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					default: UNREACHABLE(format);
+					}
+					break;
 				case GL_UNSIGNED_BYTE:
 					switch(format)
 					{
+					case GL_R8:
+					case GL_R8UI:
+					case GL_R8_SNORM:
+					case GL_RED:
+					case GL_RED_INTEGER:
 					case GL_ALPHA:
-						LoadImageData<Alpha>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
-						break;
+					case GL_ALPHA8_EXT:
 					case GL_LUMINANCE:
-						LoadImageData<Luminance>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+					case GL_LUMINANCE8_EXT:
+						LoadImageData<Bytes_1>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
+					case GL_RG8:
+					case GL_RG8UI:
+					case GL_RG8_SNORM:
+					case GL_RG:
+					case GL_RG_INTEGER:
 					case GL_LUMINANCE_ALPHA:
-						LoadImageData<LuminanceAlpha>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+					case GL_LUMINANCE8_ALPHA8_EXT:
+						LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
+					case GL_RGB8:
+					case GL_RGB8UI:
+					case GL_RGB8_SNORM:
 					case GL_RGB:
+					case GL_RGB_INTEGER:
 						LoadImageData<UByteRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
+					case GL_RGBA8:
+					case GL_RGBA8UI:
+					case GL_RGBA8_SNORM:
 					case GL_RGBA:
+					case GL_RGBA_INTEGER:
 					case GL_BGRA_EXT:
-						LoadImageData<UByte4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_SRGB8:
+						LoadImageData<SRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_SRGB8_ALPHA8:
+						LoadImageData<SRGBA>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					default: UNREACHABLE(format);
 					}
@@ -799,6 +1359,7 @@
 				case GL_UNSIGNED_SHORT_5_6_5:
 					switch(format)
 					{
+					case GL_RGB565:
 					case GL_RGB:
 						LoadImageData<RGB565>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
@@ -808,6 +1369,7 @@
 				case GL_UNSIGNED_SHORT_4_4_4_4:
 					switch(format)
 					{
+					case GL_RGBA4:
 					case GL_RGBA:
 						LoadImageData<RGBA4444>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
@@ -817,30 +1379,82 @@
 				case GL_UNSIGNED_SHORT_5_5_5_1:
 					switch(format)
 					{
+					case GL_RGB5_A1:
 					case GL_RGBA:
 						LoadImageData<RGBA5551>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					default: UNREACHABLE(format);
 					}
 					break;
+				case GL_UNSIGNED_INT_10F_11F_11F_REV:
+					switch(format)
+					{
+					case GL_R11F_G11F_B10F:
+					case GL_RGB:
+						LoadImageData<R11G11B10F>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					default: UNREACHABLE(format);
+					}
+					break;
+				case GL_UNSIGNED_INT_5_9_9_9_REV:
+					switch(format)
+					{
+					case GL_RGB9_E5:
+					case GL_RGB:
+						LoadImageData<RGB9E5>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					default: UNREACHABLE(format);
+					}
+					break;
+				case GL_UNSIGNED_INT_2_10_10_10_REV:
+					switch(format)
+					{
+					case GL_RGB10_A2UI:
+						LoadImageData<RGB10A2UI>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RGB10_A2:
+					case GL_RGBA:
+					case GL_RGBA_INTEGER:
+						LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					default: UNREACHABLE(format);
+					}
+					break;
 				case GL_FLOAT:
 					switch(format)
 					{
 					// float textures are converted to RGBA, not BGRA
 					case GL_ALPHA:
+					case GL_ALPHA32F_EXT:
 						LoadImageData<AlphaFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					case GL_LUMINANCE:
+					case GL_LUMINANCE32F_EXT:
 						LoadImageData<LuminanceFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					case GL_LUMINANCE_ALPHA:
+					case GL_LUMINANCE_ALPHA32F_EXT:
 						LoadImageData<LuminanceAlphaFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
+					case GL_RED:
+					case GL_R32F:
+						LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RG:
+					case GL_RG32F:
+						LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
 					case GL_RGB:
+					case GL_RGB32F:
 						LoadImageData<FloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					case GL_RGBA:
-						LoadImageData<Float4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+					case GL_RGBA32F:
+						LoadImageData<Bytes_16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_DEPTH_COMPONENT:
+					case GL_DEPTH_COMPONENT32F:
+						LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					default: UNREACHABLE(format);
 					}
@@ -850,32 +1464,172 @@
 					switch(format)
 					{
 					case GL_ALPHA:
+					case GL_ALPHA16F_EXT:
 						LoadImageData<AlphaHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					case GL_LUMINANCE:
+					case GL_LUMINANCE16F_EXT:
 						LoadImageData<LuminanceHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					case GL_LUMINANCE_ALPHA:
+					case GL_LUMINANCE_ALPHA16F_EXT:
 						LoadImageData<LuminanceAlphaHalfFloat>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
+					case GL_RED:
+					case GL_R16F:
+						LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RG:
+					case GL_RG16F:
+						LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
 					case GL_RGB:
+					case GL_RGB16F:
 						LoadImageData<HalfFloatRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					case GL_RGBA:
-						LoadImageData<HalfFloat4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+					case GL_RGBA16F:
+						LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					default: UNREACHABLE(format);
+					}
+					break;
+				case GL_SHORT:
+					switch(format)
+					{
+					case GL_R16I:
+					case GL_RED:
+					case GL_RED_INTEGER:
+					case GL_ALPHA:
+					case GL_LUMINANCE:
+						LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RG16I:
+					case GL_RG:
+					case GL_RG_INTEGER:
+					case GL_LUMINANCE_ALPHA:
+						LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RGB16I:
+					case GL_RGB:
+					case GL_RGB_INTEGER:
+						LoadImageData<ShortRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RGBA16I:
+					case GL_RGBA:
+					case GL_RGBA_INTEGER:
+					case GL_BGRA_EXT:
+						LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
 						break;
 					default: UNREACHABLE(format);
 					}
 					break;
 				case GL_UNSIGNED_SHORT:
-					LoadImageData<D16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+					switch(format)
+					{
+					case GL_R16UI:
+					case GL_RED:
+					case GL_RED_INTEGER:
+					case GL_ALPHA:
+					case GL_LUMINANCE:
+						LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RG16UI:
+					case GL_RG:
+					case GL_RG_INTEGER:
+					case GL_LUMINANCE_ALPHA:
+						LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RGB16UI:
+					case GL_RGB:
+					case GL_RGB_INTEGER:
+						LoadImageData<UShortRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RGBA16UI:
+					case GL_RGBA:
+					case GL_RGBA_INTEGER:
+					case GL_BGRA_EXT:
+						LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_DEPTH_COMPONENT:
+					case GL_DEPTH_COMPONENT16:
+						LoadImageData<D16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					default: UNREACHABLE(format);
+					}
+					break;
+				case GL_INT:
+					switch(format)
+					{
+					case GL_R32I:
+					case GL_RED:
+					case GL_RED_INTEGER:
+					case GL_ALPHA:
+					case GL_LUMINANCE:
+						LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RG32I:
+					case GL_RG:
+					case GL_RG_INTEGER:
+					case GL_LUMINANCE_ALPHA:
+						LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RGB32I:
+					case GL_RGB:
+					case GL_RGB_INTEGER:
+						LoadImageData<IntRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RGBA32I:
+					case GL_RGBA:
+					case GL_RGBA_INTEGER:
+					case GL_BGRA_EXT:
+						LoadImageData<Bytes_16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					default: UNREACHABLE(format);
+					}
 					break;
 				case GL_UNSIGNED_INT:
-					LoadImageData<D32>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+					switch(format)
+					{
+					case GL_R32UI:
+					case GL_RED:
+					case GL_RED_INTEGER:
+					case GL_ALPHA:
+					case GL_LUMINANCE:
+						LoadImageData<Bytes_2>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RG32UI:
+					case GL_RG:
+					case GL_RG_INTEGER:
+					case GL_LUMINANCE_ALPHA:
+						LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RGB32UI:
+					case GL_RGB:
+					case GL_RGB_INTEGER:
+						LoadImageData<UIntRGB>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_RGBA32UI:
+					case GL_RGBA:
+					case GL_RGBA_INTEGER:
+					case GL_BGRA_EXT:
+						LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					case GL_DEPTH_COMPONENT16:
+					case GL_DEPTH_COMPONENT24:
+					case GL_DEPTH_COMPONENT32_OES:
+					case GL_DEPTH_COMPONENT:
+						LoadImageData<D32>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+						break;
+					default: UNREACHABLE(format);
+					}
 					break;
 				case GL_UNSIGNED_INT_24_8_OES:
 					loadD24S8ImageData(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, input, buffer);
 					break;
+				case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+					loadD32FS8ImageData(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, input, buffer);
+					break;
 				default: UNREACHABLE(type);
 				}
 			}
@@ -905,6 +1659,20 @@
 		}
 	}
 
+	void Image::loadD32FS8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer)
+	{
+		LoadImageData<D32F>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
+
+		unsigned char *stencil = reinterpret_cast<unsigned char*>(lockStencil(0, sw::PUBLIC));
+
+		if(stencil)
+		{
+			LoadImageData<S24_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getStencilPitchB(), getHeight(), input, stencil);
+
+			unlockStencil();
+		}
+	}
+
 	void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
 	{
 		if(zoffset != 0 || depth != 1)
diff --git a/src/OpenGL/common/Image.hpp b/src/OpenGL/common/Image.hpp
index db24d8b..3b09bc7 100644
--- a/src/OpenGL/common/Image.hpp
+++ b/src/OpenGL/common/Image.hpp
@@ -171,6 +171,7 @@
 	virtual ~Image();

 

 	void loadD24S8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer);

+	void loadD32FS8ImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, int inputPitch, int inputHeight, const void *input, void *buffer);

 };

 

 #ifdef __ANDROID__