Apply the Apache 2.0 license.

Change-Id: I4a7aeefedcd2d891093520d5a10ebefadcddb5be
Reviewed-on: https://swiftshader-review.googlesource.com/5320
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLES_CM/utilities.cpp b/src/OpenGL/libGLES_CM/utilities.cpp
index 3dbedde..b03f15c 100644
--- a/src/OpenGL/libGLES_CM/utilities.cpp
+++ b/src/OpenGL/libGLES_CM/utilities.cpp
@@ -1,720 +1,723 @@
-// SwiftShader Software Renderer

-//

-// Copyright(c) 2005-2013 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.

-//

-

-// 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 es1

-{

-	bool IsCompressed(GLenum format)

-	{

-		return format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||

-		       format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||

-               format == GL_ETC1_RGB8_OES;

-	}

-

-	bool IsDepthTexture(GLenum format)

-	{

-		return format == GL_DEPTH_STENCIL_OES;

-	}

-

-	bool IsStencilTexture(GLenum format)

-	{

-		return format == GL_DEPTH_STENCIL_OES;

-	}

-

-	bool IsCubemapTextureTarget(GLenum target)

-	{

-		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES);

-	}

-

-	int CubeFaceIndex(GLenum cubeFace)

-	{

-		switch(cubeFace)

-		{

-		case GL_TEXTURE_CUBE_MAP_OES:

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES: return 0;

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES: return 1;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES: return 2;

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES: return 3;

-		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES: return 4;

-		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES: return 5;

-		default: UNREACHABLE(cubeFace); return 0;

-		}

-	}

-

-	bool IsTextureTarget(GLenum target)

-	{

-		return target == GL_TEXTURE_2D;

-	}

-

-	// 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_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_24_8_OES:

-			return (format == GL_DEPTH_STENCIL_OES);

-		default:

-			return false;

-		}

-	}

-

-	bool IsColorRenderable(GLenum internalformat)

-	{

-		switch(internalformat)

-		{

-		case GL_RGBA4_OES:

-		case GL_RGB5_A1_OES:

-		case GL_RGB565_OES:

-		case GL_RGB8_OES:

-		case GL_RGBA8_OES:

-			return true;

-		case GL_DEPTH_COMPONENT16_OES:

-		case GL_STENCIL_INDEX8_OES:

-		case GL_DEPTH24_STENCIL8_OES:

-			return false;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return false;

-	}

-

-	bool IsDepthRenderable(GLenum internalformat)

-	{

-		switch(internalformat)

-		{

-		case GL_DEPTH_COMPONENT16_OES:

-		case GL_DEPTH24_STENCIL8_OES:

-			return true;

-		case GL_STENCIL_INDEX8_OES:

-		case GL_RGBA4_OES:

-		case GL_RGB5_A1_OES:

-		case GL_RGB565_OES:

-		case GL_RGB8_OES:

-		case GL_RGBA8_OES:

-			return false;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return false;

-	}

-

-	bool IsStencilRenderable(GLenum internalformat)

-	{

-		switch(internalformat)

-		{

-		case GL_STENCIL_INDEX8_OES:

-		case GL_DEPTH24_STENCIL8_OES:

-			return true;

-		case GL_RGBA4_OES:

-		case GL_RGB5_A1_OES:

-		case GL_RGB565_OES:

-		case GL_RGB8_OES:

-		case GL_RGBA8_OES:

-		case GL_DEPTH_COMPONENT16_OES:

-			return false;

-		default:

-			UNIMPLEMENTED();

-		}

-

-		return false;

-	}

-

-	bool IsAlpha(GLenum texFormat)

-	{

-		switch(texFormat)

-		{

-		case GL_ALPHA:

-			return true;

-		default:

-			return false;

-		}

-	}

-

-	bool IsRGB(GLenum texFormat)

-	{

-		switch(texFormat)

-		{

-		case GL_LUMINANCE:

-		case GL_RGB:

-		case GL_RGB565_OES:   // GL_OES_framebuffer_object

-		case GL_RGB8_OES:     // GL_OES_rgb8_rgba8

-		case SW_YV12_BT601:

-		case SW_YV12_BT709:

-		case SW_YV12_JFIF:

-			return true;

-		default:

-			return false;

-		}

-	}

-

-	bool IsRGBA(GLenum texFormat)

-	{

-		switch(texFormat)

-		{

-		case GL_LUMINANCE_ALPHA:

-		case GL_RGBA:

-		case GL_BGRA_EXT:      // GL_EXT_texture_format_BGRA8888

-		case GL_RGBA4_OES:     // GL_OES_framebuffer_object

-		case GL_RGB5_A1_OES:   // GL_OES_framebuffer_object

-		case GL_RGBA8_OES:     // GL_OES_rgb8_rgba8

-			return true;

-		default:

-			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::AlphaCompareMode ConvertAlphaComparison(GLenum comparison)

-	{

-		switch(comparison)

-		{

-		case GL_NEVER:    return sw::ALPHA_NEVER;

-		case GL_ALWAYS:   return sw::ALPHA_ALWAYS;

-		case GL_LESS:     return sw::ALPHA_LESS;

-		case GL_LEQUAL:   return sw::ALPHA_LESSEQUAL;

-		case GL_EQUAL:    return sw::ALPHA_EQUAL;

-		case GL_GREATER:  return sw::ALPHA_GREATER;

-		case GL_GEQUAL:   return sw::ALPHA_GREATEREQUAL;

-		case GL_NOTEQUAL: return sw::ALPHA_NOTEQUAL;

-		default: UNREACHABLE(comparison);

-		}

-

-		return sw::ALPHA_ALWAYS;

-	}

-

-	sw::Color<float> ConvertColor(es1::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_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_OES:              return sw::BLENDOP_ADD;

-		case GL_FUNC_SUBTRACT_OES:         return sw::BLENDOP_SUB;

-		case GL_FUNC_REVERSE_SUBTRACT_OES: 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_OES: return sw::OPERATION_INCR;

-		case GL_DECR_WRAP_OES: return sw::OPERATION_DECR;

-		default: UNREACHABLE(stencilOp);

-		}

-

-		return sw::OPERATION_KEEP;

-	}

-

-	sw::AddressingMode ConvertTextureWrap(GLenum wrap)

-	{

-		switch(wrap)

-		{

-		case GL_REPEAT:              return sw::ADDRESSING_WRAP;

-		case GL_CLAMP_TO_EDGE:       return sw::ADDRESSING_CLAMP;

-		case GL_MIRRORED_REPEAT_OES: 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;

-		}

-

-		sw::FilterType magFilterType = sw::FILTER_POINT;

-		switch(magFilter)

-		{

-		case GL_NEAREST: magFilterType = sw::FILTER_POINT;  break;

-		case GL_LINEAR:  magFilterType = sw::FILTER_LINEAR; break;

-		default: UNREACHABLE(magFilter);

-		}

-

-		switch(minFilter)

-		{

-		case GL_NEAREST:

-		case GL_NEAREST_MIPMAP_NEAREST:

-		case GL_NEAREST_MIPMAP_LINEAR:

-			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;

-		case GL_LINEAR:

-		case GL_LINEAR_MIPMAP_NEAREST:

-		case GL_LINEAR_MIPMAP_LINEAR:

-			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;

-		default:

-			UNREACHABLE(minFilter);

-			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;

-		}

-	}

-

-	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType,  sw::DrawType &drawType, int &primitiveCount)

-	{

-		switch(primitiveType)

-		{

-		case GL_POINTS:

-			drawType = sw::DRAW_POINTLIST;

-			primitiveCount = elementCount;

-			break;

-		case GL_LINES:

-			drawType = sw::DRAW_LINELIST;

-			primitiveCount = elementCount / 2;

-			break;

-		case GL_LINE_LOOP:

-			drawType = sw::DRAW_LINELOOP;

-			primitiveCount = elementCount;

-			break;

-		case GL_LINE_STRIP:

-			drawType = sw::DRAW_LINESTRIP;

-			primitiveCount = elementCount - 1;

-			break;

-		case GL_TRIANGLES:

-			drawType = sw::DRAW_TRIANGLELIST;

-			primitiveCount = elementCount / 3;

-			break;

-		case GL_TRIANGLE_STRIP:

-			drawType = sw::DRAW_TRIANGLESTRIP;

-			primitiveCount = elementCount - 2;

-			break;

-		case GL_TRIANGLE_FAN:

-			drawType = sw::DRAW_TRIANGLEFAN;

-			primitiveCount = elementCount - 2;

-			break;

-		default:

-			return false;

-		}

-

-		sw::DrawType elementSize;

-		switch(elementType)

-		{

-		case GL_NONE:           elementSize = sw::DRAW_NONINDEXED; break;

-		case GL_UNSIGNED_BYTE:  elementSize = sw::DRAW_INDEXED8;   break;

-		case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16;  break;

-		case GL_UNSIGNED_INT:   elementSize = sw::DRAW_INDEXED32;  break;

-		default: return false;

-		}

-

-		drawType = sw::DrawType(drawType | elementSize);

-

-		return true;

-	}

-

-	sw::Format ConvertRenderbufferFormat(GLenum format)

-	{

-		switch(format)

-		{

-		case GL_RGBA4_OES:

-		case GL_RGB5_A1_OES:

-		case GL_RGBA8_OES:            return sw::FORMAT_A8B8G8R8;

-		case GL_RGB565_OES:           return sw::FORMAT_R5G6B5;

-		case GL_RGB8_OES:             return sw::FORMAT_X8B8G8R8;

-		case GL_DEPTH_COMPONENT16_OES:

-		case GL_STENCIL_INDEX8_OES:

-		case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;

-		default: UNREACHABLE(format); return sw::FORMAT_A8B8G8R8;

-		}

-	}

-

-	sw::TextureStage::StageOperation ConvertCombineOperation(GLenum operation)

-	{

-		switch(operation)

-		{

-		case GL_REPLACE:        return sw::TextureStage::STAGE_SELECTARG1;

-		case GL_MODULATE:       return sw::TextureStage::STAGE_MODULATE;

-		case GL_ADD:            return sw::TextureStage::STAGE_ADD;

-		case GL_ADD_SIGNED:     return sw::TextureStage::STAGE_ADDSIGNED;

-		case GL_INTERPOLATE:    return sw::TextureStage::STAGE_LERP;

-		case GL_SUBTRACT:       return sw::TextureStage::STAGE_SUBTRACT;

-		case GL_DOT3_RGB:       return sw::TextureStage::STAGE_DOT3;

-		case GL_DOT3_RGBA:      return sw::TextureStage::STAGE_DOT3;

-		default: UNREACHABLE(operation); return sw::TextureStage::STAGE_SELECTARG1;

-		}

-	}

-

-	sw::TextureStage::SourceArgument ConvertSourceArgument(GLenum argument)

-	{

-		switch(argument)

-		{

-		case GL_TEXTURE:        return sw::TextureStage::SOURCE_TEXTURE;

-		case GL_CONSTANT:       return sw::TextureStage::SOURCE_CONSTANT;

-		case GL_PRIMARY_COLOR:  return sw::TextureStage::SOURCE_DIFFUSE;

-		case GL_PREVIOUS:       return sw::TextureStage::SOURCE_CURRENT;

-		default: UNREACHABLE(argument); return sw::TextureStage::SOURCE_CURRENT;

-		}

-	}

-

-	sw::TextureStage::ArgumentModifier ConvertSourceOperand(GLenum operand)

-	{

-		switch(operand)

-		{

-		case GL_SRC_COLOR:           return sw::TextureStage::MODIFIER_COLOR;

-		case GL_ONE_MINUS_SRC_COLOR: return sw::TextureStage::MODIFIER_INVCOLOR;

-		case GL_SRC_ALPHA:           return sw::TextureStage::MODIFIER_ALPHA;

-		case GL_ONE_MINUS_SRC_ALPHA: return sw::TextureStage::MODIFIER_INVALPHA;

-		default: UNREACHABLE(operand);      return sw::TextureStage::MODIFIER_COLOR;

-		}

-	}

-}

-

-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:

-		case sw::FORMAT_A8B8G8R8:

-			return 8;

-		case sw::FORMAT_A1R5G5B5:

-			return 1;

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_X8B8G8R8:

-		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_A8B8G8R8:

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_X8B8G8R8:

-			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_A8B8G8R8:

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_X8B8G8R8:

-			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_A8B8G8R8:

-		case sw::FORMAT_X8R8G8B8:

-		case sw::FORMAT_X8B8G8R8:

-			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_OES;

-		case sw::FORMAT_A8R8G8B8: return GL_RGBA8_OES;

-		case sw::FORMAT_A8B8G8R8: return GL_RGBA8_OES;

-		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1_OES;

-		case sw::FORMAT_R5G6B5:   return GL_RGB565_OES;

-		case sw::FORMAT_X8R8G8B8: return GL_RGB8_OES;

-		case sw::FORMAT_X8B8G8R8: return GL_RGB8_OES;

-		default:

-			UNREACHABLE(format);

-		}

-

-		return GL_RGBA4_OES;

-	}

-

-	GLenum ConvertDepthStencilFormat(sw::Format format)

-	{

-		switch(format)

-		{

-		case sw::FORMAT_D16:

-		case sw::FORMAT_D24X8:

-		case sw::FORMAT_D32:

-			return GL_DEPTH_COMPONENT16_OES;

-		case sw::FORMAT_D24S8:

-			return GL_DEPTH24_STENCIL8_OES;

-		default:

-			UNREACHABLE(format);

-		}

-

-		return GL_DEPTH24_STENCIL8_OES;

-	}

-}

+// 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 es1
+{
+	bool IsCompressed(GLenum format)
+	{
+		return format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+		       format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
+               format == GL_ETC1_RGB8_OES;
+	}
+
+	bool IsDepthTexture(GLenum format)
+	{
+		return format == GL_DEPTH_STENCIL_OES;
+	}
+
+	bool IsStencilTexture(GLenum format)
+	{
+		return format == GL_DEPTH_STENCIL_OES;
+	}
+
+	bool IsCubemapTextureTarget(GLenum target)
+	{
+		return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES);
+	}
+
+	int CubeFaceIndex(GLenum cubeFace)
+	{
+		switch(cubeFace)
+		{
+		case GL_TEXTURE_CUBE_MAP_OES:
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES: return 0;
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES: return 1;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES: return 2;
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES: return 3;
+		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES: return 4;
+		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES: return 5;
+		default: UNREACHABLE(cubeFace); return 0;
+		}
+	}
+
+	bool IsTextureTarget(GLenum target)
+	{
+		return target == GL_TEXTURE_2D;
+	}
+
+	// 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_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_24_8_OES:
+			return (format == GL_DEPTH_STENCIL_OES);
+		default:
+			return false;
+		}
+	}
+
+	bool IsColorRenderable(GLenum internalformat)
+	{
+		switch(internalformat)
+		{
+		case GL_RGBA4_OES:
+		case GL_RGB5_A1_OES:
+		case GL_RGB565_OES:
+		case GL_RGB8_OES:
+		case GL_RGBA8_OES:
+			return true;
+		case GL_DEPTH_COMPONENT16_OES:
+		case GL_STENCIL_INDEX8_OES:
+		case GL_DEPTH24_STENCIL8_OES:
+			return false;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return false;
+	}
+
+	bool IsDepthRenderable(GLenum internalformat)
+	{
+		switch(internalformat)
+		{
+		case GL_DEPTH_COMPONENT16_OES:
+		case GL_DEPTH24_STENCIL8_OES:
+			return true;
+		case GL_STENCIL_INDEX8_OES:
+		case GL_RGBA4_OES:
+		case GL_RGB5_A1_OES:
+		case GL_RGB565_OES:
+		case GL_RGB8_OES:
+		case GL_RGBA8_OES:
+			return false;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return false;
+	}
+
+	bool IsStencilRenderable(GLenum internalformat)
+	{
+		switch(internalformat)
+		{
+		case GL_STENCIL_INDEX8_OES:
+		case GL_DEPTH24_STENCIL8_OES:
+			return true;
+		case GL_RGBA4_OES:
+		case GL_RGB5_A1_OES:
+		case GL_RGB565_OES:
+		case GL_RGB8_OES:
+		case GL_RGBA8_OES:
+		case GL_DEPTH_COMPONENT16_OES:
+			return false;
+		default:
+			UNIMPLEMENTED();
+		}
+
+		return false;
+	}
+
+	bool IsAlpha(GLenum texFormat)
+	{
+		switch(texFormat)
+		{
+		case GL_ALPHA:
+			return true;
+		default:
+			return false;
+		}
+	}
+
+	bool IsRGB(GLenum texFormat)
+	{
+		switch(texFormat)
+		{
+		case GL_LUMINANCE:
+		case GL_RGB:
+		case GL_RGB565_OES:   // GL_OES_framebuffer_object
+		case GL_RGB8_OES:     // GL_OES_rgb8_rgba8
+		case SW_YV12_BT601:
+		case SW_YV12_BT709:
+		case SW_YV12_JFIF:
+			return true;
+		default:
+			return false;
+		}
+	}
+
+	bool IsRGBA(GLenum texFormat)
+	{
+		switch(texFormat)
+		{
+		case GL_LUMINANCE_ALPHA:
+		case GL_RGBA:
+		case GL_BGRA_EXT:      // GL_EXT_texture_format_BGRA8888
+		case GL_RGBA4_OES:     // GL_OES_framebuffer_object
+		case GL_RGB5_A1_OES:   // GL_OES_framebuffer_object
+		case GL_RGBA8_OES:     // GL_OES_rgb8_rgba8
+			return true;
+		default:
+			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::AlphaCompareMode ConvertAlphaComparison(GLenum comparison)
+	{
+		switch(comparison)
+		{
+		case GL_NEVER:    return sw::ALPHA_NEVER;
+		case GL_ALWAYS:   return sw::ALPHA_ALWAYS;
+		case GL_LESS:     return sw::ALPHA_LESS;
+		case GL_LEQUAL:   return sw::ALPHA_LESSEQUAL;
+		case GL_EQUAL:    return sw::ALPHA_EQUAL;
+		case GL_GREATER:  return sw::ALPHA_GREATER;
+		case GL_GEQUAL:   return sw::ALPHA_GREATEREQUAL;
+		case GL_NOTEQUAL: return sw::ALPHA_NOTEQUAL;
+		default: UNREACHABLE(comparison);
+		}
+
+		return sw::ALPHA_ALWAYS;
+	}
+
+	sw::Color<float> ConvertColor(es1::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_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_OES:              return sw::BLENDOP_ADD;
+		case GL_FUNC_SUBTRACT_OES:         return sw::BLENDOP_SUB;
+		case GL_FUNC_REVERSE_SUBTRACT_OES: 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_OES: return sw::OPERATION_INCR;
+		case GL_DECR_WRAP_OES: return sw::OPERATION_DECR;
+		default: UNREACHABLE(stencilOp);
+		}
+
+		return sw::OPERATION_KEEP;
+	}
+
+	sw::AddressingMode ConvertTextureWrap(GLenum wrap)
+	{
+		switch(wrap)
+		{
+		case GL_REPEAT:              return sw::ADDRESSING_WRAP;
+		case GL_CLAMP_TO_EDGE:       return sw::ADDRESSING_CLAMP;
+		case GL_MIRRORED_REPEAT_OES: 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;
+		}
+
+		sw::FilterType magFilterType = sw::FILTER_POINT;
+		switch(magFilter)
+		{
+		case GL_NEAREST: magFilterType = sw::FILTER_POINT;  break;
+		case GL_LINEAR:  magFilterType = sw::FILTER_LINEAR; break;
+		default: UNREACHABLE(magFilter);
+		}
+
+		switch(minFilter)
+		{
+		case GL_NEAREST:
+		case GL_NEAREST_MIPMAP_NEAREST:
+		case GL_NEAREST_MIPMAP_LINEAR:
+			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
+		case GL_LINEAR:
+		case GL_LINEAR_MIPMAP_NEAREST:
+		case GL_LINEAR_MIPMAP_LINEAR:
+			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR;
+		default:
+			UNREACHABLE(minFilter);
+			return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR;
+		}
+	}
+
+	bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType,  sw::DrawType &drawType, int &primitiveCount)
+	{
+		switch(primitiveType)
+		{
+		case GL_POINTS:
+			drawType = sw::DRAW_POINTLIST;
+			primitiveCount = elementCount;
+			break;
+		case GL_LINES:
+			drawType = sw::DRAW_LINELIST;
+			primitiveCount = elementCount / 2;
+			break;
+		case GL_LINE_LOOP:
+			drawType = sw::DRAW_LINELOOP;
+			primitiveCount = elementCount;
+			break;
+		case GL_LINE_STRIP:
+			drawType = sw::DRAW_LINESTRIP;
+			primitiveCount = elementCount - 1;
+			break;
+		case GL_TRIANGLES:
+			drawType = sw::DRAW_TRIANGLELIST;
+			primitiveCount = elementCount / 3;
+			break;
+		case GL_TRIANGLE_STRIP:
+			drawType = sw::DRAW_TRIANGLESTRIP;
+			primitiveCount = elementCount - 2;
+			break;
+		case GL_TRIANGLE_FAN:
+			drawType = sw::DRAW_TRIANGLEFAN;
+			primitiveCount = elementCount - 2;
+			break;
+		default:
+			return false;
+		}
+
+		sw::DrawType elementSize;
+		switch(elementType)
+		{
+		case GL_NONE:           elementSize = sw::DRAW_NONINDEXED; break;
+		case GL_UNSIGNED_BYTE:  elementSize = sw::DRAW_INDEXED8;   break;
+		case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16;  break;
+		case GL_UNSIGNED_INT:   elementSize = sw::DRAW_INDEXED32;  break;
+		default: return false;
+		}
+
+		drawType = sw::DrawType(drawType | elementSize);
+
+		return true;
+	}
+
+	sw::Format ConvertRenderbufferFormat(GLenum format)
+	{
+		switch(format)
+		{
+		case GL_RGBA4_OES:
+		case GL_RGB5_A1_OES:
+		case GL_RGBA8_OES:            return sw::FORMAT_A8B8G8R8;
+		case GL_RGB565_OES:           return sw::FORMAT_R5G6B5;
+		case GL_RGB8_OES:             return sw::FORMAT_X8B8G8R8;
+		case GL_DEPTH_COMPONENT16_OES:
+		case GL_STENCIL_INDEX8_OES:
+		case GL_DEPTH24_STENCIL8_OES: return sw::FORMAT_D24S8;
+		default: UNREACHABLE(format); return sw::FORMAT_A8B8G8R8;
+		}
+	}
+
+	sw::TextureStage::StageOperation ConvertCombineOperation(GLenum operation)
+	{
+		switch(operation)
+		{
+		case GL_REPLACE:        return sw::TextureStage::STAGE_SELECTARG1;
+		case GL_MODULATE:       return sw::TextureStage::STAGE_MODULATE;
+		case GL_ADD:            return sw::TextureStage::STAGE_ADD;
+		case GL_ADD_SIGNED:     return sw::TextureStage::STAGE_ADDSIGNED;
+		case GL_INTERPOLATE:    return sw::TextureStage::STAGE_LERP;
+		case GL_SUBTRACT:       return sw::TextureStage::STAGE_SUBTRACT;
+		case GL_DOT3_RGB:       return sw::TextureStage::STAGE_DOT3;
+		case GL_DOT3_RGBA:      return sw::TextureStage::STAGE_DOT3;
+		default: UNREACHABLE(operation); return sw::TextureStage::STAGE_SELECTARG1;
+		}
+	}
+
+	sw::TextureStage::SourceArgument ConvertSourceArgument(GLenum argument)
+	{
+		switch(argument)
+		{
+		case GL_TEXTURE:        return sw::TextureStage::SOURCE_TEXTURE;
+		case GL_CONSTANT:       return sw::TextureStage::SOURCE_CONSTANT;
+		case GL_PRIMARY_COLOR:  return sw::TextureStage::SOURCE_DIFFUSE;
+		case GL_PREVIOUS:       return sw::TextureStage::SOURCE_CURRENT;
+		default: UNREACHABLE(argument); return sw::TextureStage::SOURCE_CURRENT;
+		}
+	}
+
+	sw::TextureStage::ArgumentModifier ConvertSourceOperand(GLenum operand)
+	{
+		switch(operand)
+		{
+		case GL_SRC_COLOR:           return sw::TextureStage::MODIFIER_COLOR;
+		case GL_ONE_MINUS_SRC_COLOR: return sw::TextureStage::MODIFIER_INVCOLOR;
+		case GL_SRC_ALPHA:           return sw::TextureStage::MODIFIER_ALPHA;
+		case GL_ONE_MINUS_SRC_ALPHA: return sw::TextureStage::MODIFIER_INVALPHA;
+		default: UNREACHABLE(operand);      return sw::TextureStage::MODIFIER_COLOR;
+		}
+	}
+}
+
+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:
+		case sw::FORMAT_A8B8G8R8:
+			return 8;
+		case sw::FORMAT_A1R5G5B5:
+			return 1;
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_X8B8G8R8:
+		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_A8B8G8R8:
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_X8B8G8R8:
+			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_A8B8G8R8:
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_X8B8G8R8:
+			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_A8B8G8R8:
+		case sw::FORMAT_X8R8G8B8:
+		case sw::FORMAT_X8B8G8R8:
+			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_OES;
+		case sw::FORMAT_A8R8G8B8: return GL_RGBA8_OES;
+		case sw::FORMAT_A8B8G8R8: return GL_RGBA8_OES;
+		case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1_OES;
+		case sw::FORMAT_R5G6B5:   return GL_RGB565_OES;
+		case sw::FORMAT_X8R8G8B8: return GL_RGB8_OES;
+		case sw::FORMAT_X8B8G8R8: return GL_RGB8_OES;
+		default:
+			UNREACHABLE(format);
+		}
+
+		return GL_RGBA4_OES;
+	}
+
+	GLenum ConvertDepthStencilFormat(sw::Format format)
+	{
+		switch(format)
+		{
+		case sw::FORMAT_D16:
+		case sw::FORMAT_D24X8:
+		case sw::FORMAT_D32:
+			return GL_DEPTH_COMPONENT16_OES;
+		case sw::FORMAT_D24S8:
+			return GL_DEPTH24_STENCIL8_OES;
+		default:
+			UNREACHABLE(format);
+		}
+
+		return GL_DEPTH24_STENCIL8_OES;
+	}
+}